ALU.v
2.1 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module ALU(clk, aluin1, aluin2, aluctrl, aluout, alubranch);
input clk;
input[31:0] aluin1, aluin2;
input[3:0] aluctrl;
output reg[31:0] aluout;
output reg[5:0] alubranch;
reg overflow;
reg[63:0] temp;
reg[31:0] HI, LO; // HI, LO register for multiplication and division.
reg[31:0] tempHI, tempLO; // temporary HI, LO register for multiplication and division.
initial begin
temp = 64'h0000000000000000;
tempHI = 32'h00000000;
tempLO = 32'h00000000;
HI = 32'h00000000;
LO = 32'h00000000;
end
always @(*) begin
overflow = 1'b0;
alubranch = 6'b0;
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.
alubranch[0] = (aluout == 32'h00000000) ? 1'b1 : 1'b0; // beq
alubranch[1] = (aluout != 32'h00000000) ? 1'b1 : 1'b0; // bne
alubranch[2] = (aluin1 > 32'h00000000) ? 1'b1 : 1'b0; // bgtz
alubranch[3] = (aluin1 < 32'h00000000) ? 1'b1 : 1'b0; // bltz
alubranch[4] = (aluin1 >= 32'h00000000) ? 1'b1 : 1'b0; // bgez
alubranch[5] = (aluin1 <= 32'h00000000) ? 1'b1 : 1'b0; // blez
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;
tempHI <= temp[63:32];
tempLO <= temp[31:0];
end
4'b1001: begin // div
tempHI <= aluin1 % aluin2;
tempLO <= 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'h00000000;
endcase
end
always @(negedge clk) begin
case(aluctrl)
4'b1000: begin // mult
HI <= tempHI;
LO <= tempLO;
end
4'b1001: begin // div
HI <= tempHI;
LO <= tempLO;
end
endcase
tempHI = 32'd0;
tempLO = 32'd0;
end
endmodule