LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE work.mips_types.all; ENTITY e_mips_div IS PORT ( rst: IN std_logic; clk: IN std_logic; i_num: IN std_logic_vector(31 DOWNTO 0); i_denom: 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(31 DOWNTO 0); o_rem: OUT std_logic_vector(31 DOWNTO 0) ); END ENTITY e_mips_div; ARCHITECTURE a_mips_div OF e_mips_div IS SUBTYPE t_state IS natural RANGE 0 TO 33; SIGNAL n_state: t_state; SIGNAL r_state: t_state := 0; SIGNAL n_num: signed(63 DOWNTO 0); SIGNAL n_denom: signed(63 DOWNTO 0); SIGNAL n_neg: boolean; SIGNAL n_res: signed(31 DOWNTO 0); SIGNAL r_num: signed(63 DOWNTO 0) := (OTHERS => '0'); SIGNAL r_denom: signed(63 DOWNTO 0) := (OTHERS => '0'); SIGNAL r_neg: boolean := false; SIGNAL r_res: signed(31 DOWNTO 0) := (OTHERS => '0'); SIGNAL s_rem: signed(31 DOWNTO 0) := (OTHERS => '0'); BEGIN p_div: PROCESS(r_state, r_num, r_denom, r_neg, r_res, i_num, i_denom, i_signed, i_start) VARIABLE v_num: signed(31 DOWNTO 0); VARIABLE v_denom: signed(31 DOWNTO 0); VARIABLE v_diff: signed(63 DOWNTO 0); BEGIN o_busy <= '0'; n_state <= r_state; n_num <= r_num; n_denom <= r_denom; n_neg <= r_neg; n_res <= r_res; s_rem <= (OTHERS => '0'); CASE r_state IS WHEN 0 => IF i_start = '1' THEN o_busy <= '1'; n_state <= 1; IF i_signed = '1' THEN IF i_num(31) = '1' THEN v_num := -signed(i_num); ELSE v_num := signed(i_num); END IF; IF i_denom(31) = '1' THEN v_denom := -signed(i_denom); ELSE v_denom := signed(i_denom); END IF; n_neg <= i_num(31) = '1' XOR i_denom(31) = '1'; ELSE v_num := signed(i_num); v_denom := signed(i_denom); n_neg <= false; END IF; n_num <= X"00000000" & v_num; n_denom <= "0" & v_denom & X"0000000" & "000"; END IF; WHEN 33 => o_busy <= '0'; n_state <= 0; IF r_neg THEN n_res <= -r_res; s_rem <= -n_num(31 DOWNTO 0); ELSE n_res <= r_res; s_rem <= n_num(31 DOWNTO 0); END IF; WHEN OTHERS => o_busy <= '1'; n_state <= r_state + 1; v_diff := r_num - r_denom; IF (v_diff(63) = '0') THEN n_num <= v_diff; n_res <= r_res(30 DOWNTO 0) & "1"; ELSE n_num <= r_num; n_res <= r_res(30 DOWNTO 0) & "1"; END IF; n_denom <= "0" & r_denom(63 DOWNTO 1); END CASE; END PROCESS p_div; p_sync: PROCESS(rst, clk) BEGIN IF rst = '1' THEN r_state <= 0; r_num <= (OTHERS => '0'); r_denom <= (OTHERS => '0'); r_neg <= false; r_res <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN r_state <= n_state; r_num <= n_num; r_denom <= n_denom; r_neg <= n_neg; r_res <= n_res; END IF; END PROCESS p_sync; o_res <= std_logic_vector(n_res); o_rem <= std_logic_vector(s_rem); END ARCHITECTURE a_mips_div;