LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE work.mips_types.all; ENTITY e_mips_mul IS PORT ( rst: IN std_logic; clk: IN std_logic; i_a: IN std_logic_vector(31 DOWNTO 0); i_b: IN std_logic_vector(31 DOWNTO 0); i_signed: IN std_logic; i_start: IN std_logic; o_busy: OUT std_logic; o_res: OUT std_logic_vector(63 DOWNTO 0) ); END ENTITY e_mips_mul; ARCHITECTURE a_mips_mul OF e_mips_mul IS TYPE t_state IS (idle, mul1, add1, mul2, add2, mul3, add3, mul4, add4, post); SIGNAL n_state: t_state; SIGNAL r_state: t_state; SIGNAL n_a: unsigned(31 DOWNTO 0); SIGNAL n_b: unsigned(31 DOWNTO 0); SIGNAL n_neg: boolean; SIGNAL n_r: unsigned(31 DOWNTO 0); SIGNAL n_res: unsigned(63 DOWNTO 0); SIGNAL r_a: unsigned(31 DOWNTO 0); SIGNAL r_b: unsigned(31 DOWNTO 0); SIGNAL r_neg: boolean; SIGNAL r_r: unsigned(31 DOWNTO 0); SIGNAL r_res: unsigned(63 DOWNTO 0); BEGIN p_mul: PROCESS(r_state, r_a, r_b, r_neg, r_r, r_res, i_a, i_b, i_signed, i_start) VARIABLE v_a: unsigned(15 DOWNTO 0); VARIABLE v_b: unsigned(15 DOWNTO 0); VARIABLE v_res: unsigned(31 DOWNTO 0); VARIABLE v_add: unsigned(63 DOWNTO 0); VARIABLE v_sum: unsigned(63 DOWNTO 0); BEGIN o_busy <= '0'; n_state <= idle; n_a <= r_a; n_b <= r_b; n_neg <= r_neg; n_res <= r_res; v_a := (OTHERS => '0'); v_b := (OTHERS => '0'); v_add := (OTHERS => '0'); CASE r_state IS WHEN idle => IF i_start = '1' THEN o_busy <= '1'; n_state <= mul1; IF i_signed = '1' THEN IF i_a(31) = '1' THEN n_a <= unsigned(-signed(i_a)); ELSE n_a <= unsigned(i_a); END IF; IF i_b(31) = '1' THEN n_b <= unsigned(-signed(i_b)); ELSE n_b <= unsigned(i_b); END IF; n_neg <= i_a(31) = '1' XOR i_b(31) = '1'; ELSE n_a <= unsigned(i_a); n_b <= unsigned(i_b); n_neg <= false; END IF; END IF; WHEN mul1 => o_busy <= '1'; n_state <= add1; v_a := r_a(15 DOWNTO 0); v_b := r_b(15 DOWNTO 0); WHEN add1 => o_busy <= '1'; n_state <= mul2; v_add := X"00000000" & r_r; WHEN mul2 => o_busy <= '1'; n_state <= add2; v_a := r_a(31 DOWNTO 16); v_b := r_b(15 DOWNTO 0); WHEN add2 => o_busy <= '1'; n_state <= mul3; v_add := X"0000" & r_r & X"0000"; WHEN mul3 => o_busy <= '1'; n_state <= add3; v_a := r_a(15 DOWNTO 0); v_b := r_b(31 DOWNTO 16); WHEN add3 => o_busy <= '1'; n_state <= mul4; v_add := X"0000" & r_r & X"0000"; WHEN mul4 => o_busy <= '1'; n_state <= add4; v_a := r_a(31 DOWNTO 16); v_b := r_b(31 DOWNTO 16); WHEN add4 => o_busy <= '1'; n_state <= post; v_add := r_r & X"00000000"; WHEN OTHERS => NULL; END CASE; n_r <= v_a * v_b; v_sum := r_res + v_add; CASE r_state IS WHEN idle => n_res <= (OTHERS => '0'); WHEN add1 | add2 | add3 | add4 => n_res <= v_sum; WHEN post => IF r_neg THEN n_res <= unsigned(-signed(r_res)); ELSE n_res <= r_res; END IF; WHEN OTHERS => NULL; END CASE; END PROCESS p_mul; p_sync: PROCESS(rst, clk) BEGIN IF rst = '1' THEN r_state <= idle; r_a <= (OTHERS => '0'); r_b <= (OTHERS => '0'); r_neg <= false; r_r <= (OTHERS => '0'); r_res <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN r_state <= n_state; r_a <= n_a; r_b <= n_b; r_neg <= n_neg; r_r <= n_r; r_res <= n_res; END IF; END PROCESS p_sync; o_res <= std_logic_vector(n_res); END ARCHITECTURE a_mips_mul;