-- ############################################################################ -- # Project : VHDL-Modellbibliothek # -- # # -- # Filename : tb_array_divider_multiplier.vhd # -- # # -- # Schaltung : Testbench fuer Divisions/Multiplikations-Modul # -- # # -- # tb_array_divider_multiplier # -- # # -- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig # -- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf # -- # Datum : 23.01.1995 # -- ############################################################################ -- ############################################################################ -- # 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_array_divider_multiplier IS GENERIC(X :INTEGER := @BITBR); -- symmetrisches Array X * X END TB_array_divider_multiplier; ARCHITECTURE verhalten OF TB_array_divider_multiplier IS SIGNAL tb_mode : STD_LOGIC; SIGNAL tb_op_1 : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_op_2 : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_erg_1 : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_erg_2 : UNSIGNED ((X-1) DOWNTO 0); SIGNAL fehler_num : STD_LOGIC; SIGNAL fehler_bereich : STD_LOGIC; SIGNAL fehler_insg : STD_LOGIC; -- tb_mode : Modus, der von der Testbench stimuliert wird -- -- tb_op_1 : Dividend, der von der Testbench stimuliert wird -- -- tb_op_2 : Divisor, der von der Testbench stimuliert wird -- -- tb_erg_1 : Quotient, den die Testbench vom UUT empfaengt -- -- tb_erg_2 : Rest den die Testbench vom UUT empfaengt -- -- fehler_num : ist nur '1', wenn Division durch Null auftritt -- -- fehler_bereich : ist nur '1', wenn ein von der Testbench -- : ausgegebener Stimuli den Darstellungsbereich -- : der Zahl in der gewawehlten Bitbreite uebersteigt -- -- fehler_insg : ist '1', wenn ein Fehler auftritt der auf -- : UUT zurueckzufuehren ist COMPONENT array_divider_multiplier PORT(mode : IN STD_LOGIC; op_1 : IN UNSIGNED ((X-1) DOWNTO 0); op_2 : IN UNSIGNED ((X-1) DOWNTO 0); erg_1 : OUT UNSIGNED ((X-1) DOWNTO 0); erg_2 : OUT UNSIGNED ((X-1) DOWNTO 0) ); END COMPONENT; BEGIN UUT: array_divider_multiplier -- einzige Schaltung PORT MAP(tb_mode, tb_op_1, tb_op_2, tb_erg_1, tb_erg_2); mode: PROCESS BEGIN tb_mode <= '0'; WAIT FOR 500 ns; LOOP tb_mode <= NOT(tb_mode); WAIT FOR 500 ns; END LOOP; END PROCESS; stim: PROCESS VARIABLE op_1_int : INTEGER; VARIABLE op_2_int : INTEGER; VARIABLE tb_op_1_var : SIGNED((X-1) DOWNTO 0); VARIABLE tb_op_2_var : SIGNED((X-1) DOWNTO 0); -- op_1_int : 1. Operand als Integerzahl dargestellt -- op_2_int : 2. Operand als Integerzahl dargestellt -- tb_op_1_var : 1. Operand im SIGNED-Format dargestellt -- tb_op_2_var : 2. Operand im SIGNED-Format dargestellt BEGIN op_1_int := RAND; op_2_int := RAND; tb_op_1_var := CONV_SIGNED(op_1_int, tb_op_1'LENGTH); tb_op_2_var := CONV_SIGNED(op_2_int, tb_op_2'LENGTH); tb_op_1 <= CONV_UNSIGNED(tb_op_1_var, tb_op_2_var'LENGTH); tb_op_2 <= CONV_UNSIGNED(tb_op_2_var, tb_op_1_var'LENGTH); WAIT FOR 0.1 ns; tb_op_1_var := CONV_SIGNED(tb_op_1, tb_op_1_var'LENGTH); tb_op_2_var := CONV_SIGNED(tb_op_2, tb_op_2_var'LENGTH); op_1_int := CONV_INTEGER(tb_op_1_var); op_2_int := CONV_INTEGER(tb_op_2_var); WAIT FOR 100 ns; LOOP -- ------------------------------------------------------------ -- Bestimmmung des 1. Operanden -- ------------------------------------------------------------ op_1_int := RAND; tb_op_1_var := CONV_SIGNED(op_1_int, tb_op_1_var'LENGTH); tb_op_1 <= CONV_UNSIGNED(tb_op_1_var, tb_op_1'LENGTH); WAIT FOR 0.1 ns; tb_op_1_var := CONV_SIGNED(tb_op_1, tb_op_1_var'LENGTH); op_1_int := CONV_INTEGER(tb_op_1_var); WAIT FOR 75 ns; -- ------------------------------------------------------------ -- ------------------------------------------------------------ -- Bestimmung des 2. Operanden -- ------------------------------------------------------------ op_2_int := RAND; tb_op_2_var := CONV_SIGNED(op_2_int, tb_op_2_var'LENGTH); tb_op_2 <= CONV_UNSIGNED(tb_op_2_var, tb_op_2'LENGTH); WAIT FOR 0.1 ns; tb_op_2_var := CONV_SIGNED(tb_op_2, tb_op_2_var'LENGTH); op_2_int := CONV_INTEGER(tb_op_2_var); WAIT FOR 100 ns; -- ------------------------------------------------------------ END LOOP; END PROCESS; contr: Process(tb_erg_1, tb_erg_2, tb_mode) VARIABLE quot_sgn : SIGNED(tb_erg_1'LENGTH-1 DOWNTO 0); VARIABLE rest_sgn : SIGNED(tb_erg_2'LENGTH-1 DOWNTO 0); VARIABLE quot_int : INTEGER; VARIABLE rest_int : INTEGER; VARIABLE quot_chk : INTEGER; VARIABLE rest_chk : INTEGER; VARIABLE op_1_chk : INTEGER; VARIABLE op_2_chk : INTEGER; VARIABLE op_1_sgn_var : SIGNED((X-1) DOWNTO 0); VARIABLE op_2_sgn_var : SIGNED((X-1) DOWNTO 0); VARIABLE unzul_bitkomb : UNSIGNED((X-1) DOWNTO 0); VARIABLE produkt_sgn : SIGNED(2*X-1 DOWNTO 0); VARIABLE produkt_chk : INTEGER; VARIABLE produkt_int : INTEGER; -- quot_sgn : Quotient vom UUT empfangen im SIGNED-Format -- : -- rest_sgn : Rest vom UUT empfangen im SIGNED-Format -- : -- quot_int : Quotient vom UUT empfangen im Integer-Format -- : -- rest_sgn : Rest vom UUT empfangen im Integer-Format -- : -- quot_chk : Quotient innerhalb der Testbench berechnet -- : im Integer-Format -- : -- rest_chk : Rest innerhalb der Testbench berechnet -- : im Integer-Format -- : -- op_1_chk : Dividend wie er als Stimuli vorliegt, -- : aber im Integer-Format -- : -- op_2_chk : Divisor wie er als Stimuli vorliegt, -- : aber im Integer-Format -- : -- op_1_sgn_var : Dividend wie er als Stimuli vorliegt, -- : aber im SIGNED-Format -- : -- op_2_sgn_var : Divisor wie er als Stimuli vorliegt, -- : aber im SIGNED-Format -- : -- unzul_bitkomb : In dieser Variable wird die entsprechende -- : unzulaessige Bitkombination abgelegt die -- : eine Bereichsueberschreitung im jeweiligen -- : Zahlenformat darstellt. -- : (naemlich: 100.....000) -- : -- produkt_sgn : Produkt vom UUT empfangen im SIGNED-Format -- : -- produkt_chk : Produkt vom UUT empfangen im Integer-Format -- : -- : -- produkt_int : Produkt, wie es innerhalb der Testbench -- : berechnet wurde BEGIN produkt_sgn := CONV_SIGNED(0, produkt_sgn'LENGTH); -- ----------------------------------------------------------------- -- Abfragen der am UUT anliegenden Signale -- ----------------------------------------------------------------- op_1_sgn_var := CONV_SIGNED(tb_op_1, op_1_sgn_var'LENGTH); op_2_sgn_var := CONV_SIGNED(tb_op_2, op_2_sgn_var'LENGTH); op_1_chk := CONV_INTEGER(op_1_sgn_var); op_2_chk := CONV_INTEGER(op_2_sgn_var); FOR i IN 0 TO (tb_erg_2'LENGTH-1) LOOP rest_sgn(i) := tb_erg_2(i); produkt_sgn(i) := tb_erg_2(i); END LOOP; rest_int := CONV_INTEGER(rest_sgn); FOR i IN 0 TO (tb_erg_1'LENGTH-1) LOOP quot_sgn(i) := tb_erg_1(i); produkt_sgn(i+X) := tb_erg_1(i); END LOOP; quot_int := CONV_INTEGER(quot_sgn); produkt_chk := CONV_INTEGER(produkt_sgn); -- ----------------------------------------------------------------- -- ----------------------------------------------------------------- -- Berechnung der Ausgangssignale, die am UUT anliegen muessen, -- lediglich aufgrund der Eingangssignale -- "Vergleichsmodell" -- ----------------------------------------------------------------- IF (tb_mode = '1') THEN IF ( op_2_chk /= 0) THEN quot_chk := op_1_chk / op_2_chk; rest_chk := op_1_chk - (op_2_chk*quot_chk); END IF; ELSIF (tb_mode = '0') THEN produkt_int := op_1_chk * op_2_chk; END IF; -- ----------------------------------------------------------------- -- ----------------------------------------------------------------- -- Ueberpruefung, ob die Zahlenwerte, die im UUT berechnet wurden, -- mit denen, die hier in der Testbench berechnet wurden ueberein- -- stimmen bzw., ob andere Fehler auftreten -- ----------------------------------------------------------------- unzul_bitkomb := CONV_UNSIGNED(0, tb_op_1'LENGTH); unzul_bitkomb(tb_op_1'LENGTH-1) := '1'; IF (tb_mode = '1') THEN IF (tb_op_1 = unzul_bitkomb) THEN fehler_num <= '0'; fehler_bereich <= '1'; fehler_insg <= '0'; ELSIF (op_2_chk = 0) THEN fehler_num <= '1'; fehler_bereich <= '0'; fehler_insg <= '0'; ELSE IF (quot_chk /= quot_int) OR (rest_chk /= rest_int) THEN fehler_num <= '0'; fehler_bereich <= '0'; fehler_insg <= '1'; ELSE fehler_num <= '0'; fehler_bereich <= '0'; fehler_insg <= '0'; END IF; END IF; ELSIF (tb_mode = '0') THEN IF (tb_op_1 = unzul_bitkomb) THEN fehler_num <= '0'; fehler_bereich <= '1'; fehler_insg <= '0'; ELSE IF (produkt_chk /= produkt_int) THEN fehler_num <= '0'; fehler_bereich <= '0'; fehler_insg <= '1'; ELSE fehler_num <= '0'; fehler_bereich <= '0'; fehler_insg <= '0'; END IF; END IF; END IF; -- ----------------------------------------------------------------- END PROCESS; END verhalten; CONFIGURATION CFG_TB_array_divider_multiplier OF TB_array_divider_multiplier IS FOR verhalten FOR UUT: array_divider_multiplier USE CONFIGURATION WORK.CFG_array_divider_multiplier; END FOR; END FOR; END CFG_TB_array_divider_multiplier;