mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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 FPUStallD, FStallD,
|
||||||
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
||||||
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
(* 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
|
// Stall & flush outputs
|
||||||
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
|
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
|
||||||
(* mark_debug = "true" *) output logic FlushF, FlushD, FlushE, FlushM, FlushW
|
(* 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.
|
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||||
|
|
||||||
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
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 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 StallWCause = LSUStallM | IFUStallF;
|
||||||
|
|
||||||
assign StallF = StallFCause | StallD;
|
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 [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||||
output var logic [`XLEN-1:0] PMPADDR_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 [2:0] FRM_REGW,
|
||||||
output logic BreakpointFaultM, EcallFaultM, wfiM
|
output logic BreakpointFaultM, EcallFaultM, wfiM, IntPendingM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [1:0] NextPrivilegeModeM;
|
logic [1:0] NextPrivilegeModeM;
|
||||||
@ -226,7 +226,7 @@ module privileged (
|
|||||||
.InstrM,
|
.InstrM,
|
||||||
.InstrValidM, .CommittedM, .DivE,
|
.InstrValidM, .CommittedM, .DivE,
|
||||||
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
|
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
|
||||||
.InterruptM,
|
.InterruptM, .IntPendingM,
|
||||||
.ExceptionM,
|
.ExceptionM,
|
||||||
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
|
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -48,7 +48,7 @@ module trap (
|
|||||||
input logic [31:0] InstrM,
|
input logic [31:0] InstrM,
|
||||||
input logic InstrValidM, CommittedM, DivE,
|
input logic InstrValidM, CommittedM, DivE,
|
||||||
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||||
output logic InterruptM,
|
output logic InterruptM, IntPendingM,
|
||||||
output logic ExceptionM,
|
output logic ExceptionM,
|
||||||
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
||||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
// 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;
|
logic MIntGlobalEnM, SIntGlobalEnM;
|
||||||
(* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;
|
(* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM, MValidIntsM, SValidIntsM;
|
||||||
//logic InterruptM;
|
//logic InterruptM;
|
||||||
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
|
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
|
||||||
logic Exception1M;
|
logic Exception1M;
|
||||||
@ -65,13 +65,16 @@ module trap (
|
|||||||
// interrupt if any sources are pending
|
// 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 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
|
// & 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]
|
// 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 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 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 MPendingIntsM = MIP_REGW & MIE_REGW;
|
||||||
assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW;
|
assign SPendingIntsM = 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 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
|
// Trigger Traps and RET
|
||||||
// According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous.
|
// 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)
|
// Exceptions are of lower priority than all interrupts (3.1.9)
|
||||||
always_comb
|
always_comb
|
||||||
if (reset) CauseM = 0; // hard reset 3.3
|
if (reset) CauseM = 0; // hard reset 3.3
|
||||||
else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
|
else if (MValidIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
|
||||||
else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
|
else if (MValidIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
|
||||||
else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
|
else if (MValidIntsM[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 (MValidIntsM[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 (MValidIntsM[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 (MValidIntsM[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 (SValidIntsM[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 (SValidIntsM[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 (SValidIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode
|
||||||
else if (InstrPageFaultM) CauseM = 12;
|
else if (InstrPageFaultM) CauseM = 12;
|
||||||
else if (InstrAccessFaultM) CauseM = 1;
|
else if (InstrAccessFaultM) CauseM = 1;
|
||||||
else if (IllegalInstrFaultM) CauseM = 2;
|
else if (IllegalInstrFaultM) CauseM = 2;
|
||||||
|
@ -112,7 +112,7 @@ module wallypipelinedcore (
|
|||||||
logic [1:0] PrivilegeModeW;
|
logic [1:0] PrivilegeModeW;
|
||||||
logic [`XLEN-1:0] PTE;
|
logic [`XLEN-1:0] PTE;
|
||||||
logic [1:0] PageType;
|
logic [1:0] PageType;
|
||||||
logic wfiM;
|
logic wfiM, IntPendingM;
|
||||||
|
|
||||||
// PMA checker signals
|
// PMA checker signals
|
||||||
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
||||||
@ -306,7 +306,7 @@ module wallypipelinedcore (
|
|||||||
.FPUStallD, .FStallD,
|
.FPUStallD, .FStallD,
|
||||||
.DivBusyE, .FDivBusyE,
|
.DivBusyE, .FDivBusyE,
|
||||||
.EcallFaultM, .BreakpointFaultM,
|
.EcallFaultM, .BreakpointFaultM,
|
||||||
.InvalidateICacheM, .wfiM,
|
.InvalidateICacheM, .wfiM, .IntPendingM,
|
||||||
// Stall & flush outputs
|
// Stall & flush outputs
|
||||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||||
@ -341,7 +341,7 @@ module wallypipelinedcore (
|
|||||||
.PrivilegeModeW, .SATP_REGW,
|
.PrivilegeModeW, .SATP_REGW,
|
||||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||||
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM
|
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM
|
||||||
);
|
);
|
||||||
end else begin
|
end else begin
|
||||||
assign CSRReadValW = 0;
|
assign CSRReadValW = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user