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