ALU.v
1.3 KB
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
module ALU(aluin1, aluin2, aluctrl, aluout, alubranch);
input[31:0] aluin1, aluin2;
input[3:0] aluctrl;
output reg[31:0] aluout;
output alubranch;
reg overflow;
reg[63:0] temp;
reg[31:0] HI, LO; // HI, LO register for multiplication and division.
assign alubranch = aluout == 32'h00000000 ? 1'b1 : 1'b0;
initial begin
temp = 64'h0000000000000000;
HI = 32'h00000000;
LO = 32'h00000000;
end
always @(*) begin
overflow = 0;
case(aluctrl)
4'b0000: aluout = aluin1 & aluin2; // and
4'b0001: aluout = aluin1 | aluin2; // or
4'b0010: begin // add
aluout = aluin1 + aluin2;
overflow = aluin1[31]==aluin2[31] && aluin1[31]!=aluout[31] ? 1'b1 : 1'b0; // overflow detection.
end
4'b0110: begin // sub
aluout = aluin1 - aluin2;
overflow = aluin1[31]!=aluin2[31] && aluin1[31]!=aluout[31] ? 1'b1 : 1'b0; // overflow detection.
end
4'b0111: begin // slt
aluout[31:1] = {31{1'b0}};
aluout[0] = aluin1 < aluin2 ? 1'b1 : 1'b0;
end
4'b1000: begin // mult
temp = aluin1 * aluin2;
HI = temp[63:32];
LO = temp[31:0];
end
4'b1001: begin // div
HI = aluin1 % aluin2;
LO = aluin1 / aluin2;
end
4'b1010: aluout = HI; // mfhi
4'b1011: aluout = LO; // mflo
4'b1100: aluout = ~(aluin1 | aluin2); // nor
4'b1101: aluout = aluin1 ^ aluin2; // xor
default: aluout = 32'b0;
endcase
end
endmodule