implemented divider
Stefan Schuermans

Stefan Schuermans commited on 2012-02-05 20:59:58
Showing 3 changed files, with 171 additions and 6 deletions.

... ...
@@ -96,6 +96,12 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
96 96
     SIGNAL s_mul_busy:   std_logic;
97 97
     SIGNAL s_mul_res:    std_logic_vector(63 DOWNTO 0);
98 98
 
99
+    SIGNAL s_div_signed: std_logic;
100
+    SIGNAL s_div_start:  std_logic;
101
+    SIGNAL s_div_busy:   std_logic;
102
+    SIGNAL s_div_res:    std_logic_vector(31 DOWNTO 0);
103
+    SIGNAL s_div_rem:    std_logic_vector(31 DOWNTO 0);
104
+
99 105
     COMPONENT e_mips_decoder IS
100 106
         PORT (
101 107
             i_instr:  IN  std_logic_vector(31 DOWNTO 0);
... ...
@@ -159,9 +165,23 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
159 165
         );
160 166
     END COMPONENT e_mips_mul;
161 167
 
168
+    COMPONENT e_mips_div IS
169
+        PORT (
170
+            rst:      IN  std_logic;
171
+            clk:      IN  std_logic;
172
+            i_num:    IN  std_logic_vector(31 DOWNTO 0);
173
+            i_denom:  IN  std_logic_vector(31 DOWNTO 0);
174
+            i_signed: IN  std_logic;
175
+            i_start:  IN  std_logic;
176
+            o_busy:   OUT std_logic;
177
+            o_res:    OUT std_logic_vector(31 DOWNTO 0);
178
+            o_rem:    OUT std_logic_vector(31 DOWNTO 0)
179
+        );
180
+    END COMPONENT e_mips_div;
181
+
162 182
 BEGIN
163 183
 
164
-    s_stall <= i_stall OR s_stall_data_rd OR s_mul_busy;
184
+    s_stall <= i_stall OR s_stall_data_rd OR s_mul_busy OR s_div_busy;
165 185
 
166 186
     decoder: e_mips_decoder
167 187
         PORT MAP (
... ...
@@ -221,6 +241,19 @@ BEGIN
221 241
             o_res    => s_mul_res
222 242
         );
223 243
 
244
+    div: e_mips_div
245
+        PORT MAP (
246
+            rst      => rst,
247
+            clk      => clk,
248
+            i_num    => s_val_s,
249
+            i_denom  => s_val_t,
250
+            i_signed => s_div_signed,
251
+            i_start  => s_div_start,
252
+            o_busy   => s_div_busy,
253
+            o_res    => s_div_res,
254
+            o_rem    => s_div_rem
255
+        );
256
+
224 257
     p_sync_pc: PROCESS(rst, clk)
225 258
     BEGIN
226 259
         IF rst = '1' THEN
... ...
@@ -534,7 +567,8 @@ BEGIN
534 567
         END IF;
535 568
     END PROCESS p_data_wr;
536 569
 
537
-    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s, s_mul_res)
570
+    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s,
571
+                         s_mul_res, s_div_res, s_div_rem)
538 572
     BEGIN
539 573
         n_reg_lo            <= r_reg_lo;
540 574
         n_reg_hi            <= r_reg_hi;
... ...
@@ -557,6 +591,9 @@ BEGIN
557 591
             WHEN op_mult | op_multu =>
558 592
                 n_reg_lo <= std_logic_vector(s_mul_res(31 DOWNTO  0));
559 593
                 n_reg_hi <= std_logic_vector(s_mul_res(63 DOWNTO 32));
594
+            WHEN op_div | op_divu =>
595
+                n_reg_lo <= s_div_res;
596
+                n_reg_hi <= s_div_rem;
560 597
             WHEN OTHERS => NULL;
561 598
         END CASE;
562 599
     END PROCESS p_reg_hi_lo;
... ...
@@ -577,4 +614,7 @@ BEGIN
577 614
     s_mul_signed <= '1' WHEN r_op = op_mult ELSE '0';
578 615
     s_mul_start  <= '1' WHEN i_stall = '0' AND (r_op = op_mult OR r_op = op_multu) ELSE '0';
579 616
 
617
+    s_div_signed <= '1' WHEN r_op = op_div ELSE '0';
618
+    s_div_start  <= '1' WHEN i_stall = '0' AND (r_op = op_div OR r_op = op_divu) ELSE '0';
619
+
580 620
 END ARCHITECTURE a_mips_core;
... ...
@@ -0,0 +1,121 @@
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;
24
+    SIGNAL r_state: t_state;
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);
30
+    SIGNAL r_num:   signed(63 DOWNTO 0);
31
+    SIGNAL r_denom: signed(63 DOWNTO 0);
32
+    SIGNAL r_neg:   boolean;
33
+    SIGNAL r_res:   signed(31 DOWNTO 0);
34
+    SIGNAL s_rem:   signed(31 DOWNTO 0);
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;
95
+                    n_res <= r_res(30 DOWNTO 0) & "1";
96
+                END IF;
97
+                n_denom <= "0" & r_denom(63 DOWNTO 1);
98
+        END CASE;
99
+    END PROCESS p_div;
100
+
101
+    p_sync: PROCESS(rst, clk)
102
+    BEGIN
103
+        IF rst = '1' THEN
104
+            r_state <= 0;
105
+            r_num   <= (OTHERS => '0');
106
+            r_denom <= (OTHERS => '0');
107
+            r_neg   <= false;
108
+            r_res   <= (OTHERS => '0');
109
+        ELSIF rising_edge(clk) THEN
110
+            r_state <= n_state;
111
+            r_num   <= n_num;
112
+            r_denom <= n_denom;
113
+            r_neg   <= n_neg;
114
+            r_res   <= n_res;
115
+        END IF;
116
+    END PROCESS p_sync;
117
+
118
+    o_res <= std_logic_vector(n_res);
119
+    o_rem <= std_logic_vector(s_rem);
120
+
121
+END ARCHITECTURE a_mips_div;
... ...
@@ -17,7 +17,7 @@
17 17
   <files>
18 18
     <file xil_pn:name="mips/decoder.vhd" xil_pn:type="FILE_VHDL">
19 19
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
20
-      <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
20
+      <association xil_pn:name="Implementation" xil_pn:seqID="6"/>
21 21
     </file>
22 22
     <file xil_pn:name="mips/types.vhd" xil_pn:type="FILE_VHDL">
23 23
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="48"/>
... ...
@@ -25,11 +25,11 @@
25 25
     </file>
26 26
     <file xil_pn:name="mips/alu.vhd" xil_pn:type="FILE_VHDL">
27 27
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="49"/>
28
-      <association xil_pn:name="Implementation" xil_pn:seqID="7"/>
28
+      <association xil_pn:name="Implementation" xil_pn:seqID="8"/>
29 29
     </file>
30 30
     <file xil_pn:name="mips/core.vhd" xil_pn:type="FILE_VHDL">
31 31
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="53"/>
32
-      <association xil_pn:name="Implementation" xil_pn:seqID="8"/>
32
+      <association xil_pn:name="Implementation" xil_pn:seqID="9"/>
33 33
     </file>
34 34
     <file xil_pn:name="constraints/clk.ucf" xil_pn:type="FILE_UCF">
35 35
       <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
... ...
@@ -47,12 +47,16 @@
47 47
     </file>
48 48
     <file xil_pn:name="mips/cmp.vhd" xil_pn:type="FILE_VHDL">
49 49
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="89"/>
50
-      <association xil_pn:name="Implementation" xil_pn:seqID="6"/>
50
+      <association xil_pn:name="Implementation" xil_pn:seqID="7"/>
51 51
     </file>
52 52
     <file xil_pn:name="mips/mul.vhd" xil_pn:type="FILE_VHDL">
53 53
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="93"/>
54 54
       <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
55 55
     </file>
56
+    <file xil_pn:name="mips/div.vhd" xil_pn:type="FILE_VHDL">
57
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="97"/>
58
+      <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
59
+    </file>
56 60
   </files>
57 61
 
58 62
   <properties>
59 63