-- ======================================================================= -- Author: Antonio Esteves, GEC-DI-UM. -- File: mult8x8.vhd -- Date: 13 August 2000 -- -- Parallel, or optimized for speed, aw-bit x bw-bit signed multiplier. -- Targeted into XC4xxx family. Inputs and output are registered. -- -- FOR FASTER PRODUCT COMPUTATION USE AS OPERAND 'b' THE NUMBER WITH -- LESS BITS. -- -- Functionality: -- prod[aw+bw-1:0] = a[aw-1:0] * b[bw-1:0] -- -- NOTE : THIS IS A NON-PIPELINED VERSION, THAT COMPUTES A PRODUCT EACH -- TIME DATA CHANGES. RESULT IS ONLY ALTERED ON A CLOCK TRANSITION -- WHEN CLOCK ENABLE IS HIGH ('1'). -- ======================================================================= library IEEE; use IEEE.STD_LOGIC_1164.all; library WORK; use WORK.functions_util.all; entity signed_mult is generic ( aw: NATURAL; bw: NATURAL ); port ( -- product operand 1: (aw-1 downto 0) a : in std_logic_vector(aw-1 downto 0); -- product operand 2: (bw-1 downto 0) b : in std_logic_vector(bw-1 downto 0); c : in std_logic; -- clock of product register ce : in std_logic; -- clock enable of product register reset : in std_logic; -- reset of product register -- product (stored on a register): (aw+bw-1 downto 0) prod : out std_logic_vector(aw+bw-1 downto 0) ); end signed_mult; architecture behav of signed_mult is constant signed : boolean := true; signal vprod : std_logic_vector( aw+bw - 1 downto 0 ); begin process(a,b) variable va : std_logic_vector( aw-1 downto 0 ); variable vb : std_logic_vector( bw-1 downto 0 ); variable cin : std_logic; variable value : std_logic; variable negative : boolean; variable i,j : integer; variable index : integer; variable vprod_value : std_logic_vector( aw+bw-1 downto 0 ); begin negative := FALSE; va := a; vb := b; if (signed) then -- inputs are signed values if ( (va(aw-1) xor vb(bw-1)) = '1' ) then -- result is negative negative := TRUE; end if ; if (va(aw-1) = '1') then -- 'a' is negative va := two_comp(va); end if ; if (vb(bw-1) = '1') then -- 'b' is negative vb := two_comp(vb); end if ; end if; -- end of signed alternative for j in 0 to aw+bw-1 loop -- initialize product to zero vprod_value(j) := '0'; end loop; for i in 0 to bw -1 loop -- use 'b' width (bw) to control loop if (vb(i) = '1') then index := i; cin := '0'; for j in 0 to aw-1 loop -- add 'a' to 'prod' bit-by-bit value := vprod_value(index) xor va(j) xor cin; -- 1-bit sum cin := (vprod_value(index) and va(j)) or (vprod_value(index) and cin) or (va(j) and cin); -- 1-bit carry vprod_value(index) := value; index := index + 1; end loop; vprod_value(index) := vprod_value(index) xor cin; -- last carry else cin := '0'; end if; end loop; -- convert product to twos complement when it is negative if (negative) then vprod_value := two_comp(vprod_value); end if; vprod <= vprod_value; end process; process (c, reset) begin if (reset = '1') then for j in 0 to aw+bw-1 loop -- initialize register product to zero prod(j) <= '0'; end loop; elsif (c'event and c='1') then -- store product if (ce = '1') then prod <= vprod; end if; end if; end process; end behav;