forked from grahamedgecombe/icicle
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrv32_execute.sv
256 lines (227 loc) · 7.05 KB
/
rv32_execute.sv
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
`ifndef RV32_EXECUTE
`define RV32_EXECUTE
`include "rv32_alu.sv"
`include "rv32_branch.sv"
module rv32_execute #(
parameter BYPASSING = 0
) (
input clk,
input reset,
`ifdef RISCV_FORMAL
/* debug control in */
input intr_in,
/* debug data in */
input [31:0] next_pc_in,
input [31:0] instr_in,
/* debug control out */
output logic intr_out,
output logic [4:0] rs1_out,
output logic [4:0] rs2_out,
/* debug data out */
output logic [31:0] next_pc_out,
output logic [31:0] instr_out,
`endif
/* control in (from hazard) */
input stall_in,
input flush_in,
input mem_flush_in,
input writeback_flush_in,
/* control in */
input branch_predicted_taken_in,
input valid_in,
input exception_in,
input [3:0] exception_cause_in,
input [4:0] rs1_in,
input [4:0] rs2_in,
input [2:0] alu_op_in,
input alu_sub_sra_in,
input [1:0] alu_src1_in,
input [1:0] alu_src2_in,
input mem_read_in,
input mem_write_in,
input [1:0] mem_width_in,
input mem_zero_extend_in,
input mem_fence_in,
input csr_read_in,
input csr_write_in,
input [1:0] csr_write_op_in,
input csr_src_in,
input [1:0] branch_op_in,
input branch_pc_src_in,
input ecall_in,
input ebreak_in,
input mret_in,
input [4:0] rd_in,
input rd_write_in,
/* control in (from writeback) */
input [4:0] writeback_rd_in,
input writeback_rd_write_in,
/* data in */
input [31:0] pc_in,
input [31:0] rs1_value_in,
input [31:0] rs2_value_in,
input [31:0] imm_value_in,
input [11:0] csr_in,
/* data in (from writeback) */
input [31:0] writeback_rd_value_in,
/* control out */
output logic branch_predicted_taken_out,
output logic branch_misaligned_out,
output logic valid_out,
output logic exception_out,
output logic [3:0] exception_cause_out,
output logic mem_read_out,
output logic mem_write_out,
output logic [1:0] mem_width_out,
output logic mem_zero_extend_out,
output logic mem_fence_out,
output logic csr_read_out,
output logic csr_write_out,
output logic [1:0] csr_write_op_out,
output logic csr_src_out,
output logic [1:0] branch_op_out,
output logic ecall_out,
output logic ebreak_out,
output logic mret_out,
output logic [4:0] rd_out,
output logic rd_write_out,
/* data out */
output logic [31:0] pc_out,
output logic [31:0] result_out,
output logic [31:0] rs1_value_out,
output logic [31:0] rs2_value_out,
output logic [31:0] imm_value_out,
output logic [11:0] csr_out,
output logic [31:0] branch_pc_out
);
/* bypassing */
logic [31:0] rs1_value;
logic [31:0] rs2_value;
generate
if (BYPASSING) begin
always_comb begin
if (rd_write_out && !mem_flush_in && rd_out == rs1_in && |rs1_in)
rs1_value = result_out;
else if (writeback_rd_write_in && !writeback_flush_in && writeback_rd_in == rs1_in && |rs1_in)
rs1_value = writeback_rd_value_in;
else
rs1_value = rs1_value_in;
if (rd_write_out && !mem_flush_in && rd_out == rs2_in && |rs2_in)
rs2_value = result_out;
else if (writeback_rd_write_in && !writeback_flush_in && writeback_rd_in == rs2_in && |rs2_in)
rs2_value = writeback_rd_value_in;
else
rs2_value = rs2_value_in;
end
end else begin
assign rs1_value = rs1_value_in;
assign rs2_value = rs2_value_in;
end
endgenerate
/* ALU */
logic [31:0] alu_result;
rv32_alu alu (
/* control in */
.op_in(alu_op_in),
.sub_sra_in(alu_sub_sra_in),
.src1_in(alu_src1_in),
.src2_in(alu_src2_in),
/* data in */
.pc_in(pc_in),
.rs1_value_in(rs1_value),
.rs2_value_in(rs2_value),
.imm_value_in(imm_value_in),
/* data out */
.result_out(alu_result)
);
/* branch target calculation */
logic branch_misaligned;
logic [31:0] branch_pc;
rv32_branch_pc_mux branch_pc_mux (
/* control in */
.predicted_taken_in(branch_predicted_taken_in),
.pc_src_in(branch_pc_src_in),
/* data in */
.pc_in(pc_in),
.rs1_value_in(rs1_value),
.imm_value_in(imm_value_in),
/* control out */
.misaligned_out(branch_misaligned),
/* data out */
.pc_out(branch_pc)
);
always_ff @(posedge clk) begin
if (!stall_in) begin
`ifdef RISCV_FORMAL
intr_out <= intr_in;
next_pc_out <= next_pc_in;
rs1_out <= rs1_in;
rs2_out <= rs2_in;
instr_out <= instr_in;
`endif
branch_predicted_taken_out <= branch_predicted_taken_in;
branch_misaligned_out <= branch_misaligned;
valid_out <= valid_in;
exception_out <= exception_in;
exception_cause_out <= exception_cause_in;
mem_read_out <= mem_read_in;
mem_write_out <= mem_write_in;
mem_width_out <= mem_width_in;
mem_zero_extend_out <= mem_zero_extend_in;
mem_fence_out <= mem_fence_in;
csr_read_out <= csr_read_in;
csr_write_out <= csr_write_in;
csr_write_op_out <= csr_write_op_in;
csr_src_out <= csr_src_in;
branch_op_out <= branch_op_in;
ecall_out <= ecall_in;
ebreak_out <= ebreak_in;
mret_out <= mret_in;
rd_out <= rd_in;
rd_write_out <= rd_write_in;
pc_out <= pc_in;
rs1_value_out <= rs1_value;
rs2_value_out <= rs2_value;
imm_value_out <= imm_value_in;
csr_out <= csr_in;
branch_pc_out <= branch_pc;
result_out <= alu_result;
if (flush_in) begin
branch_predicted_taken_out <= 0;
valid_out <= 0;
exception_out <= 0;
mem_read_out <= 0;
mem_write_out <= 0;
csr_read_out <= 0;
csr_write_out <= 0;
branch_op_out <= `RV32_BRANCH_OP_NEVER;
ecall_out <= 0;
ebreak_out <= 0;
mret_out <= 0;
rd_write_out <= 0;
end
end
if (reset) begin
branch_predicted_taken_out <= 0;
valid_out <= 0;
exception_out <= 0;
mem_read_out <= 0;
mem_write_out <= 0;
mem_width_out <= 0;
mem_zero_extend_out <= 0;
mem_fence_out <= 0;
csr_read_out <= 0;
csr_write_out <= 0;
branch_op_out <= 0;
ecall_out <= 0;
ebreak_out <= 0;
mret_out <= 0;
rd_out <= 0;
rd_write_out <= 0;
rs2_value_out <= 0;
branch_pc_out <= 0;
result_out <= 0;
end
end
endmodule
`endif