-
Notifications
You must be signed in to change notification settings - Fork 0
/
riscv_core_ex.v
85 lines (66 loc) · 2.5 KB
/
riscv_core_ex.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
module riscv_core_ex (
input clk,
input rstn,
//CT interface
input [31:0] ct_ex_op1_st2,
input [31:0] ct_ex_op2_st2,
//ID interface
input [9:0] id_ex_funct,
input id_ex_mux1_cntl,
input [31:0] id_ex_pc,
input id_ex_mux2_cntl,
input [31:0] id_ex_immed,
//MEM interface
output ex_mem_result
);
localparam FUNCT_NOP_OH = 10'b0000000000;
localparam FUNCT_ADD_OH = 10'b0000000001;
localparam FUNCT_SUB_OH = 10'b0000000010;
localparam FUNCT_OR_OH = 10'b0000000100;
localparam FUNCT_XOR_OH = 10'b0000001000;
localparam FUNCT_AND_OH = 10'b0000010000;
localparam FUNCT_STL_OH = 10'b0000100000;
localparam FUNCT_STLU_OH = 10'b0001000000;
localparam FUNCT_SLL_OH = 10'b0010000000;
localparam FUNCT_SRL_OH = 10'b0100000000;
localparam FUNCT_SRA_OH = 10'b1000000000;
wire [31:0] op1_st1;
wire [31:0] op2_st1;
wire [31:0] op1_st2;
wire [31:0] op2_st2;
wire [31:0] result_nxt;
wire flip_op2_st2;
wire [31:0] neg_op2_st2;
wire [5:0] shft_amnt;
assign op1_st1 = (id_ex_op1_cntl) ? id_ex_pc : ct_ex_op1;
assign op2_st1 = (id_ex_op2_cntl) ? id_ex_immed : ct_ex_op2;
assign op1_st2 = op1_st1;
assign op2_st2 = (flip_op2) ? neg_op2 : op2_st1;
assign flip_op2 == (id_ex_funct == FUNCT_SUB_OH) ? 1'b1 : 1'b0;
assign neg_op2 = (~op2_st1)+1;
assign shft_amnt = op2_st1 & 'h1f;
assign ex_mem_result = result_ff;
always @ (*) begin
case (id_ex_funct)
FUNCT_ADD_OH ,
FUNCT_SUB_OH : result = op1_st2 + op2_st2;
FUNCT_OR_OH : result = op1_st2 | op2_st2;
FUNCT_XOR_OH : result = op1_st2 ^ op2_st2;
FUNCT_AND_OH : result = op1_st2 & op2_st2;
FUNCT_STL_OH : result = ($signed(op1_st2) < $signed(op2_st2)) ? 1'b1 : 1'b0;
FUNCT_STLU_OH: result = (op1_st2 < op2_st2) ? 1'b1 : 1'b0;
FUNCT_SLL_OH : result = op1_st2 << shft_amnt;
FUNCT_SRL_OH : result = op1_st2 >> shft_amnt;
FUNCT_SRA_OH : result = op1_st2 >>> shft_amnt;
default : result = 32'b0;
endcase
end
always @ (posedge clk, negedge rstn) begin
if (~rstn) begin
result_ff <= 0;
end
else begin
result_ff <= result_nxt;
end
end
endmodule