-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwb_stage.v
319 lines (288 loc) · 12 KB
/
wb_stage.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
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
`include "mycpu.h"
`include "csr.h"
module wb_stage(
input clk ,
input reset ,
//allowin
output ws_allowin ,
//from ms
input ms_to_ws_valid ,
input [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus ,
//to rf: for write back
output [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus ,
//to ds
output ws_to_ds_valid ,
//exception
output [31:0] csr_era ,
output [ 8:0] csr_esubcode ,
output [ 5:0] csr_ecode ,
output excp_flush ,
output ertn_flush ,
output refetch_flush ,
output icacop_flush ,
output csr_wr_en ,
output [13:0] wr_csr_addr ,
output [31:0] wr_csr_data ,
output va_error ,
output [31:0] bad_va ,
output excp_tlbrefill ,
output excp_tlb ,
output [18:0] excp_tlb_vppn ,
//idle
output idle_flush ,
//llbit
output ws_llbit_set ,
output ws_llbit ,
output ws_lladdr_set ,
output [27:0] ws_lladdr ,
//tlb ins
output tlb_inst_stall ,
output tlbsrch_en ,
output tlbsrch_found ,
output [ 4:0] tlbsrch_index ,
output tlbfill_en ,
output tlbwr_en ,
output tlbrd_en ,
output invtlb_en ,
output [ 9:0] invtlb_asid ,
output [18:0] invtlb_vpn ,
output [ 4:0] invtlb_op ,
//to perf_counter
output real_valid ,
output real_br_inst ,
output real_icache_miss ,
output real_dcache_miss ,
output real_mem_inst ,
output real_br_pre ,
output real_br_pre_error ,
//debug
output debug_ws_valid ,
input debug_break_point ,
//trace debug interface
output [31:0] debug_wb_pc ,
output [ 3:0] debug_wb_rf_wen ,
output [ 4:0] debug_wb_rf_wnum ,
output [31:0] debug_wb_rf_wdata ,
output [31:0] debug_wb_inst ,
// difftest
output ws_valid_diff ,
output ws_cnt_inst_diff ,
output [63:0] ws_timer_64_diff ,
output [ 7:0] ws_inst_ld_en_diff ,
output [31:0] ws_ld_paddr_diff ,
output [31:0] ws_ld_vaddr_diff ,
output [ 7:0] ws_inst_st_en_diff ,
output [31:0] ws_st_paddr_diff ,
output [31:0] ws_st_vaddr_diff ,
output [31:0] ws_st_data_diff ,
output ws_csr_rstat_en_diff ,
output [31:0] ws_csr_data_diff
);
reg ws_valid;
wire ws_ready_go;
wire flush_sign;
reg [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r;
wire ws_gr_we;
wire ws_excp;
wire [15:0] ws_excp_num;
wire ws_ertn;
wire [ 4:0] ws_dest;
wire [31:0] ws_final_result;
wire [31:0] ws_pc;
wire [31:0] ws_csr_result;
wire [13:0] ws_csr_idx;
wire ws_csr_we;
wire ws_ll_w;
wire ws_sc_w;
wire [31:0] ws_error_va;
wire ws_tlbsrch;
wire ws_tlbfill;
wire ws_tlbwr;
wire ws_tlbrd;
wire ws_refetch;
wire ws_invtlb;
wire ws_icacop_op_en;
wire ws_br_inst;
wire ws_icache_miss;
wire ws_access_mem;
wire ws_dcache_miss;
wire ws_br_pre;
wire ws_br_pre_error;
wire ws_idle;
wire [31:0] ws_paddr;
wire ws_data_uc;
// difftest
wire [31:0] ws_inst ;
wire ws_cnt_inst ;
wire [63:0] ws_timer_64 ;
wire [ 7:0] ws_inst_ld_en ;
wire [31:0] ws_ld_paddr ;
wire [31:0] ws_ld_vaddr ;
wire [ 7:0] ws_inst_st_en ;
wire [31:0] ws_st_data ;
wire ws_csr_rstat_en ;
wire [31:0] ws_csr_data ;
assign {ws_csr_data , //492:461 for difftest
ws_csr_rstat_en, //460:460 for difftest
ws_st_data , //459:428 for difftest
ws_inst_st_en , //427:420 for difftest
ws_ld_vaddr , //419:388 for difftest
ws_ld_paddr , //387:356 for difftest
ws_inst_ld_en , //355:348 for difftest
ws_cnt_inst , //347:347 for difftest
ws_timer_64 , //346:283 for difftest
ws_inst , //282:251 for difftest
ws_data_uc , //250:250
ws_paddr , //249:218
ws_idle , //217:217
ws_br_pre_error, //216:216
ws_br_pre , //215:215
ws_dcache_miss , //214:214
ws_access_mem , //213:213
ws_icache_miss , //212:212
ws_br_inst , //211:211
ws_icacop_op_en, //210:210
invtlb_vpn , //209:191
invtlb_asid , //190:181
ws_invtlb , //180:180
ws_tlbrd , //179:179
ws_refetch , //178:178
ws_tlbfill , //177:177
ws_tlbwr , //176:176
tlbsrch_index , //175:171
tlbsrch_found , //170:170
ws_tlbsrch , //169:169
ws_error_va , //168:137
ws_sc_w , //136:136
ws_ll_w , //135:135
ws_excp_num , //134:119
ws_csr_we , //118:118
ws_csr_idx , //117:104
ws_csr_result , //103:72
ws_ertn , //71:71
ws_excp , //70:70
ws_gr_we , //69:69
ws_dest , //68:64
ws_final_result, //63:32
ws_pc //31:0
} = ms_to_ws_bus_r;
assign ws_to_ds_valid = ws_valid;
assign flush_sign = excp_flush || ertn_flush || refetch_flush || icacop_flush || idle_flush;
wire rf_we;
wire [4 :0] rf_waddr;
wire [31:0] rf_wdata;
assign ws_to_rf_bus = {rf_we , //37:37
rf_waddr, //36:32
rf_wdata //31:0
};
assign ws_ready_go = ~debug_break_point;
assign ws_allowin = !ws_valid || ws_ready_go;
always @(posedge clk) begin
if (reset || flush_sign) begin
ws_valid <= 1'b0;
end
else if (ws_allowin) begin
ws_valid <= ms_to_ws_valid;
end
if (ms_to_ws_valid && ws_allowin) begin
ms_to_ws_bus_r <= ms_to_ws_bus;
end
end
assign real_br_inst = ws_br_inst && real_valid;
assign real_icache_miss = ws_icache_miss && real_valid;
assign real_dcache_miss = ws_dcache_miss && real_valid;
assign real_mem_inst = ws_access_mem && real_valid;
assign real_br_pre = ws_br_pre && real_valid;
assign real_br_pre_error = ws_br_pre_error && real_valid;
assign real_valid = ws_valid & ~ws_excp; //ws valid and no exception
assign rf_we = ws_gr_we & real_valid;
assign rf_waddr = ws_dest;
assign rf_wdata = ws_final_result;
assign excp_flush = ws_excp & ws_valid;
assign ertn_flush = ws_ertn & real_valid;
assign refetch_flush = (ws_csr_we || ((ws_ll_w || ws_sc_w) && !ws_excp) || ws_refetch) && ws_valid;
assign csr_era = ws_pc;
assign csr_wr_en = ws_csr_we && real_valid;
assign wr_csr_addr = ws_csr_idx;
assign wr_csr_data = ws_csr_result;
assign icacop_flush = ws_icacop_op_en && ws_valid;
assign idle_flush = ws_idle && real_valid;
assign tlb_inst_stall = (ws_tlbsrch || ws_tlbrd) && ws_valid;
//tlb ins
assign {tlbsrch_en ,
tlbwr_en ,
tlbfill_en ,
tlbrd_en ,
invtlb_en } = {ws_tlbsrch ,
ws_tlbwr ,
ws_tlbfill ,
ws_tlbrd ,
ws_invtlb } & {5{real_valid}};
//llbit
assign ws_llbit_set = (ws_ll_w | ws_sc_w) & real_valid;
assign ws_llbit = ((ws_ll_w&&!ws_data_uc) & 1'b1) | (ws_sc_w & 1'b0);
assign ws_lladdr_set = ws_ll_w && !ws_data_uc && real_valid;
assign ws_lladdr = ws_paddr[31:4];
/*
excp_num[0] int
[1] adef
[2] tlbr |inst tlb exceptions
[3] pif |
[4] ppi |
[5] syscall
[6] brk
[7] ine
[8] ipe
[9] ale
[10] <null>
[11] tlbr |
[12] pme |data tlb exceptions
[13] ppi |
[14] pis |
[15] pil |
*/
//exception have piority, onle one exception is valid
assign {csr_ecode,
va_error,
bad_va,
csr_esubcode,
excp_tlbrefill,
excp_tlb,
excp_tlb_vppn} = ws_excp_num[ 0] ? {`ECODE_INT , 1'b0 , 32'b0 , 9'b0 , 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[ 1] ? {`ECODE_ADEF, ws_valid, ws_pc , `ESUBCODE_ADEF, 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[ 2] ? {`ECODE_TLBR, ws_valid, ws_pc , 9'b0 , ws_valid, ws_valid, ws_pc[31:13] } :
ws_excp_num[ 3] ? {`ECODE_PIF , ws_valid, ws_pc , 9'b0 , 1'b0 , ws_valid, ws_pc[31:13] } :
ws_excp_num[ 4] ? {`ECODE_PPI , ws_valid, ws_pc , 9'b0 , 1'b0 , ws_valid, ws_pc[31:13] } :
ws_excp_num[ 5] ? {`ECODE_SYS , 1'b0 , 32'b0 , 9'b0 , 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[ 6] ? {`ECODE_BRK , 1'b0 , 32'b0 , 9'b0 , 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[ 7] ? {`ECODE_INE , 1'b0 , 32'b0 , 9'b0 , 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[ 8] ? {`ECODE_IPE , 1'b0 , 32'b0 , 9'b0 , 1'b0 , 1'b0 , 19'b0 } : //close ipe excp now
ws_excp_num[ 9] ? {`ECODE_ALE , ws_valid, ws_error_va, 9'b0 , 1'b0 , 1'b0 , 19'b0 } :
ws_excp_num[11] ? {`ECODE_TLBR, ws_valid, ws_error_va, 9'b0 , ws_valid, ws_valid, ws_error_va[31:13]} :
ws_excp_num[12] ? {`ECODE_PME , ws_valid, ws_error_va, 9'b0 , 1'b0 , ws_valid, ws_error_va[31:13]} :
ws_excp_num[13] ? {`ECODE_PPI , ws_valid, ws_error_va, 9'b0 , 1'b0 , ws_valid, ws_error_va[31:13]} :
ws_excp_num[14] ? {`ECODE_PIS , ws_valid, ws_error_va, 9'b0 , 1'b0 , ws_valid, ws_error_va[31:13]} :
ws_excp_num[15] ? {`ECODE_PIL , ws_valid, ws_error_va, 9'b0 , 1'b0 , ws_valid, ws_error_va[31:13]} :
69'b0;
//invtlb ins
assign invtlb_op = ws_dest;
// debug info generate
assign debug_wb_pc = ws_pc;
assign debug_wb_rf_wen = {4{rf_we}};
assign debug_wb_rf_wnum = ws_dest;
assign debug_wb_rf_wdata = ws_final_result;
assign debug_wb_inst = ws_inst;
assign debug_ws_valid = ws_valid;
assign ws_valid_diff = real_valid ;
assign ws_timer_64_diff = ws_timer_64 ;
assign ws_cnt_inst_diff = ws_cnt_inst ;
assign ws_inst_ld_en_diff = ws_inst_ld_en ;
assign ws_ld_paddr_diff = ws_ld_paddr ;
assign ws_ld_vaddr_diff = ws_ld_vaddr ;
assign ws_inst_st_en_diff = ws_inst_st_en ;
assign ws_st_paddr_diff = ws_ld_paddr_diff ;
assign ws_st_vaddr_diff = ws_ld_vaddr_diff ;
assign ws_st_data_diff = ws_st_data ;
assign ws_csr_rstat_en_diff = ws_csr_rstat_en ;
assign ws_csr_data_diff = ws_csr_data ;
endmodule