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
81
82
83
84
85
86
|
module alu_op_decode (
input [6:0] opcode,
input [2:0] funct3,
input [6:0] funct7,
input alu_ctrl,
output reg [3:0] alu_op
);
parameter ALU_OP_ADD = 4'b0000,
ALU_OP_SUB = 4'b0001,
ALU_OP_SLT = 4'b0010,
ALU_OP_SLTU = 4'b0011,
ALU_OP_AND = 4'b0100,
ALU_OP_OR = 4'b0101,
ALU_OP_XOR = 4'b0110,
ALU_OP_SLL = 4'b1000,
ALU_OP_SRL = 4'b1001,
ALU_OP_SRA = 4'b1011;
always @ (*) begin
if (alu_ctrl == 1'b1) alu_op <= ALU_OP_ADD;
else case (opcode)
7'b0110011: begin // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND
case (funct3)
3'b000: alu_op <= funct7[5] ? ALU_OP_SUB : ALU_OP_ADD;
3'b001: alu_op <= ALU_OP_SLL;
3'b010: alu_op <= ALU_OP_SLT;
3'b011: alu_op <= ALU_OP_SLTU;
3'b100: alu_op <= ALU_OP_XOR;
3'b101: alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
3'b110: alu_op <= ALU_OP_OR;
3'b111: alu_op <= ALU_OP_AND;
default: alu_op <= ALU_OP_ADD;
endcase
end
7'b0010011: begin // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI
case (funct3)
3'b000: alu_op <= ALU_OP_ADD;
3'b001: alu_op <= ALU_OP_SLL;
3'b010: alu_op <= ALU_OP_SLT;
3'b011: alu_op <= ALU_OP_SLTU;
3'b100: alu_op <= ALU_OP_XOR;
3'b101: alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
3'b110: alu_op <= ALU_OP_OR;
3'b111: alu_op <= ALU_OP_AND;
default: alu_op <= ALU_OP_ADD;
endcase
end
7'b0000011: begin // LB, LH, LW, LBU, LHU
alu_op <= ALU_OP_ADD;
end
7'b1100111: begin // JALR
alu_op <= ALU_OP_ADD;
end
7'b0100011: begin // SB, SH, SW
alu_op <= ALU_OP_ADD;
end
7'b1100011: begin // BEQ, BNE, BLT, BGE, BLTU, BGEU
if ((funct3 == 3'b000) | (funct3 == 3'b001)) alu_op <= ALU_OP_SUB;
else if ((funct3 == 3'b100) | (funct3 == 3'b101)) alu_op <= ALU_OP_SLT;
else if ((funct3 == 3'b110) | (funct3 == 3'b111)) alu_op <= ALU_OP_SLTU;
else alu_op <= ALU_OP_ADD;
end
7'b0110111: begin // LUI
alu_op <= ALU_OP_ADD;
end
7'b0010111: begin // AUIPC
alu_op <= ALU_OP_ADD;
end
7'b1101111: begin // JAL
alu_op <= ALU_OP_ADD;
end
7'b0001111: begin // FENCE, FENCE.I
alu_op <= ALU_OP_ADD;
end
7'b1110011: begin // ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI
alu_op <= ALU_OP_ADD;
end
default: alu_op <= ALU_OP_ADD;
endcase
end
endmodule
|