====== UNIVERSAL MULTIPLIER ====== The UNIVERSAL MULTIPLIER consists of the following generic component: * [[.:universal_multiplier#model|universal_multiplier]] The UNIVERSAL MULTIPLIER can be verified with this testbench: * [[.:universal_multiplier#testbench|test_universal_multiplier]] This component implements an universal multiplier according to the data represenation that is used for the multiplication. More specifically the two variable-length operands , i.e. the N-bit multiplicand and the M-bit multiplier , are multiplied and the N+M-bit result is returned. The produced results depends on a 2-bit "mode" selector which may have four values : "00" means unsigned multiplication, "01" sign magnitude multiplication, "10" 1's complement multiplication and finally "11" means 2's complement multiplication. ===== Model ===== -- ############################################################################### -- # Project : Leonardo CBT-Kernel # -- # # -- # Filename : universal_multiplier.vhd # -- # # -- # Component : universal_multiplier : Universal multiplier NxM bits. # -- # According to MODE operand one of the following multiplications # -- # are performed : # -- # MODE="00" : unsigned multiplication. # -- # MODE="01" : sign magnitude multiplication. # -- # MODE="10" : 1s complement multiplication. # -- # MODE="11" : 2s complement multiplication. # -- # # -- # GENERICS : # -- # N : # of bits of X operand (multiplicand). # -- # M : # of bits of Y operand (multiplier). # -- # For better synthesis results , M must be less or equal to N. # -- # # -- # Model : rtl # -- # # -- # Designer : S. Theoharis # -- # Institute : VLSI Design Lab., University of Patras # -- # Date : 01.05.1999 # -- ############################################################################### library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; ENTITY universal_multiplier IS GENERIC ( N : integer:= 4; -- # bits of X opernand. M : integer:= 4 -- # bits of Y opernand. ); PORT ( X : IN std_ulogic_vector(N-1 downto 0); Y : IN std_ulogic_vector(M-1 downto 0); MODE : IN std_ulogic_vector(1 downto 0); Z : OUT std_ulogic_vector(N+M-1 downto 0) ); END universal_multiplier; ARCHITECTURE behav OF universal_multiplier IS SIGNAL X_un : unsigned(N-1 downto 0); SIGNAL Y_un : unsigned(M-1 downto 0); SIGNAL Z_un : unsigned(N+M-1 downto 0); BEGIN X_un <= conv_unsigned(conv_integer("0" & X),N); Y_un <= conv_unsigned(conv_integer("0" & Y),M); Multiplier : PROCESS(MODE,X_un,Y_un) VARIABLE t_X : unsigned(N-1 downto 0); VARIABLE t_Y : unsigned(M-1 downto 0); VARIABLE t_Z : unsigned(N+M-1 downto 0); VARIABLE sign_X,sign_Y,sign_Z : std_logic; BEGIN IF (MODE="00") THEN -- Unsigned multiplication. Z_un <= X_un * Y_un; ELSIF (MODE="01") THEN -- Sign magnitude multiplication. Z_un(N+M-3 downto 0) <= X_un(N-2 downto 0) * Y_un(M-2 downto 0); Z_un(N+M-2) <= '0'; Z_un(N+M-1) <= X_un(N-1) xor Y_un(M-1); ELSIF (MODE="10" or MODE="11") THEN -- 1s/2s complement multiplication. t_X := X_un; t_Y := Y_un; sign_X := X_un(N-1); sign_Y := Y_un(M-1); sign_Z := sign_X xor sign_Y; IF (sign_X='1') THEN t_X(N-2 downto 0) := not t_X(N-2 downto 0); IF (MODE="11") THEN t_X(N-2 downto 0) := t_X(N-2 downto 0) + "1"; END IF; END IF; IF (sign_Y='1') THEN t_Y(M-2 downto 0) := not t_Y(M-2 downto 0); IF (MODE="11") THEN t_Y(M-2 downto 0) := t_Y(M-2 downto 0) + "1"; END IF; END IF; t_Z(N+M-3 downto 0) := t_X(N-2 downto 0) * t_Y(M-2 downto 0); IF (sign_Z='1') THEN t_Z(N+M-3 downto 0) := not t_Z(N+M-3 downto 0); IF (MODE="11") THEN t_Z(M+N-3 downto 0) := t_Z(N+M-3 downto 0) + "1"; END IF; END IF; t_Z(N+M-2) := sign_Z; t_Z(N+M-1) := sign_Z; Z_un <= t_Z; END IF; END PROCESS Multiplier; Z <= to_stdulogicvector(conv_integer(Z_un),N+M); END behav; ===== Testbench ===== -- ############################################################################### -- # Project : Leonardo CBT-Kernel # -- # # -- # Filename : test_universal_multiplier.vhd # -- # # -- # Component : test_univ_multiplier : Test bench for Universal multiplier of # -- # NxM bits. # -- # According to MODE operand one of the following multiplications # -- # are performed : # -- # MODE="00" : unsigned multiplication. # -- # MODE="01" : sign magnitude multiplication. # -- # MODE="10" : 1s complement multiplication. # -- # MODE="11" : 2s complement multiplication. # -- # # -- # GENERICS : # -- # N : # of bits of X operand (multiplicand). # -- # M : # of bits of Y operand (multiplier). # -- # For better synthesis results , M must be less or equal to N. # -- # # -- # Model : rtl # -- # # -- # Designer : S. Theoharis # -- # Institute : VLSI Design Lab., University of Patras # -- # Date : 01.05.1999 # -- ############################################################################### ------------------------- -- Library declaration -- ------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; ------------------------ -- Entity declaration -- ------------------------ ENTITY test_universal_multiplier IS END test_universal_multiplier; ------------------------------ -- Architecture declaration -- ------------------------------ ARCHITECTURE behav OF test_universal_multiplier IS --------------------------- -- Component declaration -- --------------------------- COMPONENT universal_multiplier IS GENERIC ( N : integer:= 4; -- # bits of X opernand. M : integer:= 4 -- # bits of Y opernand. ); PORT ( X : IN std_ulogic_vector(N-1 downto 0); Y : IN std_ulogic_vector(M-1 downto 0); MODE : IN std_ulogic_vector(1 downto 0); Z : OUT std_ulogic_vector(N+M-1 downto 0) ); END COMPONENT; -- UNSIGNED="00" , SIGN_MAGNITUDE="01" , 1s COMPLEMENT="10" , 2s COMPLEMENT="11" constant X_WIDTH : integer := 4; constant Y_WIDTH : integer := 4; ------------------------ -- Signal declaration -- ------------------------ SIGNAL X : std_ulogic_vector(X_WIDTH-1 downto 0) := (OTHERS=>'0'); SIGNAL Y : std_ulogic_vector(Y_WIDTH-1 downto 0) := (OTHERS=>'0'); SIGNAL MODE : std_ulogic_vector(1 downto 0); SIGNAL Z : std_ulogic_vector(X_WIDTH+Y_WIDTH-1 downto 0) := (OTHERS=>'0'); SIGNAL X_int,Y_int,Z_int : integer := 0; signal reset : std_ulogic := '1'; signal clk : std_ulogic := '0'; BEGIN ----------------------- -- Increment Process -- ----------------------- reset <= '1', '0' after 80 ns; PROCESS(clk) BEGIN clk <= '1' xor clk after 50 ns; END PROCESS; PROCESS(clk,reset) BEGIN IF (reset='1') THEN X_int <= 0; Y_int <= 0; ELSIF (rising_edge(clk)) THEN IF (Y_int=2**Y_WIDTH-1) THEN Y_int <= 0; X_int <= X_int + 1; ELSE Y_int <= Y_int + 1; END IF; END IF; END PROCESS; Z_int <= X_int * Y_int; ------------------------------ -- Component instantiation. -- ------------------------------ X <= to_stdulogicvector(X_int,X_WIDTH); Y <= to_stdulogicvector(Y_int,Y_WIDTH); u1 : universal_multiplier GENERIC MAP ( N=>X_WIDTH, M=>Y_WIDTH ) PORT MAP ( X=>X, Y=>Y, MODE=>MODE, Z=>Z); MODE <= "01"; -------------------- -- Check results. -- -------------------- PROCESS(clk) BEGIN IF (rising_edge(clk)) THEN -- Unsigned multiplication. IF (MODE="00") THEN ASSERT (Z=to_stdulogicvector(Z_int,X_WIDTH+Y_WIDTH)) REPORT "Error in multiplication!" SEVERITY FAILURE; END IF; -- Check if X,Y have taken all the values. ASSERT (X_int/=2**X_WIDTH-1 OR Y_int/=2**Y_WIDTH-1) REPORT "Simulation is finished succesfully!" SEVERITY FAILURE; END IF; END PROCESS; END behav;