@@ -172,8 +172,10 @@ module csr_regfile
172
172
output rvfi_probes_csr_t rvfi_csr_o,
173
173
// jvt output
174
174
output jvt_t jvt_o,
175
- // action 0 request from trigger module
176
- output logic breakpoint_from_tigger_module_o
175
+ // trigger request from trigger module
176
+ output logic breakpoint_from_tigger_module_o,
177
+ input logic [CVA6Cfg.VLEN - 1 : 0 ] vaddr_from_lsu_i,
178
+ input logic [CVA6Cfg.NrIssuePorts- 1 : 0 ][31 : 0 ] orig_instr_i
177
179
);
178
180
179
181
localparam logic [63 : 0 ] SMODE_STATUS_READ_MASK = ariane_pkg :: smode_status_read_mask (CVA6Cfg);
@@ -295,8 +297,9 @@ module csr_regfile
295
297
logic breakpoint_from_tigger_module;
296
298
logic in_trap_handler;
297
299
logic prev_csr_write;
300
+ logic matched;
298
301
// icount64_tdata1_t icount64_tdata1;
299
-
302
+ mcontrol6_32_tdata1_t mcontrol6_32_tdata1_q[N_Triggers], mcontrol6_32_tdata1_d[N_Triggers];
300
303
301
304
localparam logic [CVA6Cfg.XLEN - 1 : 0 ] IsaCode = (CVA6Cfg.XLEN ' (CVA6Cfg.RVA ) << 0 ) // A - Atomic Instructions extension
302
305
| (CVA6Cfg.XLEN ' (CVA6Cfg.RVB ) << 1 ) // B - Bitmanip extension
@@ -412,6 +415,8 @@ module csr_regfile
412
415
if (CVA6Cfg.SDTRIG ) begin
413
416
if (trigger_type_q[tselect_q] == 4'd3 )
414
417
csr_rdata = icount32_tdata1_q[tselect_q]; // tdata1 based on type and indexed by tselect
418
+ end else if (trigger_type_q[tselect_q] == 4'd6 ) begin
419
+ csr_rdata = mcontrol6_32_tdata1_q[tselect_q]; // tdata1 based on type and indexed by tselect
415
420
end else begin
416
421
read_access_exception = 1'b1 ;
417
422
end
@@ -1160,6 +1165,29 @@ module csr_regfile
1160
1165
icount32_tdata1_d[tselect_q].u = csr_wdata[6 ];
1161
1166
icount32_tdata1_d[tselect_q].action = csr_wdata[5 : 0 ];
1162
1167
flush_o = 1'b1 ;
1168
+ end else if (csr_wdata[31 : 28 ] == 4'd6 && CVA6Cfg.XLEN == 32 ) begin
1169
+ trigger_type_d[tselect_q] = csr_wdata[31 : 28 ];
1170
+ mcontrol6_32_tdata1_d[tselect_q].t_type = (csr_wdata[31 : 28 ] == 4'd3 || csr_wdata[31 : 28 ] == 4'd4 || csr_wdata[31 : 28 ] == 4'd5 || csr_wdata[31 : 28 ] == 4'd6 || csr_wdata[31 : 28 ] == 4'd15 ) ? csr_wdata[31 : 28 ] : trigger_type_q[tselect_q];
1171
+ mcontrol6_32_tdata1_d[tselect_q].dmode = csr_wdata[27 ];
1172
+ mcontrol6_32_tdata1_d[tselect_q].uncertain = 0 ;
1173
+ mcontrol6_32_tdata1_d[tselect_q].hit1 = csr_wdata[25 ];
1174
+ mcontrol6_32_tdata1_d[tselect_q].vs = 0 ;
1175
+ mcontrol6_32_tdata1_d[tselect_q].vu = 0 ;
1176
+ mcontrol6_32_tdata1_d[tselect_q].hit0 = csr_wdata[22 ];
1177
+ mcontrol6_32_tdata1_d[tselect_q].select = csr_wdata[21 ];
1178
+ mcontrol6_32_tdata1_d[tselect_q].zeroes = '0 ;
1179
+ mcontrol6_32_tdata1_d[tselect_q].size = csr_wdata[18 : 16 ];
1180
+ mcontrol6_32_tdata1_d[tselect_q].action = csr_wdata[15 : 12 ];
1181
+ mcontrol6_32_tdata1_d[tselect_q].chain = 0 ;
1182
+ mcontrol6_32_tdata1_d[tselect_q].match = csr_wdata[10 : 7 ];
1183
+ mcontrol6_32_tdata1_d[tselect_q].m = csr_wdata[6 ];
1184
+ mcontrol6_32_tdata1_d[tselect_q].uncertainen = 0 ;
1185
+ mcontrol6_32_tdata1_d[tselect_q].s = csr_wdata[4 ];
1186
+ mcontrol6_32_tdata1_d[tselect_q].u = csr_wdata[3 ];
1187
+ mcontrol6_32_tdata1_d[tselect_q].execute = csr_wdata[2 ];
1188
+ mcontrol6_32_tdata1_d[tselect_q].store = csr_wdata[1 ];
1189
+ mcontrol6_32_tdata1_d[tselect_q].load = csr_wdata[0 ];
1190
+ flush_o = 1'b1 ;
1163
1191
end
1164
1192
end else begin
1165
1193
update_access_exception = 1'b1 ;
@@ -1173,16 +1201,16 @@ module csr_regfile
1173
1201
riscv :: CSR_TDATA3 :
1174
1202
if (CVA6Cfg.SDTRIG ) begin
1175
1203
if (CVA6Cfg.XLEN == 32 ) begin // textra32
1176
- textra32_tdata3_d[tselect_q].mhvalue = csr_wdata[ 31 : 26 ] ;
1177
- textra32_tdata3_d[tselect_q].mhselect = csr_wdata[ 25 : 23 ] ;
1204
+ textra32_tdata3_d[tselect_q].mhvalue = '0 ;
1205
+ textra32_tdata3_d[tselect_q].mhselect = '0 ;
1178
1206
textra32_tdata3_d[tselect_q].zeroes = '0 ;
1179
1207
textra32_tdata3_d[tselect_q].sbytemask = csr_wdata[19 : 18 ];
1180
1208
textra32_tdata3_d[tselect_q].svalue = csr_wdata[17 : 2 ];
1181
1209
textra32_tdata3_d[tselect_q].sselect = csr_wdata[1 : 0 ];
1182
1210
end
1183
1211
if (CVA6Cfg.XLEN == 64 ) begin // textra64
1184
- textra64_tdata3_d[tselect_q].mhvalue = csr_wdata[ 63 : 51 ] ;
1185
- textra64_tdata3_d[tselect_q].mhselect = csr_wdata[ 50 : 48 ] ;
1212
+ textra64_tdata3_d[tselect_q].mhvalue = '0 ;
1213
+ textra64_tdata3_d[tselect_q].mhselect = '0 ;
1186
1214
textra64_tdata3_d[tselect_q].zeroes = '0 ;
1187
1215
textra64_tdata3_d[tselect_q].sbytemask = csr_wdata[39 : 36 ];
1188
1216
textra64_tdata3_d[tselect_q].zero_field = '0 ;
@@ -2285,35 +2313,73 @@ module csr_regfile
2285
2313
end
2286
2314
end
2287
2315
2288
- // Triggers Match Logic
2316
+ // Triggers Match Logic
2289
2317
if (CVA6Cfg.SDTRIG ) begin
2290
- if (trigger_type_d[tselect_q] == 4'd3 ) begin // icount match logic
2291
- case (priv_lvl_o) // trigger will only fire if current priv lvl is same as the trigger wants to fire in
2292
- riscv :: PRIV_LVL_M : if (icount32_tdata1_d[tselect_q].m) priv_match = 1'b1 ;
2293
- riscv :: PRIV_LVL_S : if (icount32_tdata1_d[tselect_q].s) priv_match = 1'b1 ;
2294
- riscv :: PRIV_LVL_U : if (icount32_tdata1_d[tselect_q].u) priv_match = 1'b1 ;
2295
- default : priv_match = 1'b0 ;
2296
- endcase
2297
- if (ex_i.valid) begin
2298
- in_trap_handler = 1'b1 ;
2299
- icount32_tdata1_d[tselect_q].count = icount32_tdata1_d[tselect_q].count - 1 ;
2300
- end
2301
- if (commit_ack_i && mret) in_trap_handler = 1'b0 ;
2302
- if (| commit_ack_i && ! in_trap_handler && icount32_tdata1_q[tselect_q].count != 0 ) begin
2303
- icount32_tdata1_d[tselect_q].count = icount32_tdata1_d[tselect_q].count - 1 ;
2304
- end
2305
- if ((icount32_tdata1_d[tselect_q].count == 0 ) && priv_match) begin
2306
- icount32_tdata1_d[tselect_q].pending = 1'b1 ;
2307
- // icount32_tdata1_d[tselect_q].hit = 1'b1;
2308
- case (icount32_tdata1_d[tselect_q].action)
2309
- 6'd0 : breakpoint_from_tigger_module = 1'b1 ;
2310
- 6'd1 : breakpoint_from_tigger_module = 1'b1 ; // into debug mode;
2311
- default : ;
2312
- endcase
2313
- end
2318
+ // icount match logic
2319
+ if (trigger_type_d[tselect_q] == 4'd3 ) begin
2320
+ case (priv_lvl_o) // trigger will only fire if current priv lvl is same as the trigger configuration
2321
+ riscv :: PRIV_LVL_M : if (icount32_tdata1_d[tselect_q].m) priv_match = 1'b1 ;
2322
+ riscv :: PRIV_LVL_S : if (icount32_tdata1_d[tselect_q].s) priv_match = 1'b1 ;
2323
+ riscv :: PRIV_LVL_U : if (icount32_tdata1_d[tselect_q].u) priv_match = 1'b1 ;
2324
+ default : priv_match = 1'b0 ;
2325
+ endcase
2326
+ if (ex_i.valid) begin
2327
+ in_trap_handler = 1'b1 ;
2328
+ icount32_tdata1_d[tselect_q].count = icount32_tdata1_d[tselect_q].count - 1 ;
2329
+ end
2330
+ if (commit_ack_i && mret) in_trap_handler = 1'b0 ;
2331
+ if (| commit_ack_i && ! in_trap_handler && icount32_tdata1_q[tselect_q].count != 0 ) begin
2332
+ icount32_tdata1_d[tselect_q].count = icount32_tdata1_d[tselect_q].count - 1 ;
2333
+ end
2334
+ if ((icount32_tdata1_d[tselect_q].count == 0 ) && priv_match) begin
2335
+ icount32_tdata1_d[tselect_q].pending = 1'b1 ;
2336
+ case (icount32_tdata1_d[tselect_q].action)
2337
+ // 6'd0 : breakpoint_from_tigger_module = 1'b1; //breakpoint
2338
+ 6'd1 : breakpoint_from_tigger_module = 1'b1 ; // into debug mode;
2339
+ default : breakpoint_from_tigger_module = 1'b0 ;
2340
+ endcase
2341
+ end
2342
+ if (debug_mode_d && icount32_tdata1_d[tselect_q].pending) begin
2343
+ icount32_tdata1_d[tselect_q].pending = 1'b0 ;
2344
+ icount32_tdata1_d[tselect_q].hit = 1'b1 ;
2345
+ breakpoint_from_tigger_module = 1'b0 ;
2346
+ end
2347
+ end
2348
+ // mcontrol6 match logic
2349
+ if (trigger_type_d[tselect_q] == 4'd6 ) begin
2350
+ case (priv_lvl_o) // trigger will only fire if current priv lvl is same as the trigger configuration
2351
+ riscv :: PRIV_LVL_M : if (mcontrol6_32_tdata1_d[tselect_q].m) priv_match = 1'b1 ;
2352
+ riscv :: PRIV_LVL_S : if (mcontrol6_32_tdata1_d[tselect_q].s) priv_match = 1'b1 ;
2353
+ riscv :: PRIV_LVL_U : if (mcontrol6_32_tdata1_d[tselect_q].u) priv_match = 1'b1 ;
2354
+ default : priv_match = 1'b0 ;
2355
+ endcase
2356
+ // execute with address
2357
+ if (mcontrol6_32_tdata1_d[tselect_q].execute && tdata2_d[tselect_q] == commit_instr_i.pc && commit_ack_i && ! mcontrol6_32_tdata1_d[tselect_q].select) matched = 1'b1 ;
2358
+ // execute with instruction
2359
+ if (mcontrol6_32_tdata1_d[tselect_q].execute && mcontrol6_32_tdata1_d[tselect_q].select && (tdata2_d[tselect_q] == orig_instr_i)) matched = 1'b1 ;
2360
+ // store with data
2361
+ if (mcontrol6_32_tdata1_d[tselect_q].store && mcontrol6_32_tdata1_d[tselect_q].select && (tdata2_d[tselect_q] == commit_instr_i.result)) matched = 1'b1 ;
2362
+ // store with address
2363
+ if (mcontrol6_32_tdata1_d[tselect_q].store && ! mcontrol6_32_tdata1_d[tselect_q].select && (tdata2_d[tselect_q] == vaddr_from_lsu_i)) matched = 1'b1 ;
2364
+ // load with data
2365
+ if (mcontrol6_32_tdata1_d[tselect_q].load && mcontrol6_32_tdata1_d[tselect_q].select && (tdata2_d[tselect_q] == commit_instr_i.result && commit_instr_i.op == 8'h27 )) matched = 1'b1 ;
2366
+ // load with address
2367
+ if (mcontrol6_32_tdata1_d[tselect_q].load && ! mcontrol6_32_tdata1_d[tselect_q].select && (tdata2_d[tselect_q] == vaddr_from_lsu_i)) matched = 1'b1 ;
2368
+ if (priv_match && matched) begin
2369
+ case (mcontrol6_32_tdata1_d[tselect_q].action)
2370
+ // 6'd0 : breakpoint_from_tigger_module = 1'b1; //breakpoint
2371
+ 6'd1 : breakpoint_from_tigger_module = 1'b1 ; // into debug mode;
2372
+ default : breakpoint_from_tigger_module = 1'b0 ;
2373
+ endcase
2374
+ end
2375
+ if (debug_mode_d && matched) begin
2376
+ matched = 1'b0 ;
2377
+ mcontrol6_32_tdata1_d[tselect_q].hit0 = 1'b0 ;
2378
+ mcontrol6_32_tdata1_d[tselect_q].hit1 = 1'b1 ;
2379
+ breakpoint_from_tigger_module = 1'b0 ;
2314
2380
end
2381
+ end
2315
2382
end
2316
-
2317
2383
end
2318
2384
2319
2385
// ---------------------------
@@ -2748,10 +2814,12 @@ module csr_regfile
2748
2814
scontext_q <= '0 ;
2749
2815
tselect_q <= '0 ;
2750
2816
prev_csr_write <= 1'b0 ;
2817
+ matched <= 1'b0 ;
2751
2818
for (int i = 0 ; i < N_Triggers; ++ i) begin
2752
2819
trigger_type_q[i] <= '0 ;
2753
2820
icount32_tdata1_q[i] <= '0 ;
2754
2821
icount32_tdata1_q[i].count <= 1 ;
2822
+ mcontrol6_32_tdata1_q[i] <= '0 ;
2755
2823
textra32_tdata3_q[i] <= '0 ;
2756
2824
textra64_tdata3_q[i] <= '0 ;
2757
2825
tdata2_q[i] <= '0 ;
@@ -2843,14 +2911,15 @@ module csr_regfile
2843
2911
en_ld_st_g_translation_q <= en_ld_st_g_translation_d;
2844
2912
end
2845
2913
if (CVA6Cfg.SDTRIG ) begin
2846
- trigger_type_q <= trigger_type_d;
2847
- tselect_q <= tselect_d;
2848
- tdata2_q <= tdata2_d;
2849
- icount32_tdata1_q <= icount32_tdata1_d;
2850
- textra32_tdata3_q <= textra32_tdata3_d;
2851
- textra64_tdata3_q <= textra64_tdata3_d;
2852
- scontext_q <= scontext_d;
2853
- prev_csr_write <= breakpoint_from_tigger_module;
2914
+ trigger_type_q <= trigger_type_d;
2915
+ tselect_q <= tselect_d;
2916
+ tdata2_q <= tdata2_d;
2917
+ icount32_tdata1_q <= icount32_tdata1_d;
2918
+ mcontrol6_32_tdata1_q <= mcontrol6_32_tdata1_d;
2919
+ textra32_tdata3_q <= textra32_tdata3_d;
2920
+ textra64_tdata3_q <= textra64_tdata3_d;
2921
+ scontext_q <= scontext_d;
2922
+ prev_csr_write <= breakpoint_from_tigger_module;
2854
2923
end
2855
2924
// timer and counters
2856
2925
cycle_q <= cycle_d;
0 commit comments