forked from Github_Repos/cvw
WFI terminates when an interrupt is pending even if interrupts are globally disabled
This commit is contained in:
parent
412d4656ed
commit
a516f89f22
@ -38,7 +38,7 @@ module hazard(
|
||||
(* mark_debug = "true" *) input logic FPUStallD, FStallD,
|
||||
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
||||
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
||||
(* mark_debug = "true" *) input logic InvalidateICacheM, wfiM,
|
||||
(* mark_debug = "true" *) input logic InvalidateICacheM, wfiM, IntPendingM,
|
||||
// Stall & flush outputs
|
||||
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
|
||||
(* mark_debug = "true" *) output logic FlushF, FlushD, FlushE, FlushM, FlushW
|
||||
@ -61,9 +61,11 @@ module hazard(
|
||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||
|
||||
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
||||
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE); // stall in decode if instruction is a load/mul/csr dependent on previous
|
||||
// stall in decode if instruction is a load/mul/csr dependent on previous
|
||||
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
|
||||
assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM);
|
||||
assign StallMCause = wfiM & ~TrapM;
|
||||
// WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap
|
||||
assign StallMCause = wfiM & (~TrapM & ~IntPendingM);
|
||||
assign StallWCause = LSUStallM | IFUStallF;
|
||||
|
||||
assign StallF = StallFCause | StallD;
|
||||
|
@ -78,7 +78,7 @@ module privileged (
|
||||
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||
output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||
output logic [2:0] FRM_REGW,
|
||||
output logic BreakpointFaultM, EcallFaultM, wfiM
|
||||
output logic BreakpointFaultM, EcallFaultM, wfiM, IntPendingM
|
||||
);
|
||||
|
||||
logic [1:0] NextPrivilegeModeM;
|
||||
@ -226,7 +226,7 @@ module privileged (
|
||||
.InstrM,
|
||||
.InstrValidM, .CommittedM, .DivE,
|
||||
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
|
||||
.InterruptM,
|
||||
.InterruptM, .IntPendingM,
|
||||
.ExceptionM,
|
||||
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
|
||||
endmodule
|
||||
|
@ -48,7 +48,7 @@ module trap (
|
||||
input logic [31:0] InstrM,
|
||||
input logic InstrValidM, CommittedM, DivE,
|
||||
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||
output logic InterruptM,
|
||||
output logic InterruptM, IntPendingM,
|
||||
output logic ExceptionM,
|
||||
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
@ -56,7 +56,7 @@ module trap (
|
||||
);
|
||||
|
||||
logic MIntGlobalEnM, SIntGlobalEnM;
|
||||
(* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;
|
||||
(* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM, MValidIntsM, SValidIntsM;
|
||||
//logic InterruptM;
|
||||
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
|
||||
logic Exception1M;
|
||||
@ -65,13 +65,16 @@ module trap (
|
||||
// interrupt if any sources are pending
|
||||
// & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage)
|
||||
// & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice
|
||||
// MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
|
||||
// MValidIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
|
||||
// Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i]
|
||||
assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9
|
||||
assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9
|
||||
assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW;
|
||||
assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW;
|
||||
assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
|
||||
assign MPendingIntsM = MIP_REGW & MIE_REGW;
|
||||
assign SPendingIntsM = SIP_REGW & SIE_REGW;
|
||||
assign IntPendingM = |MPendingIntsM;
|
||||
assign MValidIntsM = {12{MIntGlobalEnM}} & MPendingIntsM & ~MIDELEG_REGW;
|
||||
assign SValidIntsM = {12{SIntGlobalEnM}} & SPendingIntsM;
|
||||
assign InterruptM = (|MValidIntsM || |SValidIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
|
||||
|
||||
// Trigger Traps and RET
|
||||
// According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous.
|
||||
@ -119,15 +122,15 @@ module trap (
|
||||
// Exceptions are of lower priority than all interrupts (3.1.9)
|
||||
always_comb
|
||||
if (reset) CauseM = 0; // hard reset 3.3
|
||||
else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
|
||||
else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
|
||||
else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
|
||||
else if (MPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode
|
||||
else if (MPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode
|
||||
else if (MPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by M-mode
|
||||
else if (SPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by S-mode
|
||||
else if (SPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by S-mode
|
||||
else if (SPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode
|
||||
else if (MValidIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
|
||||
else if (MValidIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
|
||||
else if (MValidIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
|
||||
else if (MValidIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode
|
||||
else if (MValidIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode
|
||||
else if (MValidIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by M-mode
|
||||
else if (SValidIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by S-mode
|
||||
else if (SValidIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by S-mode
|
||||
else if (SValidIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode
|
||||
else if (InstrPageFaultM) CauseM = 12;
|
||||
else if (InstrAccessFaultM) CauseM = 1;
|
||||
else if (IllegalInstrFaultM) CauseM = 2;
|
||||
|
@ -112,7 +112,7 @@ module wallypipelinedcore (
|
||||
logic [1:0] PrivilegeModeW;
|
||||
logic [`XLEN-1:0] PTE;
|
||||
logic [1:0] PageType;
|
||||
logic wfiM;
|
||||
logic wfiM, IntPendingM;
|
||||
|
||||
// PMA checker signals
|
||||
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
||||
@ -306,7 +306,7 @@ module wallypipelinedcore (
|
||||
.FPUStallD, .FStallD,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.EcallFaultM, .BreakpointFaultM,
|
||||
.InvalidateICacheM, .wfiM,
|
||||
.InvalidateICacheM, .wfiM, .IntPendingM,
|
||||
// Stall & flush outputs
|
||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||
@ -341,7 +341,7 @@ module wallypipelinedcore (
|
||||
.PrivilegeModeW, .SATP_REGW,
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM
|
||||
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM
|
||||
);
|
||||
end else begin
|
||||
assign CSRReadValW = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user