--- Code for LSU EE 4702 Spring 2001
--- Adder
library ieee;
use ieee.std_logic_1164.all;
entity adder is
-- Specify adder width, like a parameter in Verilog.
generic( w: integer:= 8);
port( a, b: in std_logic_vector (w-1 downto 0);
sum : out std_logic_vector (w downto 0));
end adder;
-- Behavioral description of adder.
architecture a1 of adder is
begin
p:process(a,b)
variable c: std_logic; -- Carry bit.
begin
c := '0';
for i in a'reverse_range loop
sum(i) <= a(i) xor b(i) xor c;
c := ( a(i) and b(i) ) or ( a(i) and c ) or ( b(i) and c );
end loop;
sum(sum'left) <= c;
end process p;
end a1;
-- Structural Description of Hardware
-- Ignores width specification.
architecture a2 of adder is
signal c: std_logic_vector (7 downto 0);
begin
b0:entity work.bfa port map(a(0),b(0),'0',sum(0),c(0));
b1:entity work.bfa port map(a(1),b(1),c(0),sum(1),c(1));
b2:entity work.bfa port map(a(2),b(2),c(1),sum(2),c(2));
b3:entity work.bfa port map(a(3),b(3),c(2),sum(3),c(3));
b4:entity work.bfa port map(a(4),b(4),c(3),sum(4),c(4));
b5:entity work.bfa port map(a(5),b(5),c(4),sum(5),c(5));
b6:entity work.bfa port map(a(6),b(6),c(5),sum(6),c(6));
b7:entity work.bfa port map(a(7),b(7),c(6),sum(7),sum(8));
end a2;
-- Structural Description Using Generate
-- Uses width specification (by basing generates on a and b sizes).
architecture a3 of adder is
signal c: std_logic_vector (a'left-1 downto 0);
begin
G1: for i in a'range generate
MSB: if i = a'left generate
bfa1:entity work.bfa port map( a(i), b(i), c(i-1), sum(i), sum(i+1) );
end generate;
Mid_Bits: if i > a'right and i < a'left generate
bfa2:entity work.bfa port map( a(i), b(i), c(i-1), sum(i), c(i) );
end generate;
LSB: if i = a'right generate
bfa3:entity work.bfa port map( a(i), b(i), '0', sum(i), c(i) );
end generate;
end generate;
end a3;
library ieee;
use ieee.std_logic_1164.all;
library Std_DevelopersKit;
use Std_DevelopersKit.Std_Regpak.all;
-- Adder Testbench
entity addertb is end;
architecture a1 of addertb is
constant width: integer := 4;
signal a,b:std_logic_vector ( width-1 downto 0 );
signal sum:std_logic_vector ( width downto 0 );
begin
adder1:entity work.adder(a3)
generic map( w => width )
port map(a, b, sum);
process
variable sum_tb:integer;
begin
for i in 0 to 2**width-1 loop
for j in 0 to 2**width-1 loop
a <= to_stdlogicvector(i,a'length);
b <= to_stdlogicvector(j,b'length);
sum_tb := i + j;
wait for 20 ns;
assert sum_tb = '0' & sum
report "Wrong output."
severity failure;
end loop;
end loop;
assert false
report "Not really a fatal error, only way I know to stop the sim."
severity failure;
end process;
end architecture a1;