------------------------------------- -- Defines data path width -- ------------------------------------- package mypackage is constant NBITS :INTEGER := 6; constant MBITS :INTEGER := 5; end mypackage; --------------------------------------------------------- -- Basic signed shif & add base 2 multiplier -- Iterative implementation -- ---------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use work.mypackage.all; entity signed_mult_seq is port ( clk: in std_logic; ini: in std_logic; X: in std_logic_vector(NBITS-1 downto 0); Y: in std_logic_vector(MBITS-1 downto 0); done: out std_logic; P: out std_logic_vector(NBITS+MBITS-1 downto 0) ); end signed_mult_seq; architecture simple_seq_arch of signed_mult_seq is component mult_by_1_bit is port ( A: in std_logic_vector(MBITS-1 downto 0); B: in std_logic_vector(MBITS-1 downto 0); op : in std_logic; --(add/sub) or nothing a_s: in std_logic; --add or subtract P: out std_logic_vector(MBITS downto 0) ); end component; signal Reg_X: std_logic_vector(NBITS-1 downto 0); signal Reg_Y, Reg_P: std_logic_vector(MBITS-1 downto 0); signal n_Reg_P: std_logic_vector(MBITS downto 0); signal counter: integer range 0 to NBITS+1; signal work, add_sub: STD_LOGIC; begin state_mach: process (CLK, work, ini) begin if CLK'event and CLK='0' then if ini='1' then work <= '1'; Reg_P <= (others => '0'); counter <= 0; Reg_X <= X; Reg_Y <= Y; add_sub <= '0'; elsif work = '1' then counter <= counter+1; Reg_P <= n_Reg_P(MBITS downto 1); Reg_X <= n_Reg_P(0) & Reg_X(NBITS-1 downto 1); if (counter = NBITS-2) then add_sub <= '1'; end if; if (counter = NBITS-1) then P <= n_Reg_P & Reg_X(NBITS-1 downto 1); work <= '0'; end if; end if; end if; end process; done <= not work; mult: mult_by_1_bit port map (A => Reg_P, B => Reg_Y, op => REG_X(0), a_s => add_sub, P => n_Reg_P ); end simple_seq_arch; ---------------------------------------------------- -- Mult_by_1_bit: Calcutate P <= A + (-1*a_s)*(op*B) -- The Result P has one digit more; therefore the sign bit -- is concatenated at the MSB position of each operand ---------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.mypackage.all; entity mult_by_1_bit is Port ( A: in std_logic_vector(MBITS-1 downto 0); B: in std_logic_vector(MBITS-1 downto 0); op : in std_logic; --(add/sub)=1 or nothing a_s: in std_logic; --add or subtract P: out std_logic_vector(MBITS downto 0) ); end mult_by_1_bit; architecture Behavioral of mult_by_1_bit is begin process(B,A, op, a_s) begin if op = '1' then if a_s = '0' then P <= (A(MBITS-1) & A) + (B(MBITS-1) & B); else P <= (A(MBITS-1) & A) - (B(MBITS-1) & B); end if; else P <= (A(MBITS-1) & A); end if; end process; end Behavioral; ---------------------------------------------------------------------- -- VHDL Test Bench for signed_mult_seq -- -- Notes: ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_signed.all; USE work.mypackage.all; LIBRARY ieee; USE IEEE.STD_LOGIC_TEXTIO.ALL; USE STD.TEXTIO.ALL; ENTITY test_exhaustive IS END test_exhaustive; ARCHITECTURE behavioural OF test_exhaustive IS constant DELAY: time := 100 ns; FILE RESULTS: TEXT OPEN WRITE_MODE IS "results.txt"; COMPONENT signed_mult_seq PORT( clk: in std_logic; ini: in std_logic; X: in std_logic_vector(NBITS-1 downto 0); Y: in std_logic_vector(MBITS-1 downto 0); done: out std_logic; P: out std_logic_vector(NBITS+MBITS-1 downto 0) ); END COMPONENT; SIGNAL x : std_logic_vector(NBITS-1 downto 0); SIGNAL y : std_logic_vector(MBITS-1 downto 0); SIGNAL p : std_logic_vector(NBITS+MBITS-1 downto 0); SIGNAL clk, ini, done: std_logic; BEGIN uut: signed_mult_seq PORT MAP(clk => clk, ini => ini, X => x, Y => y, done => done, P => p); PROCESS -- clock process for clk, BEGIN clk <= '0'; WAIT FOR 10 ns; CLOCK_LOOP : LOOP clk <= '1'; WAIT FOR DELAY/2; clk <= '0'; WAIT FOR DELAY/2; END LOOP CLOCK_LOOP; END PROCESS; tb_test : PROCESS VARIABLE TX_LOC : LINE; VARIABLE TX_STR : String(1 to 4096); VARIABLE iP : integer; BEGIN for i in -2**(NBITS-1) to 2**(NBITS-1)-1 loop for j in -2**(MBITS-1) to 2**(MBITS-1)-1 loop x <= conv_std_logic_vector(i,NBITS); y <= conv_std_logic_vector(j,MBITS); ini <= '1'; WAIT FOR DELAY; ini <= '0'; WAIT FOR (NBITS)*DELAY; iP := conv_integer(P); IF ( I*J /= iP) THEN write(TX_LOC,string'("ERROR!!! X=")); write(TX_LOC, i); write(TX_LOC,string'(" Y=")); write(TX_LOC, j); write(TX_LOC,string'(" P=")); write(TX_LOC, iP); write(TX_LOC, string'(" ")); TX_STR(TX_LOC.all'range) := TX_LOC.all; writeline(results, TX_LOC); Deallocate(TX_LOC); ASSERT (FALSE) REPORT TX_STR SEVERITY ERROR; END IF; end loop; end loop; ASSERT (FALSE) REPORT "Simulation successful (not a failure). No problems detected. " SEVERITY FAILURE; END PROCESS; END;