moved multiplier to own module
Stefan Schuermans

Stefan Schuermans commited on 2012-02-05 19:14:55
Showing 3 changed files, with 184 additions and 118 deletions.

... ...
@@ -21,7 +21,6 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
21 21
 
22 22
     SIGNAL s_stall:         std_logic;
23 23
     SIGNAL s_stall_data_rd: std_logic;
24
-    SIGNAL s_stall_mul:     std_logic;
25 24
 
26 25
     SIGNAL r_pc: std_logic_vector(31 DOWNTO 0);
27 26
     SIGNAL n_pc: std_logic_vector(31 DOWNTO 0);
... ...
@@ -92,16 +91,10 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
92 91
     SIGNAL r_reg_lo: std_logic_vector(31 DOWNTO 0);
93 92
     SIGNAL r_reg_hi: std_logic_vector(31 DOWNTO 0);
94 93
 
95
-    TYPE t_mul IS (mul_idle, mul_1, mul_2, mul_3, mul_4, mul_post);
96
-    SIGNAL n_mul: t_mul;
97
-    SIGNAL r_mul: t_mul;
98
-
99
-    SIGNAL n_mul_a:   unsigned(31 DOWNTO 0);
100
-    SIGNAL n_mul_b:   unsigned(31 DOWNTO 0);
101
-    SIGNAL n_mul_res: unsigned(63 DOWNTO 0);
102
-    SIGNAL r_mul_a:   unsigned(31 DOWNTO 0);
103
-    SIGNAL r_mul_b:   unsigned(31 DOWNTO 0);
104
-    SIGNAL r_mul_res: unsigned(63 DOWNTO 0);
94
+    SIGNAL s_mul_signed: std_logic;
95
+    SIGNAL s_mul_start:  std_logic;
96
+    SIGNAL s_mul_busy:   std_logic;
97
+    SIGNAL s_mul_res:    std_logic_vector(63 DOWNTO 0);
105 98
 
106 99
     COMPONENT e_mips_decoder IS
107 100
         PORT (
... ...
@@ -153,9 +146,22 @@ ARCHITECTURE a_mips_core OF e_mips_core IS
153 146
         );
154 147
     END COMPONENT e_mips_cmp;
155 148
 
149
+    COMPONENT e_mips_mul IS
150
+        PORT (
151
+            rst:      IN  std_logic;
152
+            clk:      IN  std_logic;
153
+            i_a:      IN  std_logic_vector(31 DOWNTO 0);
154
+            i_b:      IN  std_logic_vector(31 DOWNTO 0);
155
+            i_signed: IN  std_logic;
156
+            i_start:  IN  std_logic;
157
+            o_busy:   OUT std_logic;
158
+            o_res:    OUT std_logic_vector(63 DOWNTO 0)
159
+        );
160
+    END COMPONENT e_mips_mul;
161
+
156 162
 BEGIN
157 163
 
158
-    s_stall <= i_stall OR s_stall_data_rd OR s_stall_mul;
164
+    s_stall <= i_stall OR s_stall_data_rd OR s_mul_busy;
159 165
 
160 166
     decoder: e_mips_decoder
161 167
         PORT MAP (
... ...
@@ -203,6 +209,18 @@ BEGIN
203 209
             o_res => s_cmp_res
204 210
         );
205 211
 
212
+    mul: e_mips_mul
213
+        PORT MAP (
214
+            rst      => rst,
215
+            clk      => clk,
216
+            i_a      => s_val_s,
217
+            i_b      => s_val_t,
218
+            i_signed => s_mul_signed,
219
+            i_start  => s_mul_start,
220
+            o_busy   => s_mul_busy,
221
+            o_res    => s_mul_res
222
+        );
223
+
206 224
     p_sync_pc: PROCESS(rst, clk)
207 225
     BEGIN
208 226
         IF rst = '1' THEN
... ...
@@ -516,7 +534,7 @@ BEGIN
516 534
         END IF;
517 535
     END PROCESS p_data_wr;
518 536
 
519
-    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s, r_mul_res)
537
+    p_reg_hi_lo: PROCESS(r_reg_lo, r_reg_hi, r_op, r_reg_d, s_val_s, s_mul_res)
520 538
     BEGIN
521 539
         n_reg_lo            <= r_reg_lo;
522 540
         n_reg_hi            <= r_reg_hi;
... ...
@@ -537,8 +555,8 @@ BEGIN
537 555
             WHEN op_mtlo =>
538 556
                 n_reg_lo <= s_val_s;
539 557
             WHEN op_mult | op_multu =>
540
-                n_reg_lo <= std_logic_vector(r_mul_res(31 DOWNTO  0));
541
-                n_reg_hi <= std_logic_vector(r_mul_res(63 DOWNTO 32));
558
+                n_reg_lo <= std_logic_vector(s_mul_res(31 DOWNTO  0));
559
+                n_reg_hi <= std_logic_vector(s_mul_res(63 DOWNTO 32));
542 560
             WHEN OTHERS => NULL;
543 561
         END CASE;
544 562
     END PROCESS p_reg_hi_lo;
... ...
@@ -556,104 +574,7 @@ BEGIN
556 574
         END IF;
557 575
     END PROCESS p_sync_reg_hi_lo;
558 576
 
559
-    p_mul: PROCESS(r_mul, r_mul_a, r_mul_b, r_mul_res, r_op, s_val_s, s_val_t)
560
-        VARIABLE v_a:   unsigned(15 DOWNTO 0);
561
-        VARIABLE v_b:   unsigned(15 DOWNTO 0);
562
-        VARIABLE v_res: unsigned(31 DOWNTO 0);
563
-        VARIABLE v_add: unsigned(63 DOWNTO 0);
564
-        VARIABLE v_sum: unsigned(63 DOWNTO 0);
565
-    BEGIN
566
-        s_stall_mul <= '0';
567
-        n_mul       <= mul_idle;
568
-        n_mul_a     <= r_mul_a;
569
-        n_mul_b     <= r_mul_b;
570
-        n_mul_res   <= r_mul_res;
571
-        v_a         := (OTHERS => '0');
572
-        v_b         := (OTHERS => '0');
573
-        v_add       := (OTHERS => '0');
574
-        CASE r_mul IS
575
-            WHEN mul_idle =>
576
-                CASE r_op IS
577
-                    WHEN op_mult =>
578
-                        s_stall_mul <= '1';
579
-                        n_mul       <= mul_1;
580
-                        IF s_val_s(31) = '1' THEN
581
-                            n_mul_a <= unsigned(-signed(s_val_s));
582
-                        ELSE
583
-                            n_mul_a <= unsigned(s_val_s);
584
-                        END IF;
585
-                        IF s_val_t(31) = '1' THEN
586
-                            n_mul_b <= unsigned(-signed(s_val_t));
587
-                        ELSE
588
-                            n_mul_b <= unsigned(s_val_t);
589
-                        END IF;
590
-                        n_mul_res <= (OTHERS => '0');
591
-                    WHEN op_multu =>
592
-                        s_stall_mul <= '1';
593
-                        n_mul       <= mul_1;
594
-                        n_mul_a     <= unsigned(s_val_s);
595
-                        n_mul_b     <= unsigned(s_val_t);
596
-                    WHEN OTHERS => NULL;
597
-                END CASE;
598
-            WHEN mul_1 =>
599
-                s_stall_mul <= '1';
600
-                n_mul       <= mul_2;
601
-                v_a         := r_mul_a(15 DOWNTO  0);
602
-                v_b         := r_mul_b(15 DOWNTO  0);
603
-            WHEN mul_2 =>
604
-                s_stall_mul <= '1';
605
-                n_mul       <= mul_3;
606
-                v_a         := r_mul_a(31 DOWNTO 16);
607
-                v_b         := r_mul_b(15 DOWNTO  0);
608
-            WHEN mul_3 =>
609
-                s_stall_mul <= '1';
610
-                n_mul       <= mul_4;
611
-                v_a         := r_mul_a(15 DOWNTO  0);
612
-                v_b         := r_mul_b(31 DOWNTO 16);
613
-            WHEN mul_4 =>
614
-                s_stall_mul <= '1';
615
-                n_mul       <= mul_post;
616
-                v_a         := r_mul_a(31 DOWNTO 16);
617
-                v_b         := r_mul_b(31 DOWNTO 16);
618
-            WHEN OTHERS => NULL;
619
-        END CASE;
620
-        v_res := v_a * v_b;
621
-        CASE r_mul IS
622
-            WHEN mul_1 => v_add := X"00000000" & v_res;
623
-            WHEN mul_2 => v_add := X"0000" & v_res & X"0000";
624
-            WHEN mul_3 => v_add := X"0000" & v_res & X"0000";
625
-            WHEN mul_4 => v_add := v_res & X"00000000";
626
-            WHEN OTHERS => NULL;
627
-        END CASE;
628
-        v_sum := r_mul_res + v_add;
629
-        CASE r_mul IS
630
-            WHEN mul_1 | mul_2 | mul_3 | mul_4 =>
631
-                n_mul_res <= v_sum;
632
-            WHEN mul_post =>
633
-                IF r_op = op_mult AND (s_val_s(31) = '1' XOR s_val_t(31) = '1') THEN
634
-                    n_mul_res <= unsigned(-signed(r_mul_res));
635
-                ELSE
636
-                    n_mul_res <= r_mul_res;
637
-                END IF;
638
-            WHEN OTHERS => NULL;
639
-        END CASE;
640
-    END PROCESS p_mul;
641
-
642
-    p_sync_mul: PROCESS(rst, clk)
643
-    BEGIN
644
-        IF rst = '1' THEN
645
-            r_mul     <= mul_idle;
646
-            r_mul_a   <= (OTHERS => '0');
647
-            r_mul_b   <= (OTHERS => '0');
648
-            r_mul_res <= (OTHERS => '0');
649
-        ELSIF rising_edge(clk) THEN
650
-            IF i_stall = '0' THEN
651
-                r_mul     <= n_mul;
652
-                r_mul_a   <= n_mul_a;
653
-                r_mul_b   <= n_mul_b;
654
-                r_mul_res <= n_mul_res;
655
-            END IF;
656
-        END IF;
657
-    END PROCESS p_sync_mul;
577
+    s_mul_signed <= '1' WHEN r_op = op_mult ELSE '0';
578
+    s_mul_start  <= '1' WHEN i_stall = '0' AND (r_op = op_mult OR r_op = op_multu) ELSE '0';
658 579
 
659 580
 END ARCHITECTURE a_mips_core;
... ...
@@ -0,0 +1,141 @@
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_mul IS
7
+    PORT (
8
+        rst:      IN  std_logic;
9
+        clk:      IN  std_logic;
10
+        i_a:      IN  std_logic_vector(31 DOWNTO 0);
11
+        i_b:      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(63 DOWNTO 0)
16
+    );
17
+END ENTITY e_mips_mul;
18
+
19
+ARCHITECTURE a_mips_mul OF e_mips_mul IS
20
+
21
+    TYPE t_state IS (idle, state_1, state_2, state_3, state_4, post);
22
+    SIGNAL n_state: t_state;
23
+    SIGNAL r_state: t_state;
24
+
25
+    SIGNAL n_a:   unsigned(31 DOWNTO 0);
26
+    SIGNAL n_b:   unsigned(31 DOWNTO 0);
27
+    SIGNAL n_neg: boolean;
28
+    SIGNAL n_res: unsigned(63 DOWNTO 0);
29
+    SIGNAL r_a:   unsigned(31 DOWNTO 0);
30
+    SIGNAL r_b:   unsigned(31 DOWNTO 0);
31
+    SIGNAL r_res: unsigned(63 DOWNTO 0);
32
+    SIGNAL r_neg: boolean;
33
+
34
+BEGIN
35
+
36
+    p_mul: PROCESS(r_state, r_a, r_b, r_neg, r_res,
37
+                   i_a, i_b, i_signed, i_start)
38
+        VARIABLE v_a:   unsigned(15 DOWNTO 0);
39
+        VARIABLE v_b:   unsigned(15 DOWNTO 0);
40
+        VARIABLE v_res: unsigned(31 DOWNTO 0);
41
+        VARIABLE v_add: unsigned(63 DOWNTO 0);
42
+        VARIABLE v_sum: unsigned(63 DOWNTO 0);
43
+    BEGIN
44
+        o_busy  <= '0';
45
+        n_state <= idle;
46
+        n_a     <= r_a;
47
+        n_b     <= r_b;
48
+        n_neg   <= r_neg;
49
+        n_res   <= r_res;
50
+        v_a     := (OTHERS => '0');
51
+        v_b     := (OTHERS => '0');
52
+        v_add   := (OTHERS => '0');
53
+        CASE r_state IS
54
+            WHEN idle =>
55
+                IF i_start = '1' THEN
56
+                    o_busy  <= '1';
57
+                    n_state <= state_1;
58
+                    IF i_signed = '1' THEN
59
+                        IF i_a(31) = '1' THEN
60
+                            n_a <= unsigned(-signed(i_a));
61
+                        ELSE
62
+                            n_a <= unsigned(i_a);
63
+                        END IF;
64
+                        IF i_b(31) = '1' THEN
65
+                            n_b <= unsigned(-signed(i_b));
66
+                        ELSE
67
+                            n_b <= unsigned(i_b);
68
+                        END IF;
69
+                        n_neg <= i_a(31) = '1' XOR i_b(31) = '1';
70
+                    ELSE
71
+                        n_a   <= unsigned(i_a);
72
+                        n_b   <= unsigned(i_b);
73
+                        n_neg <= false;
74
+                    END IF;
75
+                END IF;
76
+            WHEN state_1 =>
77
+                o_busy  <= '1';
78
+                n_state <= state_2;
79
+                v_a     := r_a(15 DOWNTO  0);
80
+                v_b     := r_b(15 DOWNTO  0);
81
+            WHEN state_2 =>
82
+                o_busy  <= '1';
83
+                n_state <= state_3;
84
+                v_a     := r_a(31 DOWNTO 16);
85
+                v_b     := r_b(15 DOWNTO  0);
86
+            WHEN state_3 =>
87
+                o_busy  <= '1';
88
+                n_state <= state_4;
89
+                v_a     := r_a(15 DOWNTO  0);
90
+                v_b     := r_b(31 DOWNTO 16);
91
+            WHEN state_4 =>
92
+                o_busy  <= '1';
93
+                n_state <= post;
94
+                v_a     := r_a(31 DOWNTO 16);
95
+                v_b     := r_b(31 DOWNTO 16);
96
+            WHEN OTHERS => NULL;
97
+        END CASE;
98
+        v_res := v_a * v_b;
99
+        CASE r_state IS
100
+            WHEN state_1 => v_add := X"00000000" & v_res;
101
+            WHEN state_2 => v_add := X"0000" & v_res & X"0000";
102
+            WHEN state_3 => v_add := X"0000" & v_res & X"0000";
103
+            WHEN state_4 => v_add := v_res & X"00000000";
104
+            WHEN OTHERS => NULL;
105
+        END CASE;
106
+        v_sum := r_res + v_add;
107
+        CASE r_state IS
108
+            WHEN idle =>
109
+                n_res <= (OTHERS => '0');
110
+            WHEN state_1 | state_2 | state_3 | state_4 =>
111
+                n_res <= v_sum;
112
+            WHEN post =>
113
+                IF r_neg THEN
114
+                    n_res <= unsigned(-signed(r_res));
115
+                ELSE
116
+                    n_res <= r_res;
117
+                END IF;
118
+            WHEN OTHERS => NULL;
119
+        END CASE;
120
+    END PROCESS p_mul;
121
+
122
+    p_sync: PROCESS(rst, clk)
123
+    BEGIN
124
+        IF rst = '1' THEN
125
+            r_state <= idle;
126
+            r_a     <= (OTHERS => '0');
127
+            r_b     <= (OTHERS => '0');
128
+            r_neg   <= false;
129
+            r_res   <= (OTHERS => '0');
130
+        ELSIF rising_edge(clk) THEN
131
+            r_state <= n_state;
132
+            r_a     <= n_a;
133
+            r_b     <= n_b;
134
+            r_neg   <= n_neg;
135
+            r_res   <= n_res;
136
+        END IF;
137
+    END PROCESS p_sync;
138
+
139
+    o_res <= std_logic_vector(n_res);
140
+
141
+END ARCHITECTURE a_mips_mul;
... ...
@@ -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="4"/>
20
+      <association xil_pn:name="Implementation" xil_pn:seqID="5"/>
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="6"/>
28
+      <association xil_pn:name="Implementation" xil_pn:seqID="7"/>
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="7"/>
32
+      <association xil_pn:name="Implementation" xil_pn:seqID="8"/>
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,7 +47,11 @@
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="5"/>
50
+      <association xil_pn:name="Implementation" xil_pn:seqID="6"/>
51
+    </file>
52
+    <file xil_pn:name="mips/mul.vhd" xil_pn:type="FILE_VHDL">
53
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="93"/>
54
+      <association xil_pn:name="Implementation" xil_pn:seqID="4"/>
51 55
     </file>
52 56
   </files>
53 57
 
54 58