OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [MIPS32_Standalone/] [ALU.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ayersg
`timescale 1ns / 1ps
2
/*
3
 * File         : ALU.v
4
 * Project      : University of Utah, XUM Project MIPS32 core
5
 * Creator(s)   : Grant Ayers (ayers@cs.utah.edu)
6
 *
7
 * Modification History:
8
 *   Rev   Date         Initials  Description of Change
9
 *   1.0   7-Jun-2011   GEA       Initial design.
10
 *   2.0   26-Jul-2012  GEA       Many changes have been made.
11
 *
12
 * Standards/Formatting:
13
 *   Verilog 2001, 4 soft tab, wide column.
14
 *
15
 * Description:
16
 *   An Arithmetic Logic Unit for a MIPS32 processor. This module computes all
17
 *   arithmetic operations, including the following:
18
 *
19
 *   Add, Subtract, Multiply, And, Or, Nor, Xor, Shift, Count leading 1s/0s.
20
 */
21
module ALU(
22
        input  clock,
23
        input  reset,
24
    input  EX_Stall,
25
    input  EX_Flush,
26
        input  [31:0] A, B,
27
        input  [4:0]  Operation,
28
        input  signed [4:0] Shamt,
29
        output reg signed [31:0] Result,
30
    output BZero,  // Used for Movc
31
        output reg EXC_Ov
32
        );
33
 
34
        `include "MIPS_Parameters.v"
35
 
36
    /***
37
     Performance Notes:
38
 
39
     The ALU is the longest delay path in the Execute stage, and one of the longest
40
     in the entire processor. This path varies based on the logic blocks that are
41
     chosen to implement various functions, but there is certainly room to improve
42
     the speed of arithmetic operations. The ALU could also be placed in a separate
43
     pipeline stage after the Execute forwarding has completed.
44
    ***/
45
 
46
    wire signed [31:0] As = A;
47
    wire signed [31:0] Bs = B;
48
 
49
    reg  [63:0] HILO;
50
    wire [31:0] HI = HILO[63:32];
51
    wire [31:0] LO = HILO[31:0];
52
    wire HILO_Commit = ~(EX_Stall | EX_Flush);
53
 
54
    wire AddSub_Add = ((Operation == AluOp_Add) | (Operation == AluOp_Addu));
55
    wire signed [31:0] AddSub_Result = (AddSub_Add) ? (A + B) : (A - B);
56
 
57
    wire signed [63:0] Mult_Result = As * Bs;
58
    wire [63:0] Multu_Result = A * B;
59
 
60
    reg  [5:0] CLO_Result, CLZ_Result;
61
 
62
    assign BZero = (B == 32'h00000000);
63
 
64
    always @(*) begin
65
        case (Operation)
66
            AluOp_Add   : Result <= AddSub_Result;
67
            AluOp_Addu  : Result <= AddSub_Result;
68
            AluOp_And   : Result <= A & B;
69
            AluOp_Clo   : Result <= {26'b0, CLO_Result};
70
            AluOp_Clz   : Result <= {26'b0, CLZ_Result};
71
            AluOp_Div   : Result <= 32'hdeafbeef;   // XXX implement division
72
            AluOp_Divu  : Result <= 32'hdeadbeef;   // XXX implement division
73
            AluOp_Mfhi  : Result <= HI;
74
            AluOp_Mflo  : Result <= LO;
75
            AluOp_Mul   : Result <= Mult_Result[31:0];
76
            AluOp_Nor   : Result <= ~(A | B);
77
            AluOp_Or    : Result <= A | B;
78
            AluOp_Sll   : Result <= B << Shamt;
79
            AluOp_Sllc  : Result <= {B[15:0], 16'b0};
80
            AluOp_Sllv  : Result <= B << A[4:0];
81
            AluOp_Slt   : Result <= (As < Bs) ? 32'h00000001 : 32'h00000000;
82
            AluOp_Sltu  : Result <= (A < B)   ? 32'h00000001 : 32'h00000000;
83
            AluOp_Sra   : Result <= Bs >>> Shamt;
84
            AluOp_Srav  : Result <= Bs >>> As[4:0];
85
            AluOp_Srl   : Result <= B >> Shamt;
86
            AluOp_Srlv  : Result <= B >> A[4:0];
87
            AluOp_Sub   : Result <= AddSub_Result;
88
            AluOp_Subu  : Result <= AddSub_Result;
89
            AluOp_Xor   : Result <= A ^ B;
90
            default     : Result <= 32'bx;
91
        endcase
92
    end
93
 
94
 
95
    always @(posedge clock) begin
96
        if (reset) begin
97
            HILO <= 64'h00000000_00000000;
98
        end
99
        else if (HILO_Commit) begin
100
            case (Operation)
101
                AluOp_Mult  : HILO <= Mult_Result;
102
                AluOp_Multu : HILO <= Multu_Result;
103
                AluOp_Madd  : HILO <= HILO + Mult_Result;
104
                AluOp_Maddu : HILO <= HILO + Multu_Result;
105
                AluOp_Msub  : HILO <= HILO - Mult_Result;
106
                AluOp_Msubu : HILO <= HILO - Multu_Result;
107
                AluOp_Mthi  : HILO <= {A, LO};
108
                AluOp_Mtlo  : HILO <= {HI, B};
109
                default     : HILO <= HILO;
110
            endcase
111
        end
112
        else begin
113
            HILO <= HILO;
114
        end
115
    end
116
 
117
    // Detect overflow for signed operations. Note that MIPS32 has no overflow
118
    // detection for multiplication/division operations.
119
    always @(*) begin
120
        case (Operation)
121
            AluOp_Add : EXC_Ov <= ((A[31] ~^ B[31]) & (A[31] ^ AddSub_Result[31]));
122
                        AluOp_Sub : EXC_Ov <= ((A[31]  ^ B[31]) & (A[31] ^ AddSub_Result[31]));
123
                        default   : EXC_Ov <= 0;
124
        endcase
125
    end
126
 
127
 
128
        // Count Leading Ones
129
        always @(A) begin
130
                casex (A)
131
                        32'b0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd0;
132
                        32'b10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd1;
133
                        32'b110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd2;
134
                        32'b1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd3;
135
                        32'b1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd4;
136
                        32'b1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd5;
137
                        32'b1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd6;
138
                        32'b1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd7;
139
                        32'b1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd8;
140
                        32'b1111_1111_10xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd9;
141
                        32'b1111_1111_110x_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd10;
142
                        32'b1111_1111_1110_xxxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd11;
143
                        32'b1111_1111_1111_0xxx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd12;
144
                        32'b1111_1111_1111_10xx_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd13;
145
                        32'b1111_1111_1111_110x_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd14;
146
                        32'b1111_1111_1111_1110_xxxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd15;
147
                        32'b1111_1111_1111_1111_0xxx_xxxx_xxxx_xxxx : CLO_Result <= 6'd16;
148
                        32'b1111_1111_1111_1111_10xx_xxxx_xxxx_xxxx : CLO_Result <= 6'd17;
149
                        32'b1111_1111_1111_1111_110x_xxxx_xxxx_xxxx : CLO_Result <= 6'd18;
150
                        32'b1111_1111_1111_1111_1110_xxxx_xxxx_xxxx : CLO_Result <= 6'd19;
151
                        32'b1111_1111_1111_1111_1111_0xxx_xxxx_xxxx : CLO_Result <= 6'd20;
152
                        32'b1111_1111_1111_1111_1111_10xx_xxxx_xxxx : CLO_Result <= 6'd21;
153
                        32'b1111_1111_1111_1111_1111_110x_xxxx_xxxx : CLO_Result <= 6'd22;
154
                        32'b1111_1111_1111_1111_1111_1110_xxxx_xxxx : CLO_Result <= 6'd23;
155
                        32'b1111_1111_1111_1111_1111_1111_0xxx_xxxx : CLO_Result <= 6'd24;
156
                        32'b1111_1111_1111_1111_1111_1111_10xx_xxxx : CLO_Result <= 6'd25;
157
                        32'b1111_1111_1111_1111_1111_1111_110x_xxxx : CLO_Result <= 6'd26;
158
                        32'b1111_1111_1111_1111_1111_1111_1110_xxxx : CLO_Result <= 6'd27;
159
                        32'b1111_1111_1111_1111_1111_1111_1111_0xxx : CLO_Result <= 6'd28;
160
                        32'b1111_1111_1111_1111_1111_1111_1111_10xx : CLO_Result <= 6'd29;
161
                        32'b1111_1111_1111_1111_1111_1111_1111_110x : CLO_Result <= 6'd30;
162
                        32'b1111_1111_1111_1111_1111_1111_1111_1110 : CLO_Result <= 6'd31;
163
                        32'b1111_1111_1111_1111_1111_1111_1111_1111 : CLO_Result <= 6'd32;
164
                        default : CLO_Result <= 6'd0;
165
                endcase
166
        end
167
 
168
        // Count Leading Zeros
169
        always @(A) begin
170
                casex (A)
171
                        32'b1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd0;
172
                        32'b01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd1;
173
                        32'b001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd2;
174
                        32'b0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd3;
175
                        32'b0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd4;
176
                        32'b0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd5;
177
                        32'b0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd6;
178
                        32'b0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd7;
179
                        32'b0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd8;
180
                        32'b0000_0000_01xx_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd9;
181
                        32'b0000_0000_001x_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd10;
182
                        32'b0000_0000_0001_xxxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd11;
183
                        32'b0000_0000_0000_1xxx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd12;
184
                        32'b0000_0000_0000_01xx_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd13;
185
                        32'b0000_0000_0000_001x_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd14;
186
                        32'b0000_0000_0000_0001_xxxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd15;
187
                        32'b0000_0000_0000_0000_1xxx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd16;
188
                        32'b0000_0000_0000_0000_01xx_xxxx_xxxx_xxxx : CLZ_Result <= 6'd17;
189
                        32'b0000_0000_0000_0000_001x_xxxx_xxxx_xxxx : CLZ_Result <= 6'd18;
190
                        32'b0000_0000_0000_0000_0001_xxxx_xxxx_xxxx : CLZ_Result <= 6'd19;
191
                        32'b0000_0000_0000_0000_0000_1xxx_xxxx_xxxx : CLZ_Result <= 6'd20;
192
                        32'b0000_0000_0000_0000_0000_01xx_xxxx_xxxx : CLZ_Result <= 6'd21;
193
                        32'b0000_0000_0000_0000_0000_001x_xxxx_xxxx : CLZ_Result <= 6'd22;
194
                        32'b0000_0000_0000_0000_0000_0001_xxxx_xxxx : CLZ_Result <= 6'd23;
195
                        32'b0000_0000_0000_0000_0000_0000_1xxx_xxxx : CLZ_Result <= 6'd24;
196
                        32'b0000_0000_0000_0000_0000_0000_01xx_xxxx : CLZ_Result <= 6'd25;
197
                        32'b0000_0000_0000_0000_0000_0000_001x_xxxx : CLZ_Result <= 6'd26;
198
                        32'b0000_0000_0000_0000_0000_0000_0001_xxxx : CLZ_Result <= 6'd27;
199
                        32'b0000_0000_0000_0000_0000_0000_0000_1xxx : CLZ_Result <= 6'd28;
200
                        32'b0000_0000_0000_0000_0000_0000_0000_01xx : CLZ_Result <= 6'd29;
201
                        32'b0000_0000_0000_0000_0000_0000_0000_001x : CLZ_Result <= 6'd30;
202
                        32'b0000_0000_0000_0000_0000_0000_0000_0001 : CLZ_Result <= 6'd31;
203
                        32'b0000_0000_0000_0000_0000_0000_0000_0000 : CLZ_Result <= 6'd32;
204
                        default : CLZ_Result <= 6'd0;
205
                endcase
206
        end
207
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.