implemented divider
Stefan Schuermans authored 13 years ago
|
1) LIBRARY ieee;
2) USE ieee.std_logic_1164.all;
3) USE ieee.numeric_std.all;
4) USE work.mips_types.all;
5)
6) ENTITY e_mips_div IS
7) PORT (
8) rst: IN std_logic;
9) clk: IN std_logic;
10) i_num: IN std_logic_vector(31 DOWNTO 0);
11) i_denom: IN std_logic_vector(31 DOWNTO 0);
12) i_signed: IN std_logic;
13) i_start: IN std_logic;
14) o_busy: OUT std_logic;
15) o_res: OUT std_logic_vector(31 DOWNTO 0);
16) o_rem: OUT std_logic_vector(31 DOWNTO 0)
17) );
18) END ENTITY e_mips_div;
19)
20) ARCHITECTURE a_mips_div OF e_mips_div IS
21)
22) SUBTYPE t_state IS natural RANGE 0 TO 33;
23) SIGNAL n_state: t_state;
|
implemented divider
Stefan Schuermans authored 13 years ago
|
35)
36) BEGIN
37)
38) p_div: PROCESS(r_state, r_num, r_denom, r_neg, r_res,
39) i_num, i_denom, i_signed, i_start)
40) VARIABLE v_num: signed(31 DOWNTO 0);
41) VARIABLE v_denom: signed(31 DOWNTO 0);
42) VARIABLE v_diff: signed(63 DOWNTO 0);
43) BEGIN
44) o_busy <= '0';
45) n_state <= r_state;
46) n_num <= r_num;
47) n_denom <= r_denom;
48) n_neg <= r_neg;
49) n_res <= r_res;
50) s_rem <= (OTHERS => '0');
51) CASE r_state IS
52) WHEN 0 =>
53) IF i_start = '1' THEN
54) o_busy <= '1';
55) n_state <= 1;
56) IF i_signed = '1' THEN
57) IF i_num(31) = '1' THEN
58) v_num := -signed(i_num);
59) ELSE
60) v_num := signed(i_num);
61) END IF;
62) IF i_denom(31) = '1' THEN
63) v_denom := -signed(i_denom);
64) ELSE
65) v_denom := signed(i_denom);
66) END IF;
67) n_neg <= i_num(31) = '1' XOR i_denom(31) = '1';
68) ELSE
69) v_num := signed(i_num);
70) v_denom := signed(i_denom);
71) n_neg <= false;
72) END IF;
73) n_num <= X"00000000" & v_num;
74) n_denom <= "0" & v_denom & X"0000000" & "000";
75) END IF;
76) WHEN 33 =>
77) o_busy <= '0';
78) n_state <= 0;
79) IF r_neg THEN
80) n_res <= -r_res;
81) s_rem <= -n_num(31 DOWNTO 0);
82) ELSE
83) n_res <= r_res;
84) s_rem <= n_num(31 DOWNTO 0);
85) END IF;
86) WHEN OTHERS =>
87) o_busy <= '1';
88) n_state <= r_state + 1;
89) v_diff := r_num - r_denom;
90) IF (v_diff(63) = '0') THEN
91) n_num <= v_diff;
92) n_res <= r_res(30 DOWNTO 0) & "1";
93) ELSE
94) n_num <= r_num;
|