-
Notifications
You must be signed in to change notification settings - Fork 0
/
alu.v
80 lines (78 loc) · 2.21 KB
/
alu.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* The Arithmetic Logic Unit (ALU) performs all the processes related to arithmetic and bitwise operations on integer binary numbers,
on instruction words in this case. The ALU is what essentially makes the datapath work, it calculates the result for Type-A
instructions and also some of the Type-C instructions, where the use of the sign-extended (extended) value is done from the
sign-extend module (signExtend.v).
*/
module alu(op1,op2,extended,aluDecr,ALUSrc,aluCtrl,aluRslt, aluRsltR15, ovExcep);
// Input Ports
input ALUSrc,aluCtrl;
input [15:0] op1;
input [15:0] op2;
input [15:0] extended;
input [3:0] aluDecr;
// Output ports
output reg [31:0] aluRslt;
output reg [15:0] aluRsltR15;
output wire ovExcep;
// Variables
reg ovFlowSE;
wire ovFlow;
wire [15:0] aluOp1;
wire [15:0] aluOp2;
assign aluOp1 = ALUSrc ? extended:op1;
assign aluOp2 =! ALUSrc && aluDecr[3] ? extended:op2;
assign ovExcep = ovFlow && ovFlowSE;
assign ovFlow = ((aluOp1[15]^~aluOp2[15])&&(aluOp1[15]^aluRslt[15]));
always@(*)
begin
case({aluCtrl,aluDecr})
5'b00000: // Signed Addition, op1 = op1 + op2
begin
aluRslt[31:16]={16{1'b0}};
aluRslt[15:0]=aluOp1+aluOp2;
ovFlowSE=1'b1;
end
5'b00001: // Signed Subtraction, op1 = op1 - op2
begin
aluRslt[31:16]={16{1'b0}};
aluRslt[15:0]=aluOp1-aluOp2;
ovFlowSE=1'b1;
end
5'b00100: // Signed Multiplication, op1 = op1 * op2, op1 != R15
begin
aluRslt[31:0]=aluOp1*aluOp2;
aluRsltR15[15:0]=aluRslt[31:16];
ovFlowSE=1'b0;
end
5'b00101: // Signed Division, op1 = op1 / op2, op1 != R15
begin
aluRslt[31:16]=aluOp1%aluOp2;
aluRsltR15[15:0]=aluOp1/aluOp2;
ovFlowSE=1'b0;
end
5'b00010: // AND Immediate, op1 = op1 & {8’b0, constant}
begin
aluRslt[31:16]={16{1'b0}};
aluRslt[15:0]=aluOp1&aluOp2;
ovFlowSE=1'b0;
end
5'b00011: // OR Immediate, op1 = op1 | {8’b0, constant}
begin
aluRslt[31:16]={16{1'b0}};
aluRslt[15:0]=aluOp1|aluOp2;
ovFlowSE=1'b0;
end
5'b1xxxx:
begin
aluRslt[(2*15)-1:15]={15{1'b0}};
aluRslt[15-1:0]=aluOp1 + aluOp2;
ovFlowSE=1'b0;
end
default:
begin
aluRslt[(2*15)-1:0]={2*15{1'b0}};
ovFlowSE=1'b0;
end
endcase
end
endmodule