@@ -291,6 +291,7 @@ module ibex_id_stage #(
291
291
logic data_req_allowed;
292
292
293
293
// CSR control
294
+ logic no_flush_csr_addr;
294
295
logic csr_pipe_flush;
295
296
296
297
logic [31 : 0 ] alu_operand_a;
@@ -511,36 +512,20 @@ module ibex_id_stage #(
511
512
.branch_in_dec_o (branch_in_dec)
512
513
);
513
514
514
- // ///////////////////////////////
515
- // CSR-related pipeline flushes //
516
- // ///////////////////////////////
517
- always_comb begin : csr_pipeline_flushes
518
- csr_pipe_flush = 1'b0 ;
519
-
520
- // A pipeline flush is needed to let the controller react after modifying certain CSRs:
521
- // - When enabling interrupts, pending IRQs become visible to the controller only during
522
- // the next cycle. If during that cycle the core disables interrupts again, it does not
523
- // see any pending IRQs and consequently does not start to handle interrupts.
524
- // - When modifying any PMP CSR, PMP check of the next instruction might get invalidated.
525
- // Hence, a pipeline flush is needed to instantiate another PMP check with the updated CSRs.
526
- // - When modifying debug CSRs.
527
- if (csr_op_en_o == 1'b1 && (csr_op_o == CSR_OP_WRITE || csr_op_o == CSR_OP_SET )) begin
528
- if (csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_MSTATUS ||
529
- csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_MIE ||
530
- csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_MSECCFG ||
531
- // To catch all PMPCFG/PMPADDR registers, get the shared top most 7 bits.
532
- instr_rdata_i[31 : 25 ] == 7'h1D ) begin
533
- csr_pipe_flush = 1'b1 ;
534
- end
535
- end else if (csr_op_en_o == 1'b1 && csr_op_o != CSR_OP_READ ) begin
536
- if (csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_DCSR ||
537
- csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_DPC ||
538
- csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_DSCRATCH0 ||
539
- csr_num_e ' (instr_rdata_i[31 : 20 ]) == CSR_DSCRATCH1 ) begin
540
- csr_pipe_flush = 1'b1 ;
541
- end
542
- end
543
- end
515
+ // Flush pipe on most CSR modification. Some CSR modifications alter how instructions execute
516
+ // (e.g. the PMP CSRs) so this ensures all instructions always see the latest architectural state
517
+ // when entering the fetch stage. This causes some needless flushes but performance impact is
518
+ // limited. We have a single fetch stage to flush not many stages of a deep pipeline and CSR
519
+ // instructions are in general rare and not part of performance critical parts of the code.
520
+ //
521
+ // No flush is triggered for a small number of specific CSRs. These are ones that have been
522
+ // specifically identified to be a) likely to be modifed in exception handlers and b) safe to
523
+ // alter without a flush.
524
+ assign no_flush_csr_addr = csr_addr_o inside { CSR_MSCRATCH , CSR_MEPC } ;
525
+
526
+ assign csr_pipe_flush = (csr_op_en_o == 1 ) &&
527
+ (csr_op_o inside { CSR_OP_WRITE , CSR_OP_SET , CSR_OP_CLEAR } ) &&
528
+ ! no_flush_csr_addr;
544
529
545
530
// //////////////
546
531
// Controller //
0 commit comments