-
Notifications
You must be signed in to change notification settings - Fork 0
/
alu.v
95 lines (84 loc) · 2.78 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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
module alu(
input [15:0] alu_op,
input [31:0] alu_src1,
input [31:0] alu_src2,
output [31:0] alu_result
);
wire op_add; //加法操作
wire op_sub; //减法操作
wire op_slt; //有符号比较,小于置位
wire op_sltu; //无符号比较,小于置位
wire op_and; //按位与
wire op_nor; //按位或非
wire op_or; //按位或
wire op_xor; //按位异或
wire op_sll; //逻辑左移
wire op_srl; //逻辑右移
wire op_sra; //算术右移
wire op_lui; //立即数置于高半部分
// control code decomposition
assign op_add = alu_op[ 0];
assign op_sub = alu_op[ 1];
assign op_slt = alu_op[ 2];
assign op_sltu = alu_op[ 3];
assign op_and = alu_op[ 4];
assign op_nor = alu_op[ 5];
assign op_or = alu_op[ 6];
assign op_xor = alu_op[ 7];
assign op_sll = alu_op[ 8];
assign op_srl = alu_op[ 9];
assign op_sra = alu_op[10];
assign op_lui = alu_op[11];
wire [31:0] add_sub_result;
wire [31:0] slt_result;
wire [31:0] sltu_result;
wire [31:0] and_result;
wire [31:0] nor_result;
wire [31:0] or_result;
wire [31:0] xor_result;
wire [31:0] lui_result;
wire [31:0] sll_result;
wire [63:0] sr64_result;
wire [31:0] sr_result;
// 32-bit adder
wire [31:0] adder_a;
wire [31:0] adder_b;
wire adder_cin;
wire [31:0] adder_result;
wire adder_cout;
assign adder_a = alu_src1;
assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2;
assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin;
// ADD, SUB result
assign add_sub_result = adder_result;
// SLT result
assign slt_result[31:1] = 31'b0;
assign slt_result[0] = (alu_src1[31] & ~alu_src2[31])
| ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]);
// SLTU result
assign sltu_result[31:1] = 31'b0;
assign sltu_result[0] = ~adder_cout;
// bitwise operation
assign and_result = alu_src1 & alu_src2;
assign or_result = alu_src1 | alu_src2;
assign nor_result = ~or_result;
assign xor_result = alu_src1 ^ alu_src2;
assign lui_result = {alu_src2[15:0], 16'b0};
// SLL result
assign sll_result = alu_src2 << alu_src1[4:0];
// SRL, SRA result
assign sr64_result = {{32{op_sra & alu_src2[31]}}, alu_src2[31:0]} >> alu_src1[4:0];
assign sr_result = sr64_result[31:0];
// final result mux
assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
| ({32{op_slt }} & slt_result)
| ({32{op_sltu }} & sltu_result)
| ({32{op_and }} & and_result)
| ({32{op_nor }} & nor_result)
| ({32{op_or }} & or_result)
| ({32{op_xor }} & xor_result)
| ({32{op_lui }} & lui_result)
| ({32{op_sll }} & sll_result)
| ({32{op_srl|op_sra}} & sr_result);
endmodule