separated shifter from ALU
Stefan Schuermans

Stefan Schuermans commited on 2012-01-24 20:43:21
Showing 5 changed files, with 124 additions and 31 deletions.

... ...
@@ -14,52 +14,58 @@ END ENTITY e_mips_alu;
14 14
 
15 15
 ARCHITECTURE a_mips_alu OF e_mips_alu IS
16 16
 
17
+    SIGNAL s_shift_arith: std_logic;
18
+    SIGNAL s_shift_left:  std_logic;
19
+    SIGNAL s_shift_out:   std_logic_vector(31 DOWNTO 0);
20
+
21
+    COMPONENT e_mips_shifter IS
22
+        PORT (
23
+            i_arith: IN  std_logic;
24
+            i_left:  IN  std_logic;
25
+            i_val:   IN  std_logic_vector(31 DOWNTO 0);
26
+            i_num:   IN  std_logic_vector(31 DOWNTO 0);
27
+            o_val:   OUT std_logic_vector(31 DOWNTO 0)
28
+        );
29
+    END COMPONENT e_mips_shifter;
30
+
17 31
 BEGIN
18 32
 
19
-    p_alu: PROCESS(i_alu, i_op1, i_op2)
33
+    shifter: e_mips_shifter
34
+        PORT MAP (
35
+            i_arith => s_shift_arith,
36
+            i_left  => s_shift_left,
37
+            i_val   => i_op1,
38
+            i_num   => i_op2,
39
+            o_val   => s_shift_out
40
+        );
41
+
42
+    p_alu: PROCESS(i_alu, i_op1, i_op2, s_shift_out)
20 43
         VARIABLE v_op1_s: signed(31 DOWNTO 0);
21 44
         VARIABLE v_op2_s: signed(31 DOWNTO 0);
22 45
         VARIABLE v_op1_u: unsigned(31 DOWNTO 0);
23 46
         VARIABLE v_op2_u: unsigned(31 DOWNTO 0);
24
-        VARIABLE v_int5:  integer RANGE 31 DOWNTO 0;
25
-        VARIABLE v_tmp64: std_logic_vector(63 DOWNTO 0);
26 47
     BEGIN
27 48
         v_op1_s := signed(i_op1);
28 49
         v_op2_s := signed(i_op2);
29 50
         v_op1_u := unsigned(i_op1);
30 51
         v_op2_u := unsigned(i_op2);
52
+        s_shift_arith <= '0';
53
+        s_shift_left <= '0';
31 54
         CASE i_alu IS
32 55
             WHEN alu_add => o_res <= std_logic_vector(v_op1_s + v_op2_s);
33 56
             WHEN alu_and => o_res <= i_op1 AND i_op2;
34 57
             WHEN alu_nor => o_res <= i_op1 NOR i_op2;
35 58
             WHEN alu_or  => o_res <= i_op1 OR i_op2;
36 59
             WHEN alu_sub => o_res <= std_logic_vector(v_op1_s - v_op2_s);
37
-            WHEN alu_sll => IF i_op2(31 DOWNTO 5) = X"000000" & "000" THEN
38
-                                v_int5  := to_integer(v_op2_u(4 DOWNTO 0));
39
-                                v_tmp64 := i_op1 & X"00000000";
40
-                                o_res   <= v_tmp64(v_int5 + 31 DOWNTO v_int5);
41
-                            ELSE
42
-                                o_res   <= X"00000000";
43
-                            END IF;
44
-            WHEN alu_sra => IF i_op2(31 DOWNTO 5) = X"000000" & "000" THEN
45
-                                v_int5  := to_integer(v_op2_u(4 DOWNTO 0));
46
-                                IF i_op1(31) = '1' THEN
47
-                                    v_tmp64 := X"FFFFFFFF" & i_op1;
48
-                                ELSE
49
-                                    v_tmp64 := X"00000000" & i_op1;
50
-                                END IF;
51
-                                o_res   <= v_tmp64(63 - v_int5 DOWNTO 32 - v_int5);
52
-                            ELSE
53
-                                o_res   <= X"00000000";
54
-                            END IF;
55
-            WHEN alu_srl => IF i_op2(31 DOWNTO 5) = X"000000" & "000" THEN
56
-                                v_int5  := to_integer(v_op2_u(4 DOWNTO 0));
57
-                                v_tmp64 := X"00000000" & i_op1;
58
-                                o_res   <= v_tmp64(63 - v_int5 DOWNTO 32 - v_int5);
60
+            WHEN alu_sll => s_shift_arith <= '0'; s_shift_left <= '1'; o_res <= s_shift_out;
61
+            WHEN alu_sra => s_shift_arith <= '1'; s_shift_left <= '0'; o_res <= s_shift_out;
62
+            WHEN alu_srl => s_shift_arith <= '1'; s_shift_left <= '0'; o_res <= s_shift_out;
63
+            WHEN alu_slt => IF v_op1_s < v_op2_s THEN
64
+                                o_res <= X"00000001";
59 65
                             ELSE
60 66
                                 o_res <= X"00000000";
61 67
                             END IF;
62
-            WHEN alu_slt => IF v_op1_s < v_op2_s THEN
68
+            WHEN alu_sltu => IF v_op1_u < v_op2_u THEN
63 69
                                  o_res <= X"00000001";
64 70
                              ELSE
65 71
                                  o_res <= X"00000000";
... ...
@@ -128,7 +128,7 @@ BEGIN
128 128
                     WHEN "100110" => o_op <= op_alu; o_alu <= alu_xor;
129 129
                     WHEN "100111" => o_op <= op_alu; o_alu <= alu_nor;
130 130
                     WHEN "101010" => o_op <= op_alu; o_alu <= alu_slt;
131
-                    WHEN "101011" => o_op <= op_alu; o_alu <= alu_slt;
131
+                    WHEN "101011" => o_op <= op_alu; o_alu <= alu_sltu;
132 132
                     WHEN OTHERS => NULL;
133 133
                 END CASE;
134 134
             WHEN "000010" => o_op <= op_j;
... ...
@@ -140,7 +140,7 @@ BEGIN
140 140
             WHEN "001000" => o_op <= op_alu; o_alu <= alu_add; o_imm <= imm_16se;
141 141
             WHEN "001001" => o_op <= op_alu; o_alu <= alu_add; o_imm <= imm_16se;
142 142
             WHEN "001010" => o_op <= op_alu; o_alu <= alu_slt; o_imm <= imm_16se;
143
-            WHEN "001011" => o_op <= op_alu; o_alu <= alu_slt; o_imm <= imm_16se;
143
+            WHEN "001011" => o_op <= op_alu; o_alu <= alu_sltu; o_imm <= imm_16se;
144 144
             WHEN "001100" => o_op <= op_alu; o_alu <= alu_and; o_imm <= imm_16ze;
145 145
             WHEN "001101" => o_op <= op_alu; o_alu <= alu_or; o_imm <= imm_16ze;
146 146
             WHEN "001110" => o_op <= op_alu; o_alu <= alu_xor; o_imm <= imm_16ze;
... ...
@@ -0,0 +1,82 @@
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_shifter IS
7
+    PORT (
8
+        i_arith: IN  std_logic;
9
+        i_left:  IN  std_logic;
10
+        i_val:   IN  std_logic_vector(31 DOWNTO 0);
11
+        i_num:   IN  std_logic_vector(31 DOWNTO 0);
12
+        o_val:   OUT std_logic_vector(31 DOWNTO 0)
13
+    );
14
+END ENTITY e_mips_shifter;
15
+
16
+ARCHITECTURE a_mips_shifter OF e_mips_shifter IS
17
+
18
+    SIGNAL s_in:   std_logic_vector(31 DOWNTO 0);
19
+    SIGNAL s_fill: std_logic;
20
+    SIGNAL s_out:  std_logic_vector(31 DOWNTO 0);
21
+
22
+    FUNCTION l_shift(b:    std_logic;
23
+                     val:  std_logic_vector(31 DOWNTO 0);
24
+                     n:    natural) RETURN std_logic_vector IS
25
+        VARIABLE v_fill: std_logic_vector(31 DOWNTO 0);
26
+    BEGIN
27
+        v_fill := (OTHERS => '0');
28
+        IF b = '1' THEN
29
+            RETURN val(31 - n DOWNTO 0) & v_fill(n - 1 DOWNTO 0);
30
+        ELSE
31
+            RETURN val;
32
+        END IF;
33
+    END FUNCTION l_shift;
34
+
35
+    FUNCTION r_shift(b:    std_logic;
36
+                     val:  std_logic_vector(31 DOWNTO 0);
37
+                     fill: std_logic;
38
+                     n:    natural) RETURN std_logic_vector IS
39
+        VARIABLE v_fill: std_logic_vector(31 DOWNTO 0);
40
+    BEGIN
41
+        v_fill := (OTHERS => fill);
42
+        IF b = '1' THEN
43
+            RETURN v_fill(n - 1 DOWNTO 0) & val(31 DOWNTO n);
44
+        ELSE
45
+            RETURN val;
46
+        END IF;
47
+    END FUNCTION r_shift;
48
+
49
+BEGIN
50
+
51
+    s_fill <= i_arith AND s_in(31);
52
+
53
+    p_shift: PROCESS(i_val, i_num)
54
+        VARIABLE v1:   std_logic_vector(31 DOWNTO 0);
55
+        VARIABLE v2:   std_logic_vector(31 DOWNTO 0);
56
+        VARIABLE v3:   std_logic_vector(31 DOWNTO 0);
57
+        VARIABLE v4:   std_logic_vector(31 DOWNTO 0);
58
+        VARIABLE v5:   std_logic_vector(31 DOWNTO 0);
59
+        CONSTANT zero: std_logic_vector(31 DOWNTO 5) := (OTHERS => '0');
60
+    BEGIN
61
+        IF i_left = '1' THEN
62
+            v1 := l_shift(i_num(0), i_val,  1);
63
+            v2 := l_shift(i_num(1), v1,     2);
64
+            v3 := l_shift(i_num(2), v2,     4);
65
+            v4 := l_shift(i_num(3), v3,     8);
66
+            v5 := l_shift(i_num(4), v4,    16);
67
+        ELSE
68
+            v1 := r_shift(i_num(0), i_val, s_fill,  1);
69
+            v2 := r_shift(i_num(1), v1,    s_fill,  2);
70
+            v3 := r_shift(i_num(2), v2,    s_fill,  4);
71
+            v4 := r_shift(i_num(3), v3,    s_fill,  8);
72
+            v5 := r_shift(i_num(4), v4,    s_fill, 16);
73
+        END IF;
74
+        IF i_num(31 DOWNTO 5) = zero THEN
75
+            o_val <= v5;
76
+        ELSE
77
+            o_val <= (OTHERS => s_fill);
78
+        END IF;
79
+    END PROCESS p_shift;
80
+
81
+END ARCHITECTURE a_mips_shifter;
82
+
... ...
@@ -39,6 +39,7 @@ PACKAGE mips_types IS
39 39
         alu_sra,  -- shift right arithmetically
40 40
         alu_srl,  -- shift right logically
41 41
         alu_slt,  -- set on less than
42
+        alu_sltu, -- set on less than unsigned
42 43
         alu_xor   -- bitwise XOR
43 44
     );
44 45
 
... ...
@@ -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="3"/>
20
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
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="4"/>
28
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
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="5"/>
32
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
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"/>
... ...
@@ -39,6 +39,10 @@
39 39
     </file>
40 40
     <file xil_pn:name="mips/regs.vhd" xil_pn:type="FILE_VHDL">
41 41
       <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="81"/>
42
+      <association xil_pn:name="Implementation" xil_pn:seqID="0"/>
43
+    </file>
44
+    <file xil_pn:name="mips/shifter.vhd" xil_pn:type="FILE_VHDL">
45
+      <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="85"/>
42 46
       <association xil_pn:name="Implementation" xil_pn:seqID="2"/>
43 47
     </file>
44 48
   </files>
45 49