synthesizeable_vhdl-model-library:array-divider-multiplier

Array-Divider-Multiplier

Eine kurze Funktions- und Schnittstellenbeschreibung:

  • Das Modell des Dividierers/Multiplizierers ist ein in der Bitbreite parametrisierbares (@BITBR) Modul zur Multiplikation oder Division zweier Operanden im 2'er-Komplement (vorzeichenbehaftet).
  • Die Algorithmen sind asynchron implementiert.
  • mode = 1 → op_1/op_2 = erg_1: Quotient ; erg_2: Rest
  • mode = 0 → op_1*op_2 = erg_1: höherwert. Produkt ; erg_2: niederwert. Produkt

Array-Divider-Multiplier block diagram

  • mode : Moduswahl, in dem sich das Modul befindet:
    • mode = 1 → Division
    • mode = 0 → Multiplikation
  • op_1 : Eingangsport fuer 1. Operanden
    • bei der Division: Dividend
    • bei der Multiplikation: Multiplikant
  • op_2 : Eingangsport fuer 2. Operanden
    • bei der Division: Diviso
    • bei der Multiplikation: Multiplikant
  • erg_1 : Ausgangsport für 1. Teil des Ergebnisses
    • bei der Division: Quotient
    • bei der Muliplikation: höherwertiger Teil des Produktes
  • erg_2 : Ausgangsport fuer 2. Teil des Ergebnisses
    • bei der Division: Rest
    • bei der Muliplikation: niederwertiger Teil des Produktes
array_divider_multiplier.vhd
-- ############################################################################
-- # Project    :    VHDL-Modellbibliothek				      #
-- #                                                                          #
-- # Filename   :    array_divider_multiplier.vhd                             #
-- #                                                                          #
-- # Schaltung  :    Modul zur Multiplikation/Division zweier Binaer- 	      #
-- #                 zahlen in 2'er Komplementdarstellung                     #
-- #                                                                          #
-- # Modell	:    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;
-- ############################################################################
 
 
ENTITY array_divider_multiplier IS
	GENERIC(X :INTEGER := @BITBR);  -- X := Operandenbreite
				   	  -- symmetrisches Array X * X
	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));
 
	-- mode		: Moduswahl, in dem sich das Modul befindet:
	--		  o mode = 1  -> Division
	--		  o mode = 0  -> Multiplikation
	--
	-- op_1     	: Eingangsport fuer 1. Operanden
	-- 		  o bei der Division: 		Dividend
	--		  o bei der Multiplikation:	Multiplikant 
	--
	-- op_2		: Eingangsport fuer 2. Operanden
	--		  o bei der Division:		Divisor
	--		  o bei der Multiplikation	Multiplikator
	-- 
	-- 
	-- erg_1	: Ausgangsport fuer 1. Teil des Ergebnisses
	--		  o bei der Division:		Quotient
	--		  o bei der Muliplikation:	hoeherwertiger Teil
	--						des Produktes
	--
	-- erg_2	: Ausgangsport fuer 2. Teil des Ergebnisses
	--		  o bei der Division:		Rest
	--		  o bei der Muliplikation:	niederwertiger Teil
	--						des Produktes
	--
	-- -> Darstellung im 2'er Komplement
 
END array_divider_multiplier; 
 
 
ARCHITECTURE verhalten OF array_divider_multiplier IS
SIGNAL op_1_sgn	: SIGNED((X-1) DOWNTO 0);
SIGNAL op_2_sgn : SIGNED((X-1) DOWNTO 0);
 
BEGIN
 
   op_1_sgn <= CONV_SIGNED(op_1, op_1_sgn'LENGTH);
   op_2_sgn <= CONV_SIGNED(op_2, op_2_sgn'LENGTH);
 
 
   PROCESS(op_1_sgn, op_2_sgn, mode)
	CONSTANT eins : STD_LOGIC := '1';
 
	VARIABLE  ztld 		: SIGNED ((2*X-2) DOWNTO 0);
	VARIABLE  tlr		: SIGNED ((X-1)   DOWNTO 0);
 
 
 
	VARIABLE k_ztld			: UNSIGNED ((ztld'LENGTH-1) DOWNTO 0);
	VARIABLE k_tlr			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE vz			: UNSIGNED ( 1              DOWNTO 0);	
	VARIABLE a   			: UNSIGNED ((ztld'LENGTH-1) DOWNTO 0);
	VARIABLE a_ein			: UNSIGNED ((ztld'LENGTH-1) DOWNTO 0);
	VARIABLE b   			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE k_b 			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE q   			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE k_q			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE r			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE k_r			: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE sum 			: UNSIGNED ( tlr'LENGTH     DOWNTO 0);
	VARIABLE n_divisable		: UNSIGNED ((tlr'LENGTH-1)  DOWNTO 0);
	VARIABLE n_div_detect		: STD_LOGIC;
	VARIABLE b_add			: UNSIGNED ((tlr'LENGTH)    DOWNTO 0);
 
	VARIABLE zwischenerg_2		: UNSIGNED ((X*X-1)	    DOWNTO 0);
	VARIABLE p			: UNSIGNED (2*X-1 DOWNTO 0);
	VARIABLE k_p			: UNSIGNED ((ztld'LENGTH) DOWNTO 0);
	VARIABLE a_add			: UNSIGNED (X DOWNTO 0);
	VARIABLE mknt			: UNSIGNED ((X-1) DOWNTO 0);
	VARIABLE mktr			: UNSIGNED ((X-1) DOWNTO 0);
 
 
	-- ztld 		: enthaelt den Dividenden, aufbereitet
	--	  		: fuer den Divisionsalgorithmus
	--	
 	-- tlr			: enthaelt den Divisor, aufbereitet
	--	  		: fuer den Divisionsalgorithmus
	--
	-- k_ztld		: komplementierter Dividend aufbereitet fuer den
	--			: Divisionsalgorithmus
	-- 
	-- k_tlr		: komplementierter Divisor
	--
	-- vz			: 0 -> positives Vorzeichen
	--			: 1 -> negatives Vorzeichen
	--			: vz(1) Vorzeichen des Dividenden
	--			: vz(0) Vorzeichen des Divisors
	--
	-- a			: Variable fuer den aktuellen Dividenden
	-- 			: waehrend der Ausfuehrumg des
	--	              	: Divisionsalgorithmus
	--
	-- a_ein		: Variable fuer den Dividenden, der anfangs in
	--			: Divisionsalgorithmus uebernommen wird
	--
	-- b			: Variable fuer den Divisor (immer positiv)
	--
	-- k_b			: komplmentierter Divisor (immer negativ)
	--
	-- q			: Variable fuer den Quotienten
	--
	-- k_q			: komplementierter Quotient
	--		
	-- r			: ganzzahliger Rest der Division
	--
	-- k_r			: komplementierter ganzzahliger Rest der
	--			  Division
	--
	-- sum			: Ergebnis der Addition/Subtraktion in de
	--			  einzelnen Stufen
	--	
	-- n_divisable		: ist in der Stufe i Null, ab der der Dividend
	--			  nicht mehr weiter durch den Divisor teilbar
	--	   	 	  ist
	--			 
	-- n_div_detect		: ist 1, wenn der Dividend vor der letzten Zeile
	--		 	  nicht mehr durch den Divisor teilbar ist
	-- 
	-- b_add		: Zwischenspeichervariable fuer Addition
	--
	-- zwischenerg_2	: Stellt den aktuellen Zwischenerg_2 dar, der
	--			: sich aus dem Ergebnis der Addition/Subtraktion
	-- 			: und den noch nicht behandelten Stellen des
	-- 			: Dividenden zusammensetzt.
	--
	-- p			: erhaelt den Wert des Produktes im Falle  
	--			: einer Multiplikation
	--
	-- k_p			: 2'er Komplement des Produktes
	--
	-- a_add		: ein Summand fuer den Addierer
	--			
	-- mknt			: Multiplikant
	--
	-- mktr			: Multiplikator
	--
 
   BEGIN
	-- ####################################################################
	-- Eingangssignale bzw. komplementierte Eingangssignale werden den
	-- internen Variablen des PROCESS zugewiesen
	-- ####################################################################
	ztld := CONV_SIGNED(op_1_sgn, ztld'LENGTH);
   	tlr  := CONV_SIGNED(op_2_sgn, tlr'LENGTH);
 
 
	FOR i IN 0 TO (ztld'LENGTH-1) LOOP
	  k_ztld(i) := NOT(ztld(i));
	END LOOP;
	k_ztld := k_ztld + eins;
 
	FOR i IN 0 TO (tlr'LENGTH-1) LOOP
	   k_tlr(i) := NOT(tlr(i));
	END LOOP;
	k_tlr := k_tlr + eins;
 
	IF (op_1_sgn(op_1_sgn'LENGTH-1) = '1') THEN
	   vz(1) := '1';
	ELSE 
	   vz(1) := '0';
	END IF;
 
	IF (op_2_sgn(op_2_sgn'LENGTH-1) = '1') THEN
	   vz(0) := '1';
	ELSE
	   vz(0) := '0';
	END IF;
 
	CASE vz IS
	      WHEN "00" =>  	a 	:= CONV_UNSIGNED(ztld,a'LENGTH);
				a_ein 	:= CONV_UNSIGNED(ztld,a'LENGTH);
				b 	:= CONV_UNSIGNED(tlr, b'LENGTH);
				mknt 	:= CONV_UNSIGNED(op_1_sgn, mknt'LENGTH);
				mktr	:= CONV_UNSIGNED(op_2_sgn, mktr'LENGTH);
 
 
	      WHEN "01" => 	a 	:= CONV_UNSIGNED(ztld,  a'LENGTH);
				a_ein	:= CONV_UNSIGNED(ztld,  a'LENGTH);
				b 	:= CONV_UNSIGNED(k_tlr, b'LENGTH);
				mknt 	:= CONV_UNSIGNED(op_1_sgn, mknt'LENGTH);
				mktr	:= CONV_UNSIGNED(k_tlr, mktr'LENGTH);
 
 
	      WHEN "10" => 	a 	:= CONV_UNSIGNED(k_ztld,a'LENGTH);
				a_ein	:= CONV_UNSIGNED(k_ztld,a'LENGTH);
				b 	:= CONV_UNSIGNED(tlr,   b'LENGTH);
				mknt 	:= CONV_UNSIGNED(k_ztld((X-1) DOWNTO 0),
					   mknt'LENGTH);
				mktr	:= CONV_UNSIGNED(op_2_sgn, mktr'LENGTH);
 
	      WHEN "11" => 	a 	:= CONV_UNSIGNED(k_ztld,a'LENGTH);
				a_ein 	:= CONV_UNSIGNED(k_ztld,a'LENGTH);
				b 	:= CONV_UNSIGNED(k_tlr, b'LENGTH);	
				mknt 	:= CONV_UNSIGNED(k_ztld((X-1) DOWNTO 0),
					   mknt'LENGTH);
				mktr	:= CONV_UNSIGNED(k_tlr, mktr'LENGTH);
 
	      WHEN OTHERS =>	a 	:= CONV_UNSIGNED(0, a'LENGTH);
				a_ein 	:= CONV_UNSIGNED(0, a'LENGTH);
				b 	:= CONV_UNSIGNED(0, b'LENGTH);
				mknt 	:= CONV_UNSIGNED(0, mknt'LENGTH);
				mktr	:= CONV_UNSIGNED(0, mktr'LENGTH);
	END CASE;
	-- ####################################################################
 
 
 
	-- ####################################################################
	-- Divisionsalgorithmus/Multiplikationsalgorithmus
	-- ####################################################################
	IF (mode = '1') THEN
	   sum(tlr'LENGTH) := '1';
	ELSE
	   sum := CONV_UNSIGNED(0, X+1);
	   p   := CONV_UNSIGNED(0, p'LENGTH);
	END IF;
 
	zwischenerg_2 := CONV_UNSIGNED(0, zwischenerg_2'LENGTH);
 
   	FOR n IN 0 TO (tlr'LENGTH-1) LOOP
	   k_b(n) := NOT(b(n));
	END LOOP;
	k_b := k_b + eins;
 
	FOR i IN 0 TO (tlr'LENGTH-1) LOOP
	   --------------------------------------------------------------------
      	   -- Addition oder Subtraktion des Divisors in Abhaengigkeit des
	   -- Uebertrags der zuvor erfolgten Rechenoperation
	   --------------------------------------------------------------------
	   b_add := CONV_UNSIGNED(0, b_add'LENGTH);   -- Vermeidung von Latches
	   IF (mode = '1') THEN			      -- Division 
	      IF sum(tlr'LENGTH) = '1' THEN
		   b_add := CONV_UNSIGNED(k_b, tlr'LENGTH+1); 
	      ELSIF sum(tlr'LENGTH) ='0' THEN 
		   b_add := CONV_UNSIGNED(b, tlr'LENGTH+1);
	      END IF;
	      a_add :=  CONV_UNSIGNED(a(ztld'LENGTH-1-i DOWNTO
		        ztld'LENGTH-tlr'LENGTH-i), tlr'LENGTH+1);
 
	   ELSE					      -- Multiplikation
	      b_add := CONV_UNSIGNED(0, b_add'LENGTH);
	      FOR k IN 0 TO (X-1) LOOP
		 b_add(k) := mknt(k) AND mktr(i);
	      END LOOP; 
	      a_add := CONV_UNSIGNED(sum(X DOWNTO 1),
				     a_add'LENGTH);      
	   END IF;
 
	   sum := a_add + b_add;
	   -------------------------------------------------------------------
 
 
 
	   -------------------------------------------------------------------
	   -- sichern des Zwischenergebnisses mit angehaengtem Dividendenerg_2
	   -------------------------------------------------------------------
 
	   FOR k IN 0 TO (X-1-1-i) LOOP
		zwischenerg_2(i*X+k) := a_ein(k);
	   END LOOP;
 
	   FOR l IN 0 TO i LOOP 
		zwischenerg_2(i*X+(X-1-i+l)) := sum(l);
	   END LOOP;
 
	   -------------------------------------------------------------------
 
 
 
	   -------------------------------------------------------------------
	   -- Umlagern der Zwischenergebnisse und Ablagern der endgueltigen
	   -- Ergebnisse
	   -------------------------------------------------------------------
	   -- fuer Divisionsalgorithmus
	   FOR m IN 1 TO (tlr'LENGTH-1) LOOP
	      a(ztld'LENGTH-m-1-i) := sum(tlr'LENGTH-m-1);
	   END LOOP;
	   q(tlr'LENGTH-1-i)	 := sum(tlr'LENGTH); 
				  -- Uebertrag bei der Addition stellt
				  -- Quotientenstelle dar
 
	   -- fuer Multiplikationsalgorithmus
	   p(i) := sum(0);
	   -------------------------------------------------------------------
	END LOOP;
 
	FOR i IN X TO (2*X-1) LOOP
	    p(i) := sum(i-X+1);
	END LOOP;				
 
	-- ####################################################################
	-- Restkorrektur
	-- ####################################################################
	r := CONV_UNSIGNED('0', tlr'LENGTH);
	n_div_detect := '0';
 
	-- --------------------------------------------------------------------
	-- Ueberpruefung der Teilbarkeit
	-- --------------------------------------------------------------------
	FOR i IN 0 TO (tlr'LENGTH-1) LOOP
	   IF (i < tlr'LENGTH-1) THEN
	      IF (q(tlr'LENGTH-1-i) = '1') THEN
		 n_divisable(i) := '0';
	         FOR l IN i+1 TO (tlr'LENGTH-1) LOOP
	             n_divisable(i) := n_divisable(i) OR (q(tlr'LENGTH-1-l));
	         END LOOP;
	      ELSE
	       	 n_divisable(i) := '1';		 
	      END IF;
	   END IF;
	END LOOP;
 
	-- --------------------------------------------------------------------
	-- Zuweisung des entsprechenden Restes
	-- --------------------------------------------------------------------
	IF (q = CONV_UNSIGNED(0, tlr'LENGTH)) THEN
	   r := CONV_UNSIGNED(a_ein((tlr'LENGTH-1) DOWNTO 0), tlr'LENGTH);
	ELSE
	   FOR i IN 1 TO (tlr'LENGTH-1) LOOP
	      IF (i < tlr'LENGTH-1) THEN
	         IF (n_divisable(i) = '0') THEN
		     r := CONV_UNSIGNED(zwischenerg_2(i*X+X-1 DOWNTO i*X), 
		  		        tlr'LENGTH);
		     n_div_detect := '1';
	         END IF;
	      ELSE
		 IF (n_div_detect = '0') THEN
		     r := CONV_UNSIGNED(zwischenerg_2(i*X+X-1 DOWNTO i*X), 
		  		        tlr'LENGTH);
		 END IF;
	      END IF;
 
	   END LOOP;
	END IF; 
	-- ####################################################################
 
 
 
	-- ####################################################################
	-- interne Variablen werden Ausgangssignalen zugewiesen
	-- ####################################################################
	FOR i IN 0 TO (q'LENGTH-1) LOOP
	   k_q(i) := NOT(q(i));
	END LOOP;
	k_q := k_q + CONV_UNSIGNED(1, q'LENGTH);
 
	FOR i IN 0 TO (r'LENGTH-1) LOOP
	   k_r(i) := NOT(r(i));
	END LOOP;
	k_r := k_r + eins;
 
	FOR i IN 0 TO (p'LENGTH-1) LOOP
	   k_p(i) := NOT(p(i));
	END LOOP;
	k_p := k_p + eins; 
 
 
 
	IF (mode = '1') THEN
	   CASE vz IS
	      WHEN "00" 	=>  erg_1 <= q;
			      	    erg_2 <= r;
 
	      WHEN "01" 	=>  erg_1 <= k_q;
			    	    erg_2 <= r;
 
	      WHEN "10" 	=>  erg_1 <= k_q;
			    	    erg_2 <= k_r;
 
	      WHEN "11" 	=>  erg_1 <= q;
			    	    erg_2 <= k_r;
 
	      WHEN OTHERS 	=>  erg_1 <= CONV_UNSIGNED(0, erg_1'LENGTH);
			            erg_2 <= CONV_UNSIGNED(0, erg_2'LENGTH);
 
	   END CASE;
	ELSE
	   CASE vz IS
	      WHEN "00" 	=>  erg_2 <= CONV_UNSIGNED(p(erg_1'LENGTH-1
					     DOWNTO 0), erg_1'LENGTH);
			      	    erg_1 <= CONV_UNSIGNED(p(2*X-1 DOWNTO X),
					     erg_2'LENGTH);
 
	      WHEN "01" 	=>  erg_2 <= CONV_UNSIGNED(k_p(erg_1'LENGTH-1
					     DOWNTO 0), erg_1'LENGTH);
			      	    erg_1 <= CONV_UNSIGNED(k_p(2*X-1 DOWNTO X),
					     erg_2'LENGTH);
 
	      WHEN "10" 	=>  erg_2 <= CONV_UNSIGNED(k_p(erg_1'LENGTH-1
					     DOWNTO 0), erg_1'LENGTH);
			      	    erg_1 <= CONV_UNSIGNED(k_p(2*X-1 DOWNTO X),
					     erg_2'LENGTH);
 
	      WHEN "11" 	=>  erg_2 <= CONV_UNSIGNED(p(erg_1'LENGTH-1
					     DOWNTO 0), erg_1'LENGTH);
			      	    erg_1 <= CONV_UNSIGNED(p(2*X-1 DOWNTO X),
					     erg_2'LENGTH);
 
	      WHEN OTHERS 	=>  erg_2 <= CONV_UNSIGNED(0, erg_1'LENGTH);
			            erg_1 <= CONV_UNSIGNED(0, erg_2'LENGTH);
 
	   END CASE;
	END IF;
	-- ####################################################################
 
   END PROCESS;
END verhalten;
 
CONFIGURATION CFG_array_divider_multiplier OF array_divider_multiplier IS
   FOR verhalten
   END FOR;
END CFG_array_divider_multiplier;
tb_array_divider_multiplier.vhd
-- ############################################################################
-- # 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;
trace_array_divider_multiplier.vhd
tr tb_mode
tr tb_op_1
tr tb_op_2
tr tb_erg_1
tr tb_erg_2
tr fehler_num
tr fehler_bereich
tr fehler_insg
 
cd stim
tr op_1_int
tr op_2_int
 
cd contr
tr quot_int
tr rest_int
tr produkt_int