3b0e875c796b491470b56f1249893dc686d6d73b
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 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;
Stefan Schuermans add initial values for regi...

Stefan Schuermans authored 12 years ago

24)     SIGNAL r_state: t_state := 0;
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 years ago

25) 
26)     SIGNAL n_num:   signed(63 DOWNTO 0);
27)     SIGNAL n_denom: signed(63 DOWNTO 0);
28)     SIGNAL n_neg:   boolean;
29)     SIGNAL n_res:   signed(31 DOWNTO 0);
Stefan Schuermans add initial values for regi...

Stefan Schuermans authored 12 years ago

30)     SIGNAL r_num:   signed(63 DOWNTO 0) := (OTHERS => '0');
31)     SIGNAL r_denom: signed(63 DOWNTO 0) := (OTHERS => '0');
32)     SIGNAL r_neg:   boolean             := false;
33)     SIGNAL r_res:   signed(31 DOWNTO 0) := (OTHERS => '0');
34)     SIGNAL s_rem:   signed(31 DOWNTO 0) := (OTHERS => '0');
Stefan Schuermans implemented divider

Stefan Schuermans authored 12 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;
Stefan Schuermans fix divider (result)

Stefan Schuermans authored 12 years ago

95)                     n_res <= r_res(30 DOWNTO 0) & "0";