-- save this file as mult_package.vhd ---------------------------------------------------------------------------- -- -- Copyright (c) 1998 by Synopsys, Inc. All rights reserved. -- -- This source file may be used and distributed without restriction -- provided that this copyright statement is not removed from the file -- and that any derivative work contains this copyright notice. -- -- Package name: my_arith -- -- Purpose: This package defines a more efficient implementation -- for the multiplication operator. This is a general -- unsigned multiplier. -- -- Author: Ramine Roane (rroane@synopsys.com) -- -- Algorithm: -- loop: Pi = (Yi==1) ? Xi : 0 -- loop: Qi = P(2i) + P(2i+1)<<1 -- loop: Ri = Q(2i) + Q(2i+1)<<2 -- If T'length > 7 -- loop: Ti = R(2i) + R(2i+1)<<4 -- loop: Q += Ti<<(8i) -- else -- loop: Q += Ri<<(4i) -- end if -- -- Notes: Partial products Qi's ccomputed in parallel -- Partial products Ri's ccomputed in parallel -- Partial products Ti's (if apply) ccomputed in parallel -- -- Modified by Kamesh Ramani. ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; entity Multiplier is generic (lS: integer := 16; lL: integer := 16); port (S: in std_logic_vector(lS-1 downto 0); L: in std_logic_vector(lL-1 downto 0); Prod: out std_logic_vector((lS+lL+4- 1) downto 0) ); end Multiplier; architecture Multiplier_arch of Multiplier is -- Number of intermediate products P, Q, R constant nP : integer := lS; --16 constant nQ : integer := (nP+1)/2; --8 constant nR : integer := (nQ+1)/2; --4 constant nT : integer := (nR+1)/2; --2 -- Length of P, Q, R, and final result constant lP : integer := lL ; --16 constant lQ : integer := lP+2 ; --18 constant lR : integer := lQ+3 ; --21 constant lT : integer := lR+5 ; --26 constant n : integer := lS+lP ; --32 type Pi_type is array(nP-1 downto 0) of std_logic_vector(lP-1 downto 0); type Qi_type is array(nQ-1 downto 0) of std_logic_vector(lQ-1 downto 0); type Ri_type is array(nR-1 downto 0) of std_logic_vector(lR-1 downto 0); type Ti_type is array(nT-1 downto 0) of std_logic_vector(lT-1 downto 0); begin process(S, L) variable P : Pi_type; variable Q, Q_1, Q_2 : Qi_type; variable R : Ri_type; variable T : Ti_type; variable result, result1: std_logic_vector(31 downto 0); --n-1 downto 0); variable Small : std_logic_vector(15 downto 0); --(ls-1 downto 0); variable Large : std_logic_vector(15 downto 0); --(Ll-1 downto 0); begin if (S'length < L'length) then Small := S; Large := L; else Small := L; Large := S; end if; -- Compute Pi's for i in 0 to nP-1 loop if (Small(i) = '0') then P(i) := "0000000000000000"; else P(i) := Large; end if; end loop; -- Compute Qi's for i in 0 to nP/2-1 loop Q(i):= (("00" & (P(2*i)(16-1 downto 1))) + ('0' & P(2*i+1))) & P(2*i)(0); end loop; if (nP mod 2) = 1 then Q(8-1) := "00" & P(16-1); end if; -- Compute Ri's for i in 0 to nQ/2-1 loop R(i):= (("000" & (Q(2*i)(18-1 downto 2))) + ('0' & Q(2*i+1))) & Q(2*i)(1 downto 0); end loop; if (nQ mod 2) = 1 then R(4-1) := "000" & Q(8-1); ---check this out end if; if (lS >= 8) then -- Compute Ti's for i in 0 to nR/2-1 loop T(i) := (("00000" & R(2*i)(20 downto 4)) + ('0' & R(2*i+1))) & R(2*i)(3 downto 0); end loop; if (nR mod 2) = 1 then T(2-1) := "00000" & R(4-1); end if; -- Compute final product result := "000000" & T(0); for i in 1 to nT-1 loop -- skip i=0 result := result + (T(i)(23 downto 0) & "00000000"); end loop; else -- Compute final product result := "00000000000" & R(0); for i in 1 to nR-1 loop -- skip i=0 result1 := ("0000000" & R(i) & "0000"); case i is when 1 => result1 := ("0000000" & R(i) & "0000"); when 2 => result1 := ("000" & R(i) & "00000000"); when 3 => result1 := (R(i)(19 downto 0) & "000000000000"); when others => result1 := result; end case; result := result + result1; end loop; end if; prod <= "0000" & result; end process; end Multiplier_arch;