Skip to content

Commit 9e4cd2f

Browse files
Merge pull request #830 from silabs-oysteink/silabs-oysteink_issue-675
Fix for issue #675.
2 parents 768f795 + b63cda8 commit 9e4cd2f

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

rtl/cv32e40x_controller_fsm.sv

+21-12
Original file line numberDiff line numberDiff line change
@@ -633,18 +633,27 @@ module cv32e40x_controller_fsm import cv32e40x_pkg::*;
633633
// to avoid more than one instructions passing down the pipe.
634634
ctrl_fsm_o.halt_if = single_step_halt_if_q;
635635

636-
// ID stage is halted for regular stalls (i.e. stalls for which the instruction
637-
// currently in ID is not ready to be issued yet). Also halted if interrupt or debug pending
638-
// but not allowed to be taken. This is to create an interruptible bubble in WB.
639-
// Interrupts: Machine mode: Prevent issuing new instructions until we get an interruptible bubble.
640-
// Debug mode: Interrupts are not allowed during debug. Cannot halt ID stage in such a case
641-
// since the dret that brings the core out of debug mode may never get past a halted ID stage.
642-
// Sequences: If we need to halt for debug or interrupt not allowed due to a sequence, we must check if we can
643-
// actually halt the ID stage or not. Halting the same sequence that causes *_allowed to go to 0
644-
// may cause a deadlock.
645-
ctrl_fsm_o.halt_id = ctrl_byp_i.jalr_stall || ctrl_byp_i.load_stall || ctrl_byp_i.csr_stall || ctrl_byp_i.wfi_wfe_stall || ctrl_byp_i.mnxti_id_stall ||
646-
(((pending_interrupt && !interrupt_allowed) || (pending_nmi && !nmi_allowed) || (pending_nmi_early)) && debug_interruptible && id_stage_haltable) ||
647-
(((pending_async_debug && !async_debug_allowed) ||(pending_sync_debug && !sync_debug_allowed)) && id_stage_haltable);
636+
// ID stage is halted when hazards are present (i.e. stalls for which the instruction currently in ID is not ready to be issued yet).
637+
//
638+
// In addition the ID stage may be halted to enable interrupts or debug to be taken.
639+
// - If an interrupt (including NMI) is present it is not guaranteed that the pipeline
640+
// can take the interrupt immediately. A LSU instruction could for instance be outstanding, causing the interrupt not to be taken.
641+
// The controller uses (pending_interrupt && interrupt_allowed) to check for these conditions.
642+
// When an interrupt (or NMI) is pending, the ID stage is halted to guarantee that an interruptible bubble eventually will
643+
// occur in the WB stage.
644+
// -- The ID stage is only halted iff debug_interruptible==1, indicating that we are not in debug mode or single step mode with interrupts disabled.
645+
// --- If halting for interrupts while in debug mode (debug_interruptible == 0), the core would deadlock waiting for interrupt_allowed, but the core
646+
// would never exit debug mode because the dret instruction could be blocked by the halted ID stage.
647+
// -- The ID stage is only halted iff also the ID stage is haltable (meaning ID stage is not currently in the middle of a sequence or waiting for a CLIC pointer)
648+
//
649+
// - The ID stage is halted when any async or sync debug is pending for the same reasons as for interrupts.
650+
//
651+
// - If not checking for id_stage_haltable for interrupts and debug, the core could end up in a situation where it tries to create a bubble
652+
// by halting ID, but the condition disallowing interrupt or debug will not disappear until the sequence currently handled by the ID stage
653+
// is done. This would create an unrecoverable deadlock.
654+
ctrl_fsm_o.halt_id = (ctrl_byp_i.jalr_stall || ctrl_byp_i.load_stall || ctrl_byp_i.csr_stall || ctrl_byp_i.wfi_wfe_stall || ctrl_byp_i.mnxti_id_stall) ||
655+
((pending_interrupt || pending_nmi || pending_nmi_early) && debug_interruptible && id_stage_haltable) ||
656+
((pending_async_debug || pending_sync_debug) && id_stage_haltable);
648657

649658

650659
// Halting EX if minstret_stall occurs. Otherwise we would read the wrong minstret value

0 commit comments

Comments
 (0)