From 1cbdaf1f05980144c239a4fc0a03ef6935d2f5a8 Mon Sep 17 00:00:00 2001 From: Thomas Fleming Date: Sat, 3 Apr 2021 21:28:24 -0400 Subject: [PATCH] Fix extraneous page fault stall --- wally-pipelined/src/ebu/ahblite.sv | 10 ++++----- wally-pipelined/src/ebu/pagetablewalker.sv | 10 ++++----- wally-pipelined/src/mmu/tlb.sv | 12 ++-------- .../src/wally/wallypipelinedhart.sv | 22 +++++++++---------- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index 45a51812f..d3cd98341 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -136,13 +136,13 @@ module ahblite ( // stall signals // Note that we need to extend both stalls when MMUTRANSLATE goes to idle, // since translation might not be complete. - assign #2 DataStall = ~TrapM && ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || - (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) || - (NextBusState == MMUTRANSLATE) || (BusState == MMUTRANSLATE)); + assign #2 DataStall = ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || + (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) || + (NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete)); // && ~TrapM // *** Could get finer grained stalling if we distinguish between MMU // instruction address translation and data address translation - assign #1 InstrStall = ~TrapM && ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) || - (NextBusState == MMUTRANSLATE) || (BusState == MMUTRANSLATE)); + assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) || + (NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete)); // && ~TrapM // bus outputs assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || diff --git a/wally-pipelined/src/ebu/pagetablewalker.sv b/wally-pipelined/src/ebu/pagetablewalker.sv index c90cff249..1a5df96a2 100644 --- a/wally-pipelined/src/ebu/pagetablewalker.sv +++ b/wally-pipelined/src/ebu/pagetablewalker.sv @@ -116,7 +116,7 @@ module pagetablewalker ( // unswizzle PTE bits assign {Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; - + // Assign PTE descriptors common across all XLEN values assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); @@ -195,6 +195,8 @@ module pagetablewalker ( assign ITLBWriteF = ~DTLBMissM; // Prefer data over instructions end FAULT: begin + assign TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + assign MMUTranslationComplete = '1; assign InstrPageFaultM = ~DTLBMissM; assign LoadPageFaultM = DTLBMissM && ~MemStore; assign StorePageFaultM = DTLBMissM && MemStore; @@ -206,8 +208,6 @@ module pagetablewalker ( // Capture page table entry from ahblite flopenr #(32) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE); - // *** Evil hack to get CurrentPTE a cycle early before it is saved. - // Todo: Is it evil? mux2 #(32) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE); assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; @@ -300,6 +300,8 @@ module pagetablewalker ( assign ITLBWriteF = ~DTLBMissM; // Prefer data over instructions end FAULT: begin + assign TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + assign MMUTranslationComplete = '1; assign InstrPageFaultM = ~DTLBMissM; assign LoadPageFaultM = DTLBMissM && ~MemStore; assign StorePageFaultM = DTLBMissM && MemStore; @@ -309,8 +311,6 @@ module pagetablewalker ( // Capture page table entry from ahblite flopenr #(`XLEN) ptereg(HCLK, ~HRESETn, MMUReady, MMUReadPTE, SavedPTE); - // *** Evil hack to get CurrentPTE a cycle early before it is saved. - // Todo: Is it evil? mux2 #(`XLEN) ptemux(SavedPTE, MMUReadPTE, MMUReady, CurrentPTE); assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 8b84a9929..664fd92d0 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -132,16 +132,7 @@ module tlb #(parameter ENTRY_BITS = 3) ( tlb_ram #(ENTRY_BITS) ram(.*); tlb_cam #(ENTRY_BITS, `VPN_BITS) cam(.*); - always_comb begin - assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10]; - - if (TLBHit) begin - assign PhysicalAddressFull = {PhysicalPageNumber, PageOffset}; - end else begin - assign PhysicalAddressFull = '0; // *** Actual behavior; disabled until walker functioning - //assign PhysicalAddressFull = {2'b0, VirtualPageNumber, PageOffset} // *** pass through should be removed as soon as walker ready - end - end + assign PhysicalAddressFull = (TLBHit) ? {PhysicalPageNumber, PageOffset} : '0; generate if (`XLEN == 32) begin @@ -155,6 +146,7 @@ module tlb #(parameter ENTRY_BITS = 3) ( assign TLBMiss = ~TLBHit & ~TLBFlush & Translate & TLBAccess; endmodule +// *** use actual flop notation instead of initialbegin and alwaysff module tlb_ram #(parameter ENTRY_BITS = 3) ( input clk, reset, input [ENTRY_BITS-1:0] VPNIndex, // Index to read from diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index b3447d3e1..b425fed78 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -65,7 +65,7 @@ module wallypipelinedhart ( logic [`XLEN-1:0] SrcAE, SrcBE; logic [`XLEN-1:0] SrcAM; logic [2:0] Funct3E; - // logic [31:0] InstrF; + // logic [31:0] InstrF; logic [31:0] InstrD, InstrM; logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW; logic [`XLEN-1:0] PCTargetE; @@ -84,7 +84,7 @@ module wallypipelinedhart ( logic PCSrcE; logic CSRWritePendingDEM; logic LoadStallD, MulDivStallD, CSRRdStallD; - logic DivDoneW; + logic DivDoneW; logic [4:0] SetFflagsM; logic [2:0] FRM_REGW; logic FloatRegWriteW; @@ -132,15 +132,15 @@ module wallypipelinedhart ( .Funct7M(InstrM[31:25]), .*); - pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall - // *** can connect to hazard unit - // changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed. - // Would need to insertinstruction as InstrD, not InstrF - /*ahblite ebu( - .InstrReadF(1'b0), - .InstrRData(), // hook up InstrF later - .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), - .*); */ + pagetablewalker pagetablewalker(.*); // can send addresses to ahblite, send out pagetablestall + // *** can connect to hazard unit + // changing from this to the line above breaks the program. auipc at 104 fails; seems to be flushed. + // Would need to insertinstruction as InstrD, not InstrF + /*ahblite ebu( + .InstrReadF(1'b0), + .InstrRData(), // hook up InstrF later + .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), + .*); */ muldiv mdu(.*); // multiply and divide unit