====== Carry-Lookahead-Adder ====== ===== Parameters ===== A short interface specification: * The model is parameterized over the bit width ("@BITBR"). * The sum is calculated with a carry-lookahead algorithm. * The adder is cascadable. {{:synthesizeable_vhdl-model-library:lib_cla_adder.svg?nolink&300|Carry-Lookahead-Adder block diagram}} ===== Ports ===== a, b : parameterizeable binary values (bit arrays) Carry_in : carry of the adder before. s : sum computed by the adder carry_out : carry for the next adder. ===== Model ===== -- ############################################################################ -- # Project : VHDL-Modellbibliothek # -- # # -- # Filename : cla_adder.vhd # -- # # -- # Schaltung : Carry-Lookahead-Adder # -- # # -- # Modell : cla_adder # -- # # -- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig # -- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf # -- # Datum : 12.12.1994 # -- ############################################################################ -- ############################################################################ -- # IEEE PACKAGES # -- ############################################################################ Library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; -- ############################################################################ ENTITY cla_adder IS GENERIC (BR : INTEGER := @BITBR); -- Bitbreite der zu addierenden Werte PORT ( a, b : IN UNSIGNED ((BR-1) DOWNTO 0); carry_in : IN STD_LOGIC; s : OUT UNSIGNED ((BR-1) DOWNTO 0); carry_out : OUT STD_LOGIC ); -- a, b : Eingabewerte fuer die beiden zu addierenden Binaerzahlen -- carry_in : Uebertragseingang von einen Addierer, dessen Ordnungs- -- stufe geringer ist. -- s : vom Addierer berechnete Summe -- carry_out : vom Addierer berechneter Uebertrag fuer einen Addierer -- der naechsthoeheren Ordnung; END cla_adder; ARCHITECTURE verhalten OF cla_adder IS SIGNAL carry :UNSIGNED (BR-1 DOWNTO 0); BEGIN cla: PROCESS(a,b,carry_in) -- Dieser Process stellt quasi eine Carry-Look-Ahead Einheit dar und -- berechnet aus den eingegebenen Binaerzahlen a und b und dem ein- -- gegebenen Uebertrag (carry_in) parallel die Uebertraege (Variable c) -- fuer die einzelnen Stufen und weist diese dem Signal carry bzw. -- carry_out zu. VARIABLE p : UNSIGNED ((BR-1) DOWNTO 0); -- "propagate" VARIABLE g : UNSIGNED ((BR-1) DOWNTO 0); -- "generate" VARIABLE c : UNSIGNED ( BR DOWNTO 0); -- Uebertraege der einzelnen Stufen BEGIN FOR i IN 0 TO (BR-1) LOOP g(i) := a(i) AND b(i); p(i) := a(i) OR b(i); END LOOP; c(0) := carry_in ; FOR i IN 0 TO (BR-1) LOOP c(i+1) := g(i) OR (p(i) AND c(i)); END LOOP; FOR i IN 0 TO (BR-1) LOOP carry(i) <= c(i); END LOOP; carry_out <= c(BR); END PROCESS; sum: PROCESS(a,b,carry) -- eigentliche Addition BEGIN FOR i IN 0 TO (BR-1) LOOP s(i) <= a(i) XOR b(i) XOR carry(i); END LOOP; END PROCESS; END verhalten; CONFIGURATION CFG_cla_adder OF cla_adder IS FOR verhalten END FOR; END CFG_cla_adder; ===== Testbench ===== -- ############################################################################ -- # Project : VHDL-Modellbibliothek # -- # # -- # Filename : tb_cla_adder.vhd # -- # # -- # Schaltung : Carry-Lookahead-Adder # -- # # -- # # -- # Modell : tb_cla_adder # -- # # -- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig # -- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf # -- # Datum : 07.12.1994 # -- ############################################################################ -- ############################################################################ -- # IEEE PACKAGES # -- ############################################################################ Library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; USE IEEE.math_real.all; -- wird fuer die Erzeugung von Zufallszahlen -- benoetigt -- ############################################################################ ENTITY TB_cla_adder IS GENERIC (X : INTEGER := @BITBR); -- Bitbreite der zu addierenden Werte END TB_cla_adder; ARCHITECTURE behaviour OF TB_cla_adder IS SIGNAL tb_a : UNSIGNED (X-1 DOWNTO 0); SIGNAL tb_b : UNSIGNED (X-1 DOWNTO 0); SIGNAL tb_carry_in : STD_LOGIC; SIGNAL tb_s : UNSIGNED (X-1 DOWNTO 0); SIGNAL tb_carry_out : STD_LOGIC; SIGNAL fehler_insg : STD_LOGIC; COMPONENT cla_adder PORT( a, b : IN UNSIGNED ((X-1) DOWNTO 0); carry_in : IN STD_LOGIC; s : OUT UNSIGNED ((X-1) DOWNTO 0); carry_out : OUT STD_LOGIC); END COMPONENT; BEGIN UUT: cla_adder -- einzige Schaltung PORT MAP(tb_a, tb_b, tb_carry_in, tb_s, tb_carry_out); carry: PROCESS BEGIN tb_carry_in <= '0'; Wait FOR 10 ns; LOOP tb_carry_in <= NOT(tb_carry_in); WAIT FOR 7 ns; END LOOP; END PROCESS; stim: PROCESS VARIABLE a_int : INTEGER; VARIABLE b_int : INTEGER; BEGIN a_int := RAND; b_int := RAND; tb_a <= CONV_UNSIGNED(a_int, tb_a'LENGTH); tb_b <= CONV_UNSIGNED(b_int, tb_b'LENGTH); WAIT FOR 0.1 ns; a_int := CONV_INTEGER(tb_a); b_int := CONV_INTEGER(tb_b); WAIT FOR 10 ns; LOOP ---------------------------------------------------------------- -- Bestimmung des 1. Operanden ---------------------------------------------------------------- a_int := RAND; tb_a <= CONV_UNSIGNED(a_int, tb_a'LENGTH); WAIT FOR 0.1 ns; a_int := CONV_INTEGER(tb_a); WAIT FOR 7.5 ns; ---------------------------------------------------------------- ---------------------------------------------------------------- -- Bestimmung des 2. Operanden ---------------------------------------------------------------- b_int := RAND; tb_b <= CONV_UNSIGNED(b_int, tb_b'LENGTH); WAIT FOR 0.1 ns; b_int := CONV_INTEGER(tb_b); WAIT FOR 12.3 ns; ---------------------------------------------------------------- END LOOP; END PROCESS; contr: PROCESS(tb_s, tb_carry_out) VARIABLE s_chk : INTEGER; VARIABLE s_int : INTEGER; VARIABLE a_uchk : INTEGER; VARIABLE b_uchk : INTEGER; VARIABLE c_out : STD_LOGIC; VARIABLE unzul_bitkomb : SIGNED((X-1) DOWNTO 0); -- s_sgn : Summe vom UUT empfangen im SIGNED-Format -- s_chk : Summe innerhalb der Testbench berechnet -- s_int : Summe vom UUT empfangen im Integerformat -- a_chk : Operand A wie er an das UUT gesandt wird, aber im -- : Integer-Format -- b_chk : Operand B wie er an das UUT gesandt wird, aber im -- : Integer-Format -- c_out : in der Testbench generiertes Carry out BEGIN unzul_bitkomb := CONV_SIGNED(0, unzul_bitkomb'LENGTH); unzul_bitkomb(unzul_bitkomb'LENGTH-1) := '1'; s_chk := CONV_INTEGER(tb_s); a_uchk := CONV_INTEGER(tb_a); b_uchk := CONV_INTEGER(tb_b); -- -------------------------------------------------------------------- -- "Gut-Modell" -- -------------------------------------------------------------------- -- Bestimmen der Summe IF (tb_carry_in = '0') THEN s_int := a_uchk + b_uchk; ELSIF (tb_carry_in = '1') THEN s_int := a_uchk + b_uchk + 1; END IF; -- Bestimmen des Uebertrags und korrigieren der Summe IF (s_int > (2**X)-1) THEN s_int := s_int - (2**X); c_out := '1'; ELSE c_out := '0'; END IF; -- -------------------------------------------------------------------- -- -------------------------------------------------------------------- -- Vergleich zwischen UUT und Gut-Modell -- -------------------------------------------------------------------- IF ((s_int=s_chk) AND (tb_carry_out = c_out)) THEN fehler_insg <= '0'; ELSE fehler_insg <= '1'; END IF; END PROCESS; END behaviour; CONFIGURATION CFG_TB_cla_adder OF TB_cla_adder IS FOR behaviour FOR UUT: cla_adder USE CONFIGURATION WORK.CFG_cla_adder; END FOR; END FOR; END CFG_TB_cla_adder; ===== Synopsys VSS Trace ===== tr tb_a tr tb_b tr tb_carry_in tr tb_s tr tb_carry_out tr fehler_insg cd stim tr a_int tr b_int cd contr tr s_int