-- ############################################################################ -- # Project : VHDL-Modellbibliothek # -- # # -- # Filename : tb_array_divider.vhd # -- # # -- # Schaltung : Array-Dividierer Testbench # -- # # -- # Modell : tb_array_divider # -- # # -- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig # -- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf # -- # Datum : 20.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 IS GENERIC(X :INTEGER := @BITBR); -- symmetrisches Array X * X END TB_array_divider; ARCHITECTURE verhalten OF TB_array_divider IS SIGNAL tb_dvd : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_dvs : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_quot : UNSIGNED ((X-1) DOWNTO 0); SIGNAL tb_rest : UNSIGNED ((X-1) DOWNTO 0); SIGNAL fehler_num : STD_LOGIC; SIGNAL fehler_bereich : STD_LOGIC; SIGNAL fehler_insg : STD_LOGIC; -- tb_dvd : Dividend, der von der Testbench stimuliert wird -- : -- tb_dvs : Divisor, der von der Testbench stimuliert wird -- : -- tb_quot : Quotient, den die Testbench vom UUT empfaengt -- : -- tb_rest : 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 PORT(dvd : IN UNSIGNED ((X-1) DOWNTO 0); dvs : IN UNSIGNED ((X-1) DOWNTO 0); quot : OUT UNSIGNED ((X-1) DOWNTO 0); rest : OUT UNSIGNED ((X-1) DOWNTO 0)); END COMPONENT; BEGIN UUT: array_divider -- einzige Schaltung PORT MAP(tb_dvd, tb_dvs, tb_quot, tb_rest); stim: PROCESS VARIABLE dividend_int : INTEGER; VARIABLE divisor_int : INTEGER; VARIABLE tb_dividend_var : SIGNED((X-1) DOWNTO 0); VARIABLE tb_divisor_var : SIGNED((X-1) DOWNTO 0); -- dividend_int : Dividend als Integerzahl dargestellt -- divisor_int : Divisor als Integerzahl dargestellt -- tb_dividend_var : Dividend im SIGNED-Format dargestellt -- tb_divisor_var : Divisor im SIGNED-Format dargestellt BEGIN dividend_int := RAND; divisor_int := RAND; tb_dividend_var := CONV_SIGNED(dividend_int, tb_dividend_var'LENGTH); tb_divisor_var := CONV_SIGNED(divisor_int, tb_divisor_var'LENGTH); tb_dvd <= CONV_UNSIGNED(tb_dividend_var, tb_dvd'LENGTH); tb_dvs <= CONV_UNSIGNED(tb_divisor_var, tb_dvs'LENGTH); WAIT FOR 0.1 ns; tb_dividend_var := CONV_SIGNED(tb_dvd, tb_dividend_var'LENGTH); tb_divisor_var := CONV_SIGNED(tb_dvs, tb_divisor_var'LENGTH); dividend_int := CONV_INTEGER(tb_dividend_var); divisor_int := CONV_INTEGER(tb_divisor_var); WAIT FOR 10 ns; LOOP -- ------------------------------------------------------------ -- Bestimmmung des Dividenden -- ------------------------------------------------------------ dividend_int := RAND; tb_dividend_var := CONV_SIGNED(dividend_int, tb_dividend_var'LENGTH); tb_dvd <= CONV_UNSIGNED(tb_dividend_var, tb_dvd'LENGTH); WAIT FOR 0.1 ns; tb_dividend_var := CONV_SIGNED(tb_dvd, tb_dividend_var'LENGTH); dividend_int := CONV_INTEGER(tb_dividend_var); WAIT FOR 7.5 ns; -- ------------------------------------------------------------ -- ------------------------------------------------------------ -- Bestimmung des Divisors -- ------------------------------------------------------------ divisor_int := RAND; tb_divisor_var := CONV_SIGNED(divisor_int, tb_divisor_var'LENGTH); tb_dvs <= CONV_UNSIGNED(tb_divisor_var, tb_dvs'LENGTH); WAIT FOR 0.1 ns; tb_divisor_var := CONV_SIGNED(tb_dvs, tb_divisor_var'LENGTH); divisor_int := CONV_INTEGER(tb_divisor_var); WAIT FOR 12.3 ns; -- ------------------------------------------------------------ END LOOP; END PROCESS; contr: Process(tb_quot, tb_rest) VARIABLE quot_sgn : SIGNED(tb_quot'LENGTH-1 DOWNTO 0); VARIABLE rest_sgn : SIGNED(tb_rest'LENGTH-1 DOWNTO 0); VARIABLE quot_int : INTEGER; VARIABLE rest_int : INTEGER; VARIABLE quot_chk : INTEGER; VARIABLE rest_chk : INTEGER; VARIABLE dividend_chk : INTEGER; VARIABLE divisor_chk : INTEGER; VARIABLE dividend_chk_sgn : SIGNED((X-1) DOWNTO 0); VARIABLE divisor_chk_sgn : SIGNED((X-1) DOWNTO 0); VARIABLE unzul_bitkomb : UNSIGNED ((X-1) DOWNTO 0); -- 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 -- : -- dividend_chk : Dividend wie er als Stimuli vorliegt, -- : aber im Integer-Format -- : -- divisor_chk : Divisor wie er als Stimuli vorliegt, -- : aber im Integer-Format -- : -- divisor_chk_sgn : Divisor sie er als Stimuli vorliegt, -- : aber im SIGNED-Format -- : -- dividend_chk_sgn : Dividend 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) BEGIN -- ----------------------------------------------------------------- -- Abfragen der am UUT anliegenden Signale -- ----------------------------------------------------------------- dividend_chk_sgn := CONV_SIGNED(tb_dvd, dividend_chk_sgn'LENGTH); divisor_chk_sgn := CONV_SIGNED(tb_dvs, divisor_chk_sgn'LENGTH); dividend_chk := CONV_INTEGER(dividend_chk_sgn); divisor_chk := CONV_INTEGER(divisor_chk_sgn); FOR i IN 0 TO (tb_quot'LENGTH-1) LOOP quot_sgn(i) := tb_quot(i); END LOOP; quot_int := CONV_INTEGER(quot_sgn); FOR i IN 0 TO (tb_rest'LENGTH-1) LOOP rest_sgn(i) := tb_rest(i); END LOOP; rest_int := CONV_INTEGER(rest_sgn); -- ----------------------------------------------------------------- -- ----------------------------------------------------------------- -- Berechnung der Ausgangssignale, die am UUT anliegen muessen, -- lediglich aufgrund der Eingangssignale -- "Vergleichsmodell" -- ----------------------------------------------------------------- IF ( divisor_chk /= 0) THEN quot_chk := dividend_chk / divisor_chk; rest_chk := dividend_chk - (divisor_chk*quot_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_dvd'LENGTH); unzul_bitkomb(tb_dvd'LENGTH-1) := '1'; IF (tb_dvd = unzul_bitkomb) THEN fehler_num <= '0'; fehler_bereich <= '1'; fehler_insg <= '0'; ELSIF (divisor_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; -- ----------------------------------------------------------------- END PROCESS; END verhalten; CONFIGURATION CFG_TB_array_divider OF TB_array_divider IS FOR verhalten FOR UUT: array_divider USE CONFIGURATION WORK.CFG_array_divider; END FOR; END FOR; END CFG_TB_array_divider;