====== 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