--USE work.bv_arithmetic.all; --USE std.textio.all; ENTITY mult_test IS END mult_test; ARCHITECTURE rtl OF mult_test IS CONSTANT word_size : natural := 32; SUBTYPE word IS bit_vector(word_size-1 downto 0); SIGNAL clk : bit; SIGNAL load : bit; SIGNAL multiplicand : word; SIGNAL multiply_by : word; SIGNAL ready : bit; SIGNAL product_low : word; SIGNAL product_high : word; SIGNAL b : word; SIGNAL b_or_0 : word; SIGNAL partial_product : word; SIGNAL c_in : bit; SIGNAL c_out : bit; SIGNAL c_to_p : bit; SIGNAL p_to_a : bit; SIGNAL p_and_c_load : bit; SIGNAL shift : bit; SIGNAL tied_0 : bit := '0'; ALIAS a_0 : bit IS product_low(0); BEGIN -- bench --UUT : multiplier -- port map ( clk, load, multiplicand, multiply_by, -- ready, product_low, product_high); ---------------------------------------------------------------- --a_reg : shift_reg_word -- port map ( clk => clk, -- load => load, -- shift => shift, -- clr => tied_0, -- d => multiplicand, -- d_s => p_to_a, -- q => product_low, -- q_s => open ); a_reg : PROCESS (clk) CONSTANT Tpd_clk_q_clr : Time := 4 ns; CONSTANT Tpd_clk_q_load : Time := 5 ns; CONSTANT Tpd_clk_q_shift : Time := 6 ns; VARIABLE reg_value : word; BEGIN -- PROCESS a_reg IF (clk = '1') THEN IF (tied_0 = '1') THEN reg_value := word'(others => '0'); product_low <= reg_value after Tpd_clk_q_clr; --q_s <= reg_value(0) after Tpd_Clk_Q_clr; ELSIF (load = '1') THEN reg_value := multiplicand; product_low <= reg_value after Tpd_clk_q_load; --q_s <= reg_value(0) after Tpd_Clk_Q_Load; ELSIF (shift = '1') THEN FOR i IN 1 TO word_size-1 LOOP reg_value(i-1) := reg_value(i); END LOOP; -- i reg_value(word_size-1) := p_to_a; product_low <= reg_value after Tpd_clk_q_shift; --q_s <= reg_value(0) after Tpd_Clk_Q_shift; END IF; END IF; END PROCESS a_reg; ---------------------------------------------------------------- --b_reg : reg_word -- port map ( clk => clk, -- load => load, -- d => multiply_by, -- q => b ); b_reg : PROCESS (clk) CONSTANT Tpd_clk_q : Time := 4 ns; BEGIN -- PROCESS b_reg IF (clk = '1' AND load = '1') THEN b <= multiply_by after Tpd_clk_q; END IF; END PROCESS b_reg; ---------------------------------------------------------------- --p_reg : shift_reg_word -- port map ( clk => clk, -- load => p_and_c_load, -- shift => shift, -- clr => load, -- d => partial_product, -- d_s => c_in, -- q => product_high, -- q_s => p_to_a ); p_reg : PROCESS (clk) CONSTANT Tpd_clk_q_clr : Time := 4 ns; CONSTANT Tpd_clk_q_load : Time := 5 ns; CONSTANT Tpd_clk_q_shift : Time := 6 ns; VARIABLE reg_value : word; Begin -- PROCESS p_reg IF (clk = '1') THEN IF (load = '1') THEN reg_value := word'(others => '0'); product_high <= reg_value after Tpd_clk_q_clr; p_to_a <= reg_value(0) after Tpd_Clk_Q_clr; ELSIF (p_and_c_load = '1') THEN reg_value := partial_product; product_high <= reg_value after Tpd_clk_q_load; p_to_a <= reg_value(0) after Tpd_Clk_Q_Load; ELSIF (shift = '1') THEN FOR i IN 1 TO word_size-1 LOOP reg_value(i-1) := reg_value(i); END LOOP; -- i reg_value(word_size-1) := c_in; product_high <= reg_value after Tpd_clk_q_shift; p_to_a <= reg_value(0) after Tpd_Clk_Q_shift; END IF; END IF; END PROCESS p_reg; ---------------------------------------------------------------- --carry_reg : reg_1 -- port map (clk => clk, -- load => p_and_c_load, -- d => c_out, -- q => c_in ); carry_reg : PROCESS (clk) CONSTANT Tpd_clk_q : Time := 4 ns; BEGIN -- PROCESS carry_reg IF (clk = '1' AND p_and_c_load = '1') THEN c_in <= c_out after Tpd_clk_q; END IF; END PROCESS carry_reg; ---------------------------------------------------------------- --b_gate : and_word -- port map ( a => a_0, -- b => b, -- z => b_or_0 ); b_gate: b_or_0 <= b WHEN a_0 = '1' ELSE word'(others => '0'); ---------------------------------------------------------------- --the_adder : adder -- port map ( a => product_high, -- b => b_or_0, -- c_in => c_in, -- s => partial_product, -- c_out => c_out ); the_adder : PROCESS (product_high, b_or_0, c_in) CONSTANT Tpd : Time := 8 ns; VARIABLE c : bit; VARIABLE sum : word; BEGIN -- PROCESS the_adder c := c_in; FOR i IN 0 to word_size-1 LOOP sum(i) := (product_high(i) XOR b_or_0(i)) XOR c; c := (product_high(i) AND b_or_0(i)) OR ((product_high(i) XOR b_or_0(i)) AND c); END LOOP; partial_product <= sum after Tpd; c_out <= c after Tpd; END PROCESS the_adder; ---------------------------------------------------------------- ----------------------------------------------------------------------------- -- Process: controller -- Purpose: sequences register loading and shifting -- Inputs: clk, load -- Outputs: p_and_c_load, shift, ready ----------------------------------------------------------------------------- controller : PROCESS CONSTANT Tpd_clk_load : Time := 5 ns; CONSTANT Tpd_clk_shift : Time := 5 ns; CONSTANT Tpd_clk_ready : Time := 5 ns; BEGIN -- PROCESS controller p_and_c_load <= '0' after Tpd_Clk_Load; shift <= '0' after Tpd_clk_shift; ready <= '1' after Tpd_clk_ready; WAIT on clk until clk = '1' and load = '1'; ready <= '0' after Tpd_clk_ready; FOR cycle IN 1 to word_size LOOP p_and_c_load <= '1' after Tpd_clk_load; WAIT until clk = '1'; p_and_c_load <= '0' after Tpd_clk_load; shift <= '1' after Tpd_clk_shift; WAIT until clk = '1'; shift <= '0' after Tpd_clk_shift; END LOOP; -- cycle ready <= '1' after Tpd_clk_ready; END PROCESS controller; ---------------------------------------------------------------- clock_gen : PROCESS CONSTANT Tc : Time := 100 ns; BEGIN -- PROCESS clock_gen FOR i IN 1 to 500 LOOP WAIT for Tc/2; clk <= '1'; WAIT for Tc - Tc/2; clk <= '0'; END LOOP; -- i wait; END PROCESS clock_gen; tester : PROCESS --VARIABLE L : line; PROCEDURE drive (a, b : word) IS CONSTANT Tdelay : Time := 6 ns; BEGIN multiplicand <= a after Tdelay; multiply_by <= b after Tdelay; load <= '1' after Tdelay; WAIT until clk = '1'; load <= '0' after Tdelay; WAIT on clk until clk = '1' and ready = '1'; END drive; BEGIN -- PROCESS tester drive(X"0000_0000", X"0000_0002"); --write(L, string'("tester: X""0"" x X""2"" -> ")); --write_hex(L, product_high); --write(L, ' '); --write_hex(L, product_low); --writeline(output, L); -- drive(X"0000_0002", X"0000_0002"); --write(L, string'("tester: X""2"" x X""2"" -> ")); --write_hex(L, product_high); --write(L, ' '); --write_hex(L, product_low); --writeline(output, L); -- drive(x"A5A5_A5A5", x"5A5A_5A5A"); --write(L, string'("tester: x""A5A5_A5A5"" x x""5A5A_5A5A"" -> ")); --write_hex(L, product_high); --write(L, ' '); --write_hex(L, product_low); --writeline(output, L); -- drive(X"FFFF_FFFF", X"FFFF_FFFF"); --write(L, string'("tester: X""FFFF_FFFF"" x X""FFFF_FFFF"" -> ")); --write_hex(L, product_high); --write(L, ' '); --write_hex(L, product_low); --writeline(output, L); -- wait; END PROCESS tester; END rtl;