synthesizeable_vhdl-model-library:carry-lookahead-adder

Carry-Lookahead-Adder

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.

Carry-Lookahead-Adder block diagram

    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.
cla_adder.vhd
-- ############################################################################
-- # 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;
tb_cla_adder.vhd
-- ############################################################################
-- # 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;
trace_cla_adder.vhd
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