mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Moved TLB Flush logic into privdec
This commit is contained in:
parent
1d01bc98a4
commit
9f8dca5190
@ -60,6 +60,8 @@ module hazard(
|
||||
// A stage must stall if the next stage is stalled
|
||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||
|
||||
// *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
|
||||
|
||||
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
||||
// stall in decode if instruction is a load/mul/csr dependent on previous
|
||||
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
|
||||
|
@ -33,16 +33,18 @@
|
||||
|
||||
module privdec (
|
||||
input logic clk, reset,
|
||||
input logic StallM,
|
||||
input logic [31:20] InstrM,
|
||||
input logic PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic STATUS_TSR, STATUS_TVM, STATUS_TW,
|
||||
input logic [1:0] STATUS_FS,
|
||||
output logic IllegalInstrFaultM,
|
||||
output logic IllegalInstrFaultM, ITLBFlushF, DTLBFlushM,
|
||||
output logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
|
||||
|
||||
logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
|
||||
logic WFITimeoutM;
|
||||
logic StallMQ;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Decode privileged instructions
|
||||
@ -65,7 +67,19 @@ module privdec (
|
||||
floprc #(`WFI_TIMEOUT_BIT+1) wficountreg(clk, reset, ~wfiM, WFICountPlus1, WFICount); // count while in WFI
|
||||
assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT];
|
||||
end else assign WFITimeoutM = 0;
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// sfence.vma causes TLB flushes
|
||||
///////////////////////////////////////////
|
||||
// sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
|
||||
// In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
|
||||
// But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and
|
||||
// the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush
|
||||
// after a cycle AND pulse it for another cycle on any further back-to-back sfences.
|
||||
flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
|
||||
assign ITLBFlushF = sfencevmaM & ~StallMQ;
|
||||
assign DTLBFlushM = sfencevmaM;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Fault on illegal instructions
|
||||
///////////////////////////////////////////
|
||||
|
@ -100,11 +100,8 @@ module privileged (
|
||||
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM;
|
||||
logic STATUS_MIE, STATUS_SIE;
|
||||
logic [11:0] MIP_REGW, MIE_REGW;
|
||||
logic StallMQ;
|
||||
logic WFITimeoutM;
|
||||
logic [1:0] NextPrivilegeModeM;
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// track the current privilege level
|
||||
///////////////////////////////////////////
|
||||
@ -116,9 +113,10 @@ module privileged (
|
||||
// decode privileged instructions
|
||||
///////////////////////////////////////////
|
||||
|
||||
privdec pmd(.clk, .reset, .InstrM(InstrM[31:20]),
|
||||
privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]),
|
||||
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM,
|
||||
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM,
|
||||
.ITLBFlushF, .DTLBFlushM,
|
||||
.sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
|
||||
|
||||
///////////////////////////////////////////
|
||||
@ -158,15 +156,6 @@ module privileged (
|
||||
assign BreakpointFaultM = ebreakM; // could have other causes too
|
||||
assign EcallFaultM = ecallM;
|
||||
|
||||
flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
|
||||
assign ITLBFlushF = sfencevmaM & ~StallMQ;
|
||||
assign DTLBFlushM = sfencevmaM;
|
||||
// sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
|
||||
// In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
|
||||
// But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and
|
||||
// the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush
|
||||
// after a cycle AND pulse it for another cycle on any further back-to-back sfences.
|
||||
|
||||
|
||||
// A page fault might occur because of insufficient privilege during a TLB
|
||||
// lookup or a improperly formatted page table during walking
|
||||
|
Loading…
Reference in New Issue
Block a user