From 37691b84d0622883f77dc403f6c08d1d6dcef3ec Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 02:59:35 -0400 Subject: [PATCH 01/30] Flip-flop clean-up --- wally-pipelined/src/mmu/pagetablewalker.sv | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 528b7292..eed2c5ef 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -119,9 +119,6 @@ module pagetablewalker - flop #(`XLEN) HPTWPAdrMReg(.clk(clk), - .d(HPTWPAdrE), - .q(HPTWPAdrM)); @@ -135,9 +132,9 @@ module pagetablewalker assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; assign SelDataTranslation = DTLBMissMQ | DTLBMissM; - flopenrc #(1) - DTLBMissMReg(.clk(clk), - .reset(reset), + flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); + flopenrc #(2) TLBMissMReg(clk, reset, StartWalk | EndWalk, EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); +/* .reset(reset), .en(StartWalk | EndWalk), .clear(EndWalk), .d(DTLBMissM), @@ -149,7 +146,7 @@ module pagetablewalker .en(StartWalk | EndWalk), .clear(EndWalk), .d(ITLBMissF), - .q(ITLBMissFQ)); + .q(ITLBMissFQ)); */ flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); From 8241dd4599b0bc3f1db21836e40faf7a61e8d6b8 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:10:17 -0400 Subject: [PATCH 02/30] Flip-flop clean-up --- wally-pipelined/src/mmu/pagetablewalker.sv | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 528b7292..1a051c8f 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -119,9 +119,7 @@ module pagetablewalker - flop #(`XLEN) HPTWPAdrMReg(.clk(clk), - .d(HPTWPAdrE), - .q(HPTWPAdrM)); + flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); From 9a15a2f7df8c5685117c6868a9ae256a129fc345 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:12:24 -0400 Subject: [PATCH 03/30] Flip-flop clean-up --- wally-pipelined/src/mmu/pagetablewalker.sv | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 1a051c8f..13a297c3 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -121,8 +121,6 @@ module pagetablewalker flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); - - assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; @@ -133,7 +131,8 @@ module pagetablewalker assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; assign SelDataTranslation = DTLBMissMQ | DTLBMissM; - flopenrc #(1) + flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); + /* flopenrc #(1) DTLBMissMReg(.clk(clk), .reset(reset), .en(StartWalk | EndWalk), @@ -147,7 +146,7 @@ module pagetablewalker .en(StartWalk | EndWalk), .clear(EndWalk), .d(ITLBMissF), - .q(ITLBMissFQ)); + .q(ITLBMissFQ));*/ flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); From 86ca9abe42e0b4dbf8d2e76f7b98ea5af66a0c85 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:15:47 -0400 Subject: [PATCH 04/30] Flip-flop clean-up --- wally-pipelined/src/mmu/pagetablewalker.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 13a297c3..d71248a8 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -119,7 +119,6 @@ module pagetablewalker - flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; @@ -131,7 +130,6 @@ module pagetablewalker assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; assign SelDataTranslation = DTLBMissMQ | DTLBMissM; - flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); /* flopenrc #(1) DTLBMissMReg(.clk(clk), .reset(reset), @@ -148,6 +146,8 @@ module pagetablewalker .d(ITLBMissF), .q(ITLBMissFQ));*/ + flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); + flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); From ac67342dd44c374a259c3f6d1039a216e173ca35 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:21:09 -0400 Subject: [PATCH 05/30] Pulled out shared PTEReg --- wally-pipelined/src/mmu/pagetablewalker.sv | 48 ++++------------------ 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index d71248a8..bb5ae854 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -78,7 +78,7 @@ module pagetablewalker logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`XLEN-1:0] TranslationVAdr; - logic [`XLEN-1:0] SavedPTE, CurrentPTE; + logic [`XLEN-1:0] CurrentPTE; logic [`PA_BITS-1:0] TranslationPAdr; logic [`PPN_BITS-1:0] CurrentPPN; logic [`SVMODE_BITS-1:0] SvMode; @@ -130,31 +130,18 @@ module pagetablewalker assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; assign SelDataTranslation = DTLBMissMQ | DTLBMissM; - /* flopenrc #(1) - DTLBMissMReg(.clk(clk), - .reset(reset), - .en(StartWalk | EndWalk), - .clear(EndWalk), - .d(DTLBMissM), - .q(DTLBMissMQ)); - - flopenrc #(1) - ITLBMissMReg(.clk(clk), - .reset(reset), - .en(StartWalk | EndWalk), - .clear(EndWalk), - .d(ITLBMissF), - .q(ITLBMissFQ));*/ - flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); - flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); - flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); + flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); + flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); + flopenr #(`XLEN) ptereg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache + assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; + assign AnyTLBMissM = DTLBMissM | ITLBMissF; - assign StartWalk = WalkerState == IDLE & AnyTLBMissM; - assign EndWalk = WalkerState == LEAF || WalkerState == FAULT; + assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM; + assign EndWalk = (WalkerState == LEAF) || (WalkerState == FAULT); // unswizzle PTE bits assign {Dirty, Accessed, Global, User, @@ -291,18 +278,6 @@ module pagetablewalker - // Capture page table entry from data cache - // *** may need to delay reading this value until the next clock cycle. - // The clk to q latency of the SRAM in the data cache will be long. - // I cannot see directly using this value. This is no different than - // a load delay hazard. This will require rewriting the walker fsm. - // also need a new signal to save. Should be a mealy output of the fsm - // request followed by ~stall. - flopenr #(32) ptereg(clk, reset, PRegEn, HPTWReadPTE, SavedPTE); - //mux2 #(32) ptemux(SavedPTE, HPTWReadPTE, PRegEn, CurrentPTE); - assign CurrentPTE = SavedPTE; - assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; - // Assign outputs to ahblite // *** Currently truncate address to 32 bits. This must be changed if // we support larger physical address spaces @@ -514,13 +489,6 @@ module pagetablewalker assign VPN1 = TranslationVAdr[29:21]; assign VPN0 = TranslationVAdr[20:12]; - - // Capture page table entry from ahblite - flopenr #(`XLEN) ptereg(clk, reset, PRegEn, HPTWReadPTE, SavedPTE); - //mux2 #(`XLEN) ptemux(SavedPTE, HPTWReadPTE, PRegEn, CurrentPTE); - assign CurrentPTE = SavedPTE; - assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; - // *** Major issue. We need the full virtual address here. // When the TLB's are update it use use the orignal address // *** Currently truncate address to 32 bits. This must be changed if From 569843346387b85c1503de5550907df32ce40939 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:30:17 -0400 Subject: [PATCH 06/30] Simplified bad PTE detection --- wally-pipelined/src/mmu/pagetablewalker.sv | 59 ++++++++++------------ 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index bb5ae854..bd71538f 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -88,7 +88,7 @@ module pagetablewalker logic Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid; // PTE descriptions - logic ValidPTE, AccessAlert, MegapageMisaligned, BadMegapage, LeafPTE; + logic ValidPTE, ADPageFault, MegapageMisaligned, BadMegapage, LeafPTE; // Outputs of walker logic [`XLEN-1:0] PageTableEntry; @@ -134,7 +134,7 @@ module pagetablewalker flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); - flopenr #(`XLEN) ptereg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache + flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; @@ -150,7 +150,7 @@ module pagetablewalker // Assign PTE descriptors common across all XLEN values assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); - assign AccessAlert = ~Accessed | (MemStore & ~Dirty); + assign ADPageFault = ~Accessed | (MemStore & ~Dirty); // Assign specific outputs to general outputs assign PageTableEntryF = PageTableEntry; @@ -159,6 +159,11 @@ module pagetablewalker // generate if (`XLEN == 32) begin logic [9:0] VPN1, VPN0; + assign VPN1 = TranslationVAdr[31:22]; + assign VPN0 = TranslationVAdr[21:12]; + + // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. + assign MegapageMisaligned = |(CurrentPPN[9:0]); // State transition logic @@ -208,7 +213,7 @@ module pagetablewalker // fault upon finding a superpage that is misaligned or has 0 // access bit. The following commented line of code is // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~BadMegapage) begin + if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) begin NextWalkerState = LEAF; TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; end @@ -239,7 +244,7 @@ module pagetablewalker end LEVEL0: begin - if (ValidPTE & LeafPTE & ~AccessAlert) begin + if (ValidPTE & LeafPTE & ~ADPageFault) begin NextWalkerState = LEAF; TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; end else begin @@ -269,12 +274,7 @@ module pagetablewalker endcase end - // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. - assign MegapageMisaligned = |(CurrentPPN[9:0]); - assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme - assign VPN1 = TranslationVAdr[31:22]; - assign VPN0 = TranslationVAdr[21:12]; @@ -286,8 +286,20 @@ module pagetablewalker end else begin logic [8:0] VPN3, VPN2, VPN1, VPN0; + assign VPN3 = TranslationVAdr[47:39]; + assign VPN2 = TranslationVAdr[38:30]; + assign VPN1 = TranslationVAdr[29:21]; + assign VPN0 = TranslationVAdr[20:12]; - logic TerapageMisaligned, GigapageMisaligned, BadTerapage, BadGigapage; + logic TerapageMisaligned, GigapageMisaligned; + // A terapage is a level 3 leaf page. This page must have zero PPN[2], + // zero PPN[1], and zero PPN[0] + assign TerapageMisaligned = |(CurrentPPN[26:0]); + // A gigapage is a Level 2 leaf page. This page must have zero PPN[1] and + // zero PPN[0] + assign GigapageMisaligned = |(CurrentPPN[17:0]); + // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. + assign MegapageMisaligned = |(CurrentPPN[8:0]); always_comb begin PRegEn = 1'b0; @@ -337,7 +349,7 @@ module pagetablewalker // fault upon finding a superpage that is misaligned or has 0 // access bit. The following commented line of code is // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~BadTerapage) begin + if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end @@ -371,7 +383,7 @@ module pagetablewalker // fault upon finding a superpage that is misaligned or has 0 // access bit. The following commented line of code is // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~BadGigapage) begin + if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end @@ -405,7 +417,7 @@ module pagetablewalker // fault upon finding a superpage that is misaligned or has 0 // access bit. The following commented line of code is // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~BadMegapage) begin + if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; @@ -436,7 +448,7 @@ module pagetablewalker end LEVEL0: begin - if (ValidPTE && LeafPTE && ~AccessAlert) begin + if (ValidPTE && LeafPTE && ~ADPageFault) begin NextWalkerState = LEAF; TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end else begin @@ -471,23 +483,6 @@ module pagetablewalker endcase end - // A terapage is a level 3 leaf page. This page must have zero PPN[2], - // zero PPN[1], and zero PPN[0] - assign TerapageMisaligned = |(CurrentPPN[26:0]); - // A gigapage is a Level 2 leaf page. This page must have zero PPN[1] and - // zero PPN[0] - assign GigapageMisaligned = |(CurrentPPN[17:0]); - // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. - assign MegapageMisaligned = |(CurrentPPN[8:0]); - - assign BadTerapage = TerapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme - assign BadGigapage = GigapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme - assign BadMegapage = MegapageMisaligned || AccessAlert; // *** Implement better access/dirty scheme - - assign VPN3 = TranslationVAdr[47:39]; - assign VPN2 = TranslationVAdr[38:30]; - assign VPN1 = TranslationVAdr[29:21]; - assign VPN0 = TranslationVAdr[20:12]; // *** Major issue. We need the full virtual address here. // When the TLB's are update it use use the orignal address From 03ef3f7f1740a76203e0be9373b049740b21bdc1 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:06:26 -0400 Subject: [PATCH 07/30] Pulled TranslationPAdr mux out of HPTW FSM --- wally-pipelined/src/mmu/pagetablewalker.sv | 121 ++++++++++++++------- 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index bd71538f..3fb13e99 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -156,12 +156,59 @@ module pagetablewalker assign PageTableEntryF = PageTableEntry; assign PageTableEntryM = PageTableEntry; + // *** is there a way to speed up HPTW? + + // TranslationPAdr mux + if (`XLEN==32) begin + logic [9:0] VPN1, VPN0; + assign VPN1 = TranslationVAdr[31:22]; + assign VPN0 = TranslationVAdr[21:12]; + always_comb + case (WalkerState) + LEVEL1_SET_ADRE: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + LEVEL1_WDV: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this and similar + else TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL0_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL0: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; + LEAF: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; + default: TranslationPAdr = 0; // cause seg fault if this is improperly used + endcase + end else begin + logic [8:0] VPN3, VPN2, VPN1, VPN0; + assign VPN3 = TranslationVAdr[47:39]; + assign VPN2 = TranslationVAdr[38:30]; + assign VPN1 = TranslationVAdr[29:21]; + assign VPN0 = TranslationVAdr[20:12]; + always_comb + case (WalkerState) + LEVEL3_SET_ADRE: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + LEVEL3_WDV: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + LEVEL3: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + else TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + LEVEL2_SET_ADRE: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + LEVEL2_WDV: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + LEVEL2: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + else TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + LEVEL1_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + LEVEL1_WDV: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + else TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + LEVEL0_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + LEVEL0: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + LEAF: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + default: TranslationPAdr = 0; // cause seg fault if this is improperly used + endcase + end // generate if (`XLEN == 32) begin - logic [9:0] VPN1, VPN0; - assign VPN1 = TranslationVAdr[31:22]; - assign VPN0 = TranslationVAdr[21:12]; - + // *** make sure 32/34 bit addresses are being handled properly + //logic [9:0] VPN1, VPN0; + //assign VPN1 = TranslationVAdr[31:22]; + //assign VPN0 = TranslationVAdr[21:12]; + // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. assign MegapageMisaligned = |(CurrentPPN[9:0]); @@ -169,7 +216,7 @@ module pagetablewalker // State transition logic always_comb begin PRegEn = 1'b0; - TranslationPAdr = '0; + // TranslationPAdr = '0; HPTWRead = 1'b0; PageTableEntry = '0; PageType = '0; @@ -194,11 +241,11 @@ module pagetablewalker LEVEL1_SET_ADRE: begin NextWalkerState = LEVEL1_WDV; - TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; end LEVEL1_WDV: begin - TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL1_WDV; @@ -209,18 +256,13 @@ module pagetablewalker end LEVEL1: begin - // *** According to the architecture, we should - // fault upon finding a superpage that is misaligned or has 0 - // access bit. The following commented line of code is - // supposed to perform that check. However, it is untested. if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) begin NextWalkerState = LEAF; - TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; + //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this end - // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL0_SET_ADRE; - TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; HPTWRead = 1'b1; end else begin NextWalkerState = FAULT; @@ -229,11 +271,11 @@ module pagetablewalker LEVEL0_SET_ADRE: begin NextWalkerState = LEVEL0_WDV; - TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; end LEVEL0_WDV: begin - TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL0_WDV; @@ -246,7 +288,7 @@ module pagetablewalker LEVEL0: begin if (ValidPTE & LeafPTE & ~ADPageFault) begin NextWalkerState = LEAF; - TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; + //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; end else begin NextWalkerState = FAULT; end @@ -258,7 +300,7 @@ module pagetablewalker PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? DTLBWriteM = DTLBMissMQ; ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions - TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; + //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; end FAULT: begin @@ -285,11 +327,11 @@ module pagetablewalker end else begin - logic [8:0] VPN3, VPN2, VPN1, VPN0; +/* logic [8:0] VPN3, VPN2, VPN1, VPN0; assign VPN3 = TranslationVAdr[47:39]; assign VPN2 = TranslationVAdr[38:30]; assign VPN1 = TranslationVAdr[29:21]; - assign VPN0 = TranslationVAdr[20:12]; + assign VPN0 = TranslationVAdr[20:12];*/ logic TerapageMisaligned, GigapageMisaligned; // A terapage is a level 3 leaf page. This page must have zero PPN[2], @@ -303,7 +345,7 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; - TranslationPAdr = '0; + //TranslationPAdr = '0; HPTWRead = 1'b0; PageTableEntry = '0; PageType = '0; @@ -330,11 +372,11 @@ module pagetablewalker LEVEL3_SET_ADRE: begin NextWalkerState = LEVEL3_WDV; - TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; end LEVEL3_WDV: begin - TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL3_WDV; @@ -345,18 +387,13 @@ module pagetablewalker end LEVEL3: begin - // *** According to the architecture, we should - // fault upon finding a superpage that is misaligned or has 0 - // access bit. The following commented line of code is - // supposed to perform that check. However, it is untested. if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; - TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end - // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL2_SET_ADRE; - TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; end else begin NextWalkerState = FAULT; end @@ -364,11 +401,11 @@ module pagetablewalker LEVEL2_SET_ADRE: begin NextWalkerState = LEVEL2_WDV; - TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; end LEVEL2_WDV: begin - TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL2_WDV; @@ -385,12 +422,12 @@ module pagetablewalker // supposed to perform that check. However, it is untested. if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; - TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL1_SET_ADRE; - TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; end else begin NextWalkerState = FAULT; end @@ -398,11 +435,11 @@ module pagetablewalker LEVEL1_SET_ADRE: begin NextWalkerState = LEVEL1_WDV; - TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; end LEVEL1_WDV: begin - TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL1_WDV; @@ -419,13 +456,13 @@ module pagetablewalker // supposed to perform that check. However, it is untested. if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) begin NextWalkerState = LEAF; - TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL0_SET_ADRE; - TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; end else begin NextWalkerState = FAULT; end @@ -433,11 +470,11 @@ module pagetablewalker LEVEL0_SET_ADRE: begin NextWalkerState = LEVEL0_WDV; - TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; end LEVEL0_WDV: begin - TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; HPTWRead = 1'b1; if (HPTWStall) begin NextWalkerState = LEVEL0_WDV; @@ -450,7 +487,7 @@ module pagetablewalker LEVEL0: begin if (ValidPTE && LeafPTE && ~ADPageFault) begin NextWalkerState = LEAF; - TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; end else begin NextWalkerState = FAULT; end @@ -463,7 +500,7 @@ module pagetablewalker ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); DTLBWriteM = DTLBMissMQ; ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions - TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; + //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; NextWalkerState = IDLE; end From 330e500442e901260c941f429edb834e06891637 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:12:31 -0400 Subject: [PATCH 08/30] Simplify FSM --- wally-pipelined/src/mmu/pagetablewalker.sv | 51 +++++++--------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 3fb13e99..d365dc30 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -156,6 +156,9 @@ module pagetablewalker assign PageTableEntryF = PageTableEntry; assign PageTableEntryM = PageTableEntry; + assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT); + + // *** is there a way to speed up HPTW? // TranslationPAdr mux @@ -216,7 +219,6 @@ module pagetablewalker // State transition logic always_comb begin PRegEn = 1'b0; - // TranslationPAdr = '0; HPTWRead = 1'b0; PageTableEntry = '0; PageType = '0; @@ -227,46 +229,27 @@ module pagetablewalker WalkerLoadPageFaultM = 1'b0; WalkerStorePageFaultM = 1'b0; - SelPTW = 1'b1; + // SelPTW = 1'b1; case (WalkerState) - IDLE: begin - SelPTW = 1'b0; - if (AnyTLBMissM & SvMode == `SV32) begin - NextWalkerState = LEVEL1_SET_ADRE; - end else begin - NextWalkerState = IDLE; - end - end - - LEVEL1_SET_ADRE: begin - NextWalkerState = LEVEL1_WDV; - //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; - end - + IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; + else NextWalkerState = IDLE; + LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: begin - //TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL1_WDV; - end else begin + if (HPTWStall) NextWalkerState = LEVEL1_WDV; + else begin NextWalkerState = LEVEL1; PRegEn = 1'b1; end end LEVEL1: begin - if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) begin - NextWalkerState = LEAF; - //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this - end + if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) begin - NextWalkerState = LEVEL0_SET_ADRE; - //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; - HPTWRead = 1'b1; - end else begin - NextWalkerState = FAULT; - end + NextWalkerState = LEVEL0_SET_ADRE; + HPTWRead = 1'b1; + end else NextWalkerState = FAULT; end LEVEL0_SET_ADRE: begin @@ -304,7 +287,7 @@ module pagetablewalker end FAULT: begin - SelPTW = 1'b0; + //SelPTW = 1'b0; NextWalkerState = IDLE; WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; @@ -356,11 +339,9 @@ module pagetablewalker WalkerLoadPageFaultM = 1'b0; WalkerStorePageFaultM = 1'b0; - SelPTW = 1'b1; - case (WalkerState) IDLE: begin - SelPTW = 1'b0; + //SelPTW = 1'b0; if (AnyTLBMissM & SvMode == `SV48) begin NextWalkerState = LEVEL3_SET_ADRE; end else if (AnyTLBMissM & SvMode == `SV39) begin @@ -505,7 +486,7 @@ module pagetablewalker end FAULT: begin - SelPTW = 1'b0; + //SelPTW = 1'b0; NextWalkerState = IDLE; WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; From 6d8a6eeba0edaf3461c458be6e1ae824ca6cf157 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:26:41 -0400 Subject: [PATCH 09/30] cleaning up FSM --- wally-pipelined/src/mmu/pagetablewalker.sv | 57 +++++----------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index d365dc30..6af6a9fd 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -229,8 +229,6 @@ module pagetablewalker WalkerLoadPageFaultM = 1'b0; WalkerStorePageFaultM = 1'b0; - // SelPTW = 1'b1; - case (WalkerState) IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; else NextWalkerState = IDLE; @@ -239,8 +237,8 @@ module pagetablewalker HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL1_WDV; else begin - NextWalkerState = LEVEL1; - PRegEn = 1'b1; + NextWalkerState = LEVEL1; + PRegEn = 1'b1; end end @@ -251,33 +249,19 @@ module pagetablewalker HPTWRead = 1'b1; end else NextWalkerState = FAULT; end - - LEVEL0_SET_ADRE: begin - NextWalkerState = LEVEL0_WDV; - //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; - end - + LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: begin - //TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL0_WDV; - end else begin - NextWalkerState = LEVEL0; - PRegEn = 1'b1; + if (HPTWStall) NextWalkerState = LEVEL0_WDV; + else begin + NextWalkerState = LEVEL0; + PRegEn = 1'b1; end end - LEVEL0: begin - if (ValidPTE & LeafPTE & ~ADPageFault) begin - NextWalkerState = LEAF; - //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; - end else begin - NextWalkerState = FAULT; - end - end - - LEAF: begin + LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; + else NextWalkerState = FAULT; + LEAF: begin // *** pull out datapath stuff NextWalkerState = IDLE; PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? @@ -287,7 +271,6 @@ module pagetablewalker end FAULT: begin - //SelPTW = 1'b0; NextWalkerState = IDLE; WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; @@ -309,13 +292,6 @@ module pagetablewalker assign HPTWPAdrE = TranslationPAdr[31:0]; end else begin - -/* logic [8:0] VPN3, VPN2, VPN1, VPN0; - assign VPN3 = TranslationVAdr[47:39]; - assign VPN2 = TranslationVAdr[38:30]; - assign VPN1 = TranslationVAdr[29:21]; - assign VPN0 = TranslationVAdr[20:12];*/ - logic TerapageMisaligned, GigapageMisaligned; // A terapage is a level 3 leaf page. This page must have zero PPN[2], // zero PPN[1], and zero PPN[0] @@ -328,7 +304,6 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; - //TranslationPAdr = '0; HPTWRead = 1'b0; PageTableEntry = '0; PageType = '0; @@ -340,16 +315,8 @@ module pagetablewalker WalkerStorePageFaultM = 1'b0; case (WalkerState) - IDLE: begin - //SelPTW = 1'b0; - if (AnyTLBMissM & SvMode == `SV48) begin - NextWalkerState = LEVEL3_SET_ADRE; - end else if (AnyTLBMissM & SvMode == `SV39) begin - NextWalkerState = LEVEL2_SET_ADRE; - end else begin - NextWalkerState = IDLE; - end - end + IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; + else NextWalkerState = IDLE; LEVEL3_SET_ADRE: begin NextWalkerState = LEVEL3_WDV; From bd270acdb61a04460b32eb51ec542de85dd172d0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:35:51 -0400 Subject: [PATCH 10/30] more cleaning up FSM --- wally-pipelined/src/mmu/pagetablewalker.sv | 159 +++++---------------- 1 file changed, 36 insertions(+), 123 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 6af6a9fd..596b400f 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -207,10 +207,6 @@ module pagetablewalker end // generate if (`XLEN == 32) begin - // *** make sure 32/34 bit addresses are being handled properly - //logic [9:0] VPN1, VPN0; - //assign VPN1 = TranslationVAdr[31:22]; - //assign VPN0 = TranslationVAdr[21:12]; // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. assign MegapageMisaligned = |(CurrentPPN[9:0]); @@ -317,130 +313,57 @@ module pagetablewalker case (WalkerState) IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; else NextWalkerState = IDLE; - - LEVEL3_SET_ADRE: begin - NextWalkerState = LEVEL3_WDV; - //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; - end - + LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: begin - //TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL3_WDV; - end else begin - NextWalkerState = LEVEL3; - PRegEn = 1'b1; + if (HPTWStall) NextWalkerState = LEVEL3_WDV; + else begin + NextWalkerState = LEVEL3; + PRegEn = 1'b1; end end - - LEVEL3: begin - if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) begin - NextWalkerState = LEAF; - //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; - end - else if (ValidPTE && ~LeafPTE) begin - NextWalkerState = LEVEL2_SET_ADRE; - //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; - end else begin - NextWalkerState = FAULT; - end - end - - LEVEL2_SET_ADRE: begin - NextWalkerState = LEVEL2_WDV; - //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; - end - + LEVEL3: + if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; LEVEL2_WDV: begin - //TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL2_WDV; - end else begin - NextWalkerState = LEVEL2; - PRegEn = 1'b1; + if (HPTWStall) NextWalkerState = LEVEL2_WDV; + else begin + NextWalkerState = LEVEL2; + PRegEn = 1'b1; end end - - LEVEL2: begin - // *** According to the architecture, we should - // fault upon finding a superpage that is misaligned or has 0 - // access bit. The following commented line of code is - // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) begin - NextWalkerState = LEAF; - //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; - end - // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. - else if (ValidPTE && ~LeafPTE) begin - NextWalkerState = LEVEL1_SET_ADRE; - //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; - end else begin - NextWalkerState = FAULT; - end - end - - LEVEL1_SET_ADRE: begin - NextWalkerState = LEVEL1_WDV; - //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; - end - + LEVEL2: + if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: begin - //TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL1_WDV; - end else begin - NextWalkerState = LEVEL1; - PRegEn = 1'b1; + if (HPTWStall) NextWalkerState = LEVEL1_WDV; + else begin + NextWalkerState = LEVEL1; + PRegEn = 1'b1; end end - - LEVEL1: begin - // *** According to the architecture, we should - // fault upon finding a superpage that is misaligned or has 0 - // access bit. The following commented line of code is - // supposed to perform that check. However, it is untested. - if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) begin - NextWalkerState = LEAF; - //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; - - end - // else if (ValidPTE && LeafPTE) NextWalkerState = LEAF; // *** Once the above line is properly tested, delete this line. - else if (ValidPTE && ~LeafPTE) begin - NextWalkerState = LEVEL0_SET_ADRE; - //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; - end else begin - NextWalkerState = FAULT; - end - end - - LEVEL0_SET_ADRE: begin - NextWalkerState = LEVEL0_WDV; - //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; - end - + LEVEL1: + if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: begin - //TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; HPTWRead = 1'b1; - if (HPTWStall) begin - NextWalkerState = LEVEL0_WDV; - end else begin - NextWalkerState = LEVEL0; - PRegEn = 1'b1; + if (HPTWStall) NextWalkerState = LEVEL0_WDV; + else begin + NextWalkerState = LEVEL0; + PRegEn = 1'b1; end end - - LEVEL0: begin - if (ValidPTE && LeafPTE && ~ADPageFault) begin - NextWalkerState = LEAF; - //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; - end else begin - NextWalkerState = FAULT; - end - end - + LEVEL0: + if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; + else NextWalkerState = FAULT; LEAF: begin PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? @@ -448,12 +371,9 @@ module pagetablewalker ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); DTLBWriteM = DTLBMissMQ; ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions - //TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; NextWalkerState = IDLE; end - - FAULT: begin - //SelPTW = 1'b0; + FAULT: begin // *** why do these only get raised on TLB misses? Should they always fault? NextWalkerState = IDLE; WalkerInstrPageFaultF = ~DTLBMissMQ; WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; @@ -467,15 +387,8 @@ module pagetablewalker endcase end - - - // *** Major issue. We need the full virtual address here. - // When the TLB's are update it use use the orignal address - // *** Currently truncate address to 32 bits. This must be changed if - // we support larger physical address spaces assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; end - //endgenerate end else begin assign HPTWPAdrE = 0; assign HPTWRead = 0; From 08e494dd7deb96937a4a7a23dc81c8b6dac91125 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:40:01 -0400 Subject: [PATCH 11/30] HPTW: factored out PageTableENtry --- wally-pipelined/src/mmu/pagetablewalker.sv | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 596b400f..41012415 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -91,7 +91,7 @@ module pagetablewalker logic ValidPTE, ADPageFault, MegapageMisaligned, BadMegapage, LeafPTE; // Outputs of walker - logic [`XLEN-1:0] PageTableEntry; + //logic [`XLEN-1:0] PageTableEntry; logic StartWalk; logic EndWalk; @@ -153,11 +153,13 @@ module pagetablewalker assign ADPageFault = ~Accessed | (MemStore & ~Dirty); // Assign specific outputs to general outputs - assign PageTableEntryF = PageTableEntry; - assign PageTableEntryM = PageTableEntry; + // *** try to eliminate this duplication, but attempts caused MMU to hang + assign PageTableEntryF = CurrentPTE; + assign PageTableEntryM = CurrentPTE; assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT); - + assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ; + assign DTLBWriteM = (WalkerState == LEAF) & ~DTLBMissMQ; // *** is there a way to speed up HPTW? @@ -216,7 +218,7 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - PageTableEntry = '0; + //PageTableEntry = '0; PageType = '0; DTLBWriteM = '0; ITLBWriteF = '0; @@ -259,7 +261,7 @@ module pagetablewalker else NextWalkerState = FAULT; LEAF: begin // *** pull out datapath stuff NextWalkerState = IDLE; - PageTableEntry = CurrentPTE; + //PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? DTLBWriteM = DTLBMissMQ; ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions @@ -301,7 +303,7 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - PageTableEntry = '0; + //PageTableEntry = '0; PageType = '0; DTLBWriteM = '0; ITLBWriteF = '0; @@ -365,7 +367,7 @@ module pagetablewalker if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; LEAF: begin - PageTableEntry = CurrentPTE; + //PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? ((PreviousWalkerState == LEVEL2) ? 2'b10 : ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); From a0f6c9aec194d59dba2e46577825469944fa8a9a Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:44:23 -0400 Subject: [PATCH 12/30] HPTW: factored out DTLBWrite/ITLBWrite --- wally-pipelined/src/mmu/pagetablewalker.sv | 25 +++------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 41012415..b6c23345 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -159,7 +159,7 @@ module pagetablewalker assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT); assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ; - assign DTLBWriteM = (WalkerState == LEAF) & ~DTLBMissMQ; + assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ; // *** is there a way to speed up HPTW? @@ -218,10 +218,7 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - //PageTableEntry = '0; PageType = '0; - DTLBWriteM = '0; - ITLBWriteF = '0; WalkerInstrPageFaultF = 1'b0; WalkerLoadPageFaultM = 1'b0; @@ -239,7 +236,6 @@ module pagetablewalker PRegEn = 1'b1; end end - LEVEL1: begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) begin @@ -256,16 +252,11 @@ module pagetablewalker PRegEn = 1'b1; end end - LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; - LEAF: begin // *** pull out datapath stuff + LEAF: begin NextWalkerState = IDLE; - //PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? - DTLBWriteM = DTLBMissMQ; - ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions - //TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; end FAULT: begin @@ -303,10 +294,7 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - //PageTableEntry = '0; PageType = '0; - DTLBWriteM = '0; - ITLBWriteF = '0; WalkerInstrPageFaultF = 1'b0; WalkerLoadPageFaultM = 1'b0; @@ -367,12 +355,9 @@ module pagetablewalker if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; LEAF: begin - //PageTableEntry = CurrentPTE; PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? ((PreviousWalkerState == LEVEL2) ? 2'b10 : ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); - DTLBWriteM = DTLBMissMQ; - ITLBWriteF = ~DTLBMissMQ; // Prefer data over instructions NextWalkerState = IDLE; end FAULT: begin // *** why do these only get raised on TLB misses? Should they always fault? @@ -381,11 +366,7 @@ module pagetablewalker WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; WalkerStorePageFaultM = DTLBMissMQ && MemStore; end - - // Default case should never happen - default: begin - NextWalkerState = IDLE; - end + default: NextWalkerState = IDLE; // should never be reached endcase end From 880aa1c03aee68b8fda4c2399a9047eced1aac53 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 04:55:01 -0400 Subject: [PATCH 13/30] HPTW: more cleanup --- wally-pipelined/src/mmu/pagetablewalker.sv | 76 +++++----------------- 1 file changed, 17 insertions(+), 59 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index b6c23345..f60281d4 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -95,21 +95,11 @@ module pagetablewalker logic StartWalk; logic EndWalk; - typedef enum {LEVEL0_SET_ADRE, - LEVEL0_WDV, - LEVEL0, - LEVEL1_SET_ADRE, - LEVEL1_WDV, - LEVEL1, - LEVEL2_SET_ADRE, - LEVEL2_WDV, - LEVEL2, - LEVEL3_SET_ADRE, - LEVEL3_WDV, - LEVEL3, - LEAF, - IDLE, - FAULT} statetype; + typedef enum {LEVEL0_SET_ADRE, LEVEL0_WDV, LEVEL0, + LEVEL1_SET_ADRE, LEVEL1_WDV, LEVEL1, + LEVEL2_SET_ADRE, LEVEL2_WDV, LEVEL2, + LEVEL3_SET_ADRE, LEVEL3_WDV, LEVEL3, + LEAF, IDLE, FAULT} statetype; statetype WalkerState, NextWalkerState, PreviousWalkerState; @@ -117,13 +107,8 @@ module pagetablewalker logic SelDataTranslation; logic AnyTLBMissM; - - - assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; - assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; - assign MemStore = MemRWM[0]; // Prefer data address translations over instruction address translations @@ -137,7 +122,6 @@ module pagetablewalker flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; - assign AnyTLBMissM = DTLBMissM | ITLBMissF; assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM; @@ -161,6 +145,14 @@ module pagetablewalker assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ; assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ; + assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBMissMQ; //*** why do these only get raised on TLB misses? Should they always fault even for ADpagefaults, invalid addresses,etc?? + assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemStore; + assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemStore; + + assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? + ((PreviousWalkerState == LEVEL2) ? 2'b10 : + ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); + // *** is there a way to speed up HPTW? // TranslationPAdr mux @@ -218,11 +210,6 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - PageType = '0; - - WalkerInstrPageFaultF = 1'b0; - WalkerLoadPageFaultM = 1'b0; - WalkerStorePageFaultM = 1'b0; case (WalkerState) IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; @@ -254,27 +241,13 @@ module pagetablewalker end LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; - LEAF: begin - NextWalkerState = IDLE; - PageType = (PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00; // *** not sure about this mux? - end - - FAULT: begin - NextWalkerState = IDLE; - WalkerInstrPageFaultF = ~DTLBMissMQ; - WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; - WalkerStorePageFaultM = DTLBMissMQ && MemStore; - end - + LEAF: NextWalkerState = IDLE; + FAULT: NextWalkerState = IDLE; // Default case should never happen, but is included for linter. default: NextWalkerState = IDLE; endcase end - - - - // Assign outputs to ahblite // *** Currently truncate address to 32 bits. This must be changed if // we support larger physical address spaces @@ -294,11 +267,6 @@ module pagetablewalker always_comb begin PRegEn = 1'b0; HPTWRead = 1'b0; - PageType = '0; - - WalkerInstrPageFaultF = 1'b0; - WalkerLoadPageFaultM = 1'b0; - WalkerStorePageFaultM = 1'b0; case (WalkerState) IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; @@ -354,18 +322,8 @@ module pagetablewalker LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; - LEAF: begin - PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? - ((PreviousWalkerState == LEVEL2) ? 2'b10 : - ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); - NextWalkerState = IDLE; - end - FAULT: begin // *** why do these only get raised on TLB misses? Should they always fault? - NextWalkerState = IDLE; - WalkerInstrPageFaultF = ~DTLBMissMQ; - WalkerLoadPageFaultM = DTLBMissMQ && ~MemStore; - WalkerStorePageFaultM = DTLBMissMQ && MemStore; - end + LEAF: NextWalkerState = IDLE; + FAULT: NextWalkerState = IDLE; default: NextWalkerState = IDLE; // should never be reached endcase From ef63e1ab526d2af528ffecd1ad7dcde2e8af37be Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:11:10 -0400 Subject: [PATCH 14/30] hptw: factored pregen --- wally-pipelined/src/mmu/pagetablewalker.sv | 23 ++++++++----------- .../testbench/testbench-imperas.sv | 1 + 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index f60281d4..d421a79c 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -29,11 +29,6 @@ `include "wally-config.vh" -/* *** - TO-DO: - - Implement faults on accessed/dirty behavior - */ - module pagetablewalker ( // Control signals @@ -152,6 +147,7 @@ module pagetablewalker assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? ((PreviousWalkerState == LEVEL2) ? 2'b10 : ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); + assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); // *** is there a way to speed up HPTW? @@ -205,10 +201,9 @@ module pagetablewalker // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. assign MegapageMisaligned = |(CurrentPPN[9:0]); - // State transition logic always_comb begin - PRegEn = 1'b0; + //PRegEn = 1'b0; HPTWRead = 1'b0; case (WalkerState) @@ -220,7 +215,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL1_WDV; else begin NextWalkerState = LEVEL1; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL1: begin @@ -236,7 +231,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL0_WDV; else begin NextWalkerState = LEVEL0; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; @@ -265,7 +260,7 @@ module pagetablewalker assign MegapageMisaligned = |(CurrentPPN[8:0]); always_comb begin - PRegEn = 1'b0; + //PRegEn = 1'b0; HPTWRead = 1'b0; case (WalkerState) @@ -277,7 +272,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL3_WDV; else begin NextWalkerState = LEVEL3; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL3: @@ -290,7 +285,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL2_WDV; else begin NextWalkerState = LEVEL2; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL2: @@ -303,7 +298,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL1_WDV; else begin NextWalkerState = LEVEL1; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL1: @@ -316,7 +311,7 @@ module pagetablewalker if (HPTWStall) NextWalkerState = LEVEL0_WDV; else begin NextWalkerState = LEVEL0; - PRegEn = 1'b1; + //PRegEn = 1'b1; end end LEVEL0: diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 46dfd00b..4f805536 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -746,6 +746,7 @@ module riscvassertions(); initial begin assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries"); assert (`F_SUPPORTED || ~`D_SUPPORTED) else $error("Can't support double without supporting float"); + assert (`XLEN == 64 || ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32"); end endmodule From 708f8cc3a25678c3e1aafafa183e5ca6b4b8b133 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:25:52 -0400 Subject: [PATCH 15/30] hptw: factored HPTWRead --- wally-pipelined/src/mmu/pagetablewalker.sv | 62 +++++++++------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index d421a79c..04a84f5c 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -144,10 +144,18 @@ module pagetablewalker assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemStore; assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemStore; - assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // *** not sure about this mux? + always_comb // determine type of page being walked: + case (PreviousWalkerState) + LEVEL3: PageType = 2'b11; // terapage + LEVEL2: PageType = 2'b10; // gigapage + LEVEL1: PageType = 2'b01; // megapage + default: PageType = 2'b00; // kilopage + endcase +/* assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // is ((PreviousWalkerState == LEVEL2) ? 2'b10 : - ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00)); + ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00));*/ assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); + assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // is this really necessary? // *** is there a way to speed up HPTW? @@ -203,36 +211,29 @@ module pagetablewalker // State transition logic always_comb begin - //PRegEn = 1'b0; - HPTWRead = 1'b0; + //HPTWRead = 1'b0; case (WalkerState) IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; else NextWalkerState = IDLE; LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL1_WDV; - else begin - NextWalkerState = LEVEL1; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL1; end LEVEL1: begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL0_SET_ADRE; - HPTWRead = 1'b1; + //HPTWRead = 1'b1; // *** seems this shouldn't be asserted here end else NextWalkerState = FAULT; end LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL0_WDV; - else begin - NextWalkerState = LEVEL0; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL0; end LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; @@ -260,20 +261,16 @@ module pagetablewalker assign MegapageMisaligned = |(CurrentPPN[8:0]); always_comb begin - //PRegEn = 1'b0; - HPTWRead = 1'b0; + //HPTWRead = 1'b0; case (WalkerState) IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; else NextWalkerState = IDLE; LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL3_WDV; - else begin - NextWalkerState = LEVEL3; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL3; end LEVEL3: if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; @@ -281,12 +278,9 @@ module pagetablewalker else NextWalkerState = FAULT; LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; LEVEL2_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL2_WDV; - else begin - NextWalkerState = LEVEL2; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL2; end LEVEL2: if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; @@ -294,12 +288,9 @@ module pagetablewalker else NextWalkerState = FAULT; LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL1_WDV; - else begin - NextWalkerState = LEVEL1; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL1; end LEVEL1: if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; @@ -307,12 +298,9 @@ module pagetablewalker else NextWalkerState = FAULT; LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: begin - HPTWRead = 1'b1; + //HPTWRead = 1'b1; if (HPTWStall) NextWalkerState = LEVEL0_WDV; - else begin - NextWalkerState = LEVEL0; - //PRegEn = 1'b1; - end + else NextWalkerState = LEVEL0; end LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; From fa12727bbba953d44f8b47284e7b4eee1909bd4b Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:25:59 -0400 Subject: [PATCH 16/30] hptw: factored HPTWRead --- wally-pipelined/src/mmu/pagetablewalker.sv | 39 +++++----------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 04a84f5c..23040772 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -211,28 +211,20 @@ module pagetablewalker // State transition logic always_comb begin - //HPTWRead = 1'b0; - - case (WalkerState) +å case (WalkerState) IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; else NextWalkerState = IDLE; LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; - LEVEL1_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL1_WDV; + LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; else NextWalkerState = LEVEL1; - end LEVEL1: begin if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) begin NextWalkerState = LEVEL0_SET_ADRE; - //HPTWRead = 1'b1; // *** seems this shouldn't be asserted here end else NextWalkerState = FAULT; end LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; - LEVEL0_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL0_WDV; + LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; else NextWalkerState = LEVEL0; end LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; @@ -261,47 +253,34 @@ module pagetablewalker assign MegapageMisaligned = |(CurrentPPN[8:0]); always_comb begin - //HPTWRead = 1'b0; - case (WalkerState) IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; else NextWalkerState = IDLE; LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; - LEVEL3_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL3_WDV; + LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; else NextWalkerState = LEVEL3; - end LEVEL3: if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE; else NextWalkerState = FAULT; LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; - LEVEL2_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL2_WDV; + LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; else NextWalkerState = LEVEL2; - end LEVEL2: if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE; else NextWalkerState = FAULT; LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; - LEVEL1_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL1_WDV; + LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; else NextWalkerState = LEVEL1; - end LEVEL1: if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE; else NextWalkerState = FAULT; LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; - LEVEL0_WDV: begin - //HPTWRead = 1'b1; - if (HPTWStall) NextWalkerState = LEVEL0_WDV; - else NextWalkerState = LEVEL0; - end + LEVEL0_WDV: + if (HPTWStall) NextWalkerState = LEVEL0_WDV; + else NextWalkerState = LEVEL0; LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; From 9cee6c22814de0cc0981e3f71b00c8b3b4cdcde0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:31:16 -0400 Subject: [PATCH 17/30] hptw: factored Misaligned --- wally-pipelined/src/mmu/pagetablewalker.sv | 34 +++++++++------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 23040772..0c0855e5 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -78,15 +78,8 @@ module pagetablewalker logic [`PPN_BITS-1:0] CurrentPPN; logic [`SVMODE_BITS-1:0] SvMode; logic MemStore; - - // PTE Control Bits - logic Dirty, Accessed, Global, User, - Executable, Writable, Readable, Valid; - // PTE descriptions - logic ValidPTE, ADPageFault, MegapageMisaligned, BadMegapage, LeafPTE; - - // Outputs of walker - //logic [`XLEN-1:0] PageTableEntry; + logic Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid; + logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; logic StartWalk; logic EndWalk; @@ -203,15 +196,24 @@ module pagetablewalker default: TranslationPAdr = 0; // cause seg fault if this is improperly used endcase end + + if (`XLEN == 32) begin + assign TerapageMisaligned = 0; // not applicable + assign GigapageMisaligned = 0; // not applicable + assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 + end else begin + assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 + assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 + assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 + end // generate if (`XLEN == 32) begin // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. - assign MegapageMisaligned = |(CurrentPPN[9:0]); // State transition logic always_comb begin -å case (WalkerState) + case (WalkerState) IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; else NextWalkerState = IDLE; LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; @@ -226,7 +228,6 @@ module pagetablewalker LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; else NextWalkerState = LEVEL0; - end LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; else NextWalkerState = FAULT; LEAF: NextWalkerState = IDLE; @@ -242,15 +243,6 @@ module pagetablewalker assign HPTWPAdrE = TranslationPAdr[31:0]; end else begin - logic TerapageMisaligned, GigapageMisaligned; - // A terapage is a level 3 leaf page. This page must have zero PPN[2], - // zero PPN[1], and zero PPN[0] - assign TerapageMisaligned = |(CurrentPPN[26:0]); - // A gigapage is a Level 2 leaf page. This page must have zero PPN[1] and - // zero PPN[0] - assign GigapageMisaligned = |(CurrentPPN[17:0]); - // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. - assign MegapageMisaligned = |(CurrentPPN[8:0]); always_comb begin case (WalkerState) From 4469b5a4b3cbb58293b00a38d2143c08b787560d Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:33:16 -0400 Subject: [PATCH 18/30] hptw: default state should be unreachable --- wally-pipelined/src/mmu/pagetablewalker.sv | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 0c0855e5..4e906cc9 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -201,6 +201,7 @@ module pagetablewalker assign TerapageMisaligned = 0; // not applicable assign GigapageMisaligned = 0; // not applicable assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 + assign HPTWPAdrE = TranslationPAdr[31:0]; // ***not right? end else begin assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 @@ -232,15 +233,16 @@ module pagetablewalker else NextWalkerState = FAULT; LEAF: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE; - // Default case should never happen, but is included for linter. - default: NextWalkerState = IDLE; + default: begin + $error("Default state in HPTW should be unreachable") + NextWalkerState = IDLE; // should never be reached + end endcase end // Assign outputs to ahblite // *** Currently truncate address to 32 bits. This must be changed if // we support larger physical address spaces - assign HPTWPAdrE = TranslationPAdr[31:0]; end else begin @@ -278,7 +280,10 @@ module pagetablewalker else NextWalkerState = FAULT; LEAF: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE; - default: NextWalkerState = IDLE; // should never be reached + default: begin + $error("Default state in HPTW should be unreachable") + NextWalkerState = IDLE; // should never be reached + end endcase end From cf0975c93779205f62cef1fcab41361193f7ecc0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:41:43 -0400 Subject: [PATCH 19/30] hptw: FSM simplification --- wally-pipelined/src/mmu/pagetablewalker.sv | 76 ++++++++++------------ 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 4e906cc9..2303f707 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -206,12 +206,10 @@ module pagetablewalker assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 - end + assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; + end // generate if (`XLEN == 32) begin - - // A megapage is a Level 1 leaf page. This page must have zero PPN[0]. - // State transition logic always_comb begin case (WalkerState) @@ -234,7 +232,7 @@ module pagetablewalker LEAF: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE; default: begin - $error("Default state in HPTW should be unreachable") + $error("Default state in HPTW should be unreachable"); NextWalkerState = IDLE; // should never be reached end endcase @@ -248,47 +246,43 @@ module pagetablewalker always_comb begin case (WalkerState) - IDLE: if (AnyTLBMissM) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; - else NextWalkerState = IDLE; - LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; - LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; - else NextWalkerState = LEVEL3; - LEVEL3: - if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE; - else NextWalkerState = FAULT; - LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; - LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; - else NextWalkerState = LEVEL2; - LEVEL2: - if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE; - else NextWalkerState = FAULT; - LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; - LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; - else NextWalkerState = LEVEL1; - LEVEL1: - if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE; - else NextWalkerState = FAULT; - LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; - LEVEL0_WDV: - if (HPTWStall) NextWalkerState = LEVEL0_WDV; - else NextWalkerState = LEVEL0; - LEVEL0: - if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; - else NextWalkerState = FAULT; - LEAF: NextWalkerState = IDLE; - FAULT: NextWalkerState = IDLE; + IDLE: if (AnyTLBMissM) + if (`XLEN == 64) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; + else NextWalkerState = LEVEL1_SET_ADRE; + else NextWalkerState = IDLE; + LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; + LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; + else NextWalkerState = LEVEL3; + LEVEL3: if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; + LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; + else NextWalkerState = LEVEL2; + LEVEL2: if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; + LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; + else NextWalkerState = LEVEL1; + LEVEL1: if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE; + else NextWalkerState = FAULT; + LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; + LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; + else NextWalkerState = LEVEL0; + LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; + else NextWalkerState = FAULT; + LEAF: NextWalkerState = IDLE; + FAULT: NextWalkerState = IDLE; default: begin - $error("Default state in HPTW should be unreachable") - NextWalkerState = IDLE; // should never be reached + $error("Default state in HPTW should be unreachable"); + NextWalkerState = IDLE; // should never be reached end endcase end - assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; - end + end end else begin assign HPTWPAdrE = 0; assign HPTWRead = 0; From 0a6622a6fb6a2a3bf3f4326a28e4929ba35bbf21 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 11:55:24 -0400 Subject: [PATCH 20/30] hptw: Merged RV32/64 FSMs --- wally-pipelined/src/mmu/pagetablewalker.sv | 61 ++++------------------ 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 2303f707..63f57543 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -76,7 +76,6 @@ module pagetablewalker logic [`XLEN-1:0] CurrentPTE; logic [`PA_BITS-1:0] TranslationPAdr; logic [`PPN_BITS-1:0] CurrentPPN; - logic [`SVMODE_BITS-1:0] SvMode; logic MemStore; logic Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid; logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; @@ -89,13 +88,15 @@ module pagetablewalker LEVEL3_SET_ADRE, LEVEL3_WDV, LEVEL3, LEAF, IDLE, FAULT} statetype; - statetype WalkerState, NextWalkerState, PreviousWalkerState; + statetype WalkerState, NextWalkerState, PreviousWalkerState, InitialWalkerState; logic PRegEn; logic SelDataTranslation; logic AnyTLBMissM; + logic [`SVMODE_BITS-1:0] SvMode; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; + assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; assign MemStore = MemRWM[0]; @@ -115,11 +116,8 @@ module pagetablewalker assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM; assign EndWalk = (WalkerState == LEAF) || (WalkerState == FAULT); - // unswizzle PTE bits - assign {Dirty, Accessed, Global, User, - Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; - // Assign PTE descriptors common across all XLEN values + assign {Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); assign ADPageFault = ~Accessed | (MemStore & ~Dirty); @@ -144,9 +142,6 @@ module pagetablewalker LEVEL1: PageType = 2'b01; // megapage default: PageType = 2'b00; // kilopage endcase -/* assign PageType = (PreviousWalkerState == LEVEL3) ? 2'b11 : // is - ((PreviousWalkerState == LEVEL2) ? 2'b10 : - ((PreviousWalkerState == LEVEL1) ? 2'b01 : 2'b00));*/ assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // is this really necessary? @@ -198,57 +193,22 @@ module pagetablewalker end if (`XLEN == 32) begin + assign InitialWalkerState = LEVEL1_SET_ADRE; assign TerapageMisaligned = 0; // not applicable assign GigapageMisaligned = 0; // not applicable assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 assign HPTWPAdrE = TranslationPAdr[31:0]; // ***not right? end else begin + assign InitialWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; end - // generate - if (`XLEN == 32) begin - // State transition logic - always_comb begin + + always_comb case (WalkerState) - IDLE: if (AnyTLBMissM & SvMode == `SV32) NextWalkerState = LEVEL1_SET_ADRE; - else NextWalkerState = IDLE; - LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; - LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; - else NextWalkerState = LEVEL1; - LEVEL1: begin - if (ValidPTE && LeafPTE && ~(MegapageMisaligned | ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) begin - NextWalkerState = LEVEL0_SET_ADRE; - end else NextWalkerState = FAULT; - end - LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; - LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; - else NextWalkerState = LEVEL0; - LEVEL0: if (ValidPTE & LeafPTE & ~ADPageFault) NextWalkerState = LEAF; - else NextWalkerState = FAULT; - LEAF: NextWalkerState = IDLE; - FAULT: NextWalkerState = IDLE; - default: begin - $error("Default state in HPTW should be unreachable"); - NextWalkerState = IDLE; // should never be reached - end - endcase - end - - // Assign outputs to ahblite - // *** Currently truncate address to 32 bits. This must be changed if - // we support larger physical address spaces - - end else begin - - always_comb begin - case (WalkerState) - IDLE: if (AnyTLBMissM) - if (`XLEN == 64) NextWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; - else NextWalkerState = LEVEL1_SET_ADRE; + IDLE: if (AnyTLBMissM) NextWalkerState = InitialWalkerState; else NextWalkerState = IDLE; LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; @@ -279,10 +239,7 @@ module pagetablewalker $error("Default state in HPTW should be unreachable"); NextWalkerState = IDLE; // should never be reached end - endcase - end - end end else begin assign HPTWPAdrE = 0; assign HPTWRead = 0; From 784e6cf5389e945d59116e4eb3c89e90b67f3a35 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 12:01:43 -0400 Subject: [PATCH 21/30] hptw: Renamed Memstore to MemWrite --- wally-pipelined/src/mmu/pagetablewalker.sv | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 63f57543..5ca42801 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -76,7 +76,7 @@ module pagetablewalker logic [`XLEN-1:0] CurrentPTE; logic [`PA_BITS-1:0] TranslationPAdr; logic [`PPN_BITS-1:0] CurrentPPN; - logic MemStore; + logic MemWrite; logic Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid; logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; logic StartWalk; @@ -96,9 +96,9 @@ module pagetablewalker logic [`SVMODE_BITS-1:0] SvMode; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; - + assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; - assign MemStore = MemRWM[0]; + assign MemWrite = MemRWM[0]; // Prefer data address translations over instruction address translations assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; @@ -120,7 +120,7 @@ module pagetablewalker assign {Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); - assign ADPageFault = ~Accessed | (MemStore & ~Dirty); + assign ADPageFault = ~Accessed | (MemWrite & ~Dirty); // Assign specific outputs to general outputs // *** try to eliminate this duplication, but attempts caused MMU to hang @@ -132,8 +132,8 @@ module pagetablewalker assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ; assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBMissMQ; //*** why do these only get raised on TLB misses? Should they always fault even for ADpagefaults, invalid addresses,etc?? - assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemStore; - assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemStore; + assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemWrite; + assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemWrite; always_comb // determine type of page being walked: case (PreviousWalkerState) @@ -206,6 +206,7 @@ module pagetablewalker assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; end + // Walker FSM always_comb case (WalkerState) IDLE: if (AnyTLBMissM) NextWalkerState = InitialWalkerState; From ea2aa469a1df0d20a8f70fcf449d9af8908359c0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 12:07:51 -0400 Subject: [PATCH 22/30] hptw: Simplifed out AnyTLBMiss --- wally-pipelined/src/mmu/pagetablewalker.sv | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 5ca42801..cd080a8f 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -92,7 +92,6 @@ module pagetablewalker logic PRegEn; logic SelDataTranslation; - logic AnyTLBMissM; logic [`SVMODE_BITS-1:0] SvMode; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; @@ -111,14 +110,12 @@ module pagetablewalker flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; - assign AnyTLBMissM = DTLBMissM | ITLBMissF; - - assign StartWalk = (WalkerState == IDLE) & AnyTLBMissM; + assign StartWalk = (WalkerState == IDLE) & (DTLBMissM | ITLBMissF); assign EndWalk = (WalkerState == LEAF) || (WalkerState == FAULT); // Assign PTE descriptors common across all XLEN values assign {Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; - assign LeafPTE = Executable | Writable | Readable; + assign LeafPTE = Executable | Readable; // leaf PTE never has only Writable assign ValidPTE = Valid && ~(Writable && ~Readable); assign ADPageFault = ~Accessed | (MemWrite & ~Dirty); @@ -209,7 +206,7 @@ module pagetablewalker // Walker FSM always_comb case (WalkerState) - IDLE: if (AnyTLBMissM) NextWalkerState = InitialWalkerState; + IDLE: if (StartWalk) NextWalkerState = InitialWalkerState; else NextWalkerState = IDLE; LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; From 87aa527de7a2145ef2e1592a2c82849fd84d2d62 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 13:40:12 -0400 Subject: [PATCH 23/30] hptw: minor cleanup --- wally-pipelined/regression/wally-busybear-batch.do | 1 - wally-pipelined/regression/wally-pipelined-batch.do | 7 +++++++ wally-pipelined/src/lsu/lsu.sv | 2 -- wally-pipelined/src/lsu/lsuArb.sv | 3 --- wally-pipelined/src/mmu/pagetablewalker.sv | 4 +--- wally-pipelined/testbench/testbench-imperas.sv | 7 +------ 6 files changed, 9 insertions(+), 15 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear-batch.do b/wally-pipelined/regression/wally-busybear-batch.do index e2817dfa..e9beed4c 100644 --- a/wally-pipelined/regression/wally-busybear-batch.do +++ b/wally-pipelined/regression/wally-busybear-batch.do @@ -32,7 +32,6 @@ vlog -work work_busybear +incdir+../config/busybear +incdir+../config/shared .. # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals vopt work_busybear.testbench -o workopt_busybear - vsim workopt_busybear -suppress 8852,12070 run -all diff --git a/wally-pipelined/regression/wally-pipelined-batch.do b/wally-pipelined/regression/wally-pipelined-batch.do index 49ed8cf7..1e67b836 100644 --- a/wally-pipelined/regression/wally-pipelined-batch.do +++ b/wally-pipelined/regression/wally-pipelined-batch.do @@ -38,6 +38,13 @@ switch $argc { # remove +acc flag for faster sim during regressions if there is no need to access internal signals vopt work_$2.testbench -work work_$2 -o workopt_$2 vsim -lib work_$2 workopt_$2 +# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time +#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf +#vsim -coverage -lib work_$2 workopt_$2 run -all +#coverage report -file wally-pipelined-coverage.txt +# These aren't doing anything helpful +#coverage report -memory +#profile report -calltree -file wally-pipelined-calltree.rpt -cutoff 2 quit diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index 46f174a9..81a22f79 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -121,7 +121,6 @@ module lsu logic [`XLEN-1:0] PageTableEntryM; logic DTLBWriteM; logic [`XLEN-1:0] HPTWReadPTE; - logic MMUReady; logic HPTWStall; logic [`XLEN-1:0] HPTWPAdrE; logic [`XLEN-1:0] HPTWPAdrM; @@ -164,7 +163,6 @@ module lsu .ITLBWriteF(ITLBWriteF), .DTLBWriteM(DTLBWriteM), .HPTWReadPTE(HPTWReadPTE), - .MMUReady(HPTWReady), .HPTWStall(HPTWStall), .HPTWPAdrE(HPTWPAdrE), .HPTWPAdrM(HPTWPAdrM), diff --git a/wally-pipelined/src/lsu/lsuArb.sv b/wally-pipelined/src/lsu/lsuArb.sv index 13a77243..d84c2d60 100644 --- a/wally-pipelined/src/lsu/lsuArb.sv +++ b/wally-pipelined/src/lsu/lsuArb.sv @@ -34,8 +34,6 @@ module lsuArb input logic HPTWRead, input logic [`XLEN-1:0] HPTWPAdrE, input logic [`XLEN-1:0] HPTWPAdrM, - // to page table walker. - //output logic [`XLEN-1:0] HPTWReadPTE, output logic HPTWStall, // from CPU @@ -94,7 +92,6 @@ module lsuArb // demux the inputs from LSU to walker or cpu's data port. assign ReadDataW = SelPTW ? `XLEN'b0 : ReadDataWfromDCache; // probably can avoid this demux - //assign HPTWReadPTE = SelPTW ? ReadDataWfromDCache : `XLEN'b0 ; // probably can avoid this demux assign SquashSCW = SelPTW ? 1'b0 : SquashSCWfromDCache; assign DataMisalignedM = SelPTW ? 1'b0 : DataMisalignedMfromDCache; // *** need to rename DcacheStall and Datastall. diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index cd080a8f..02d20632 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -49,7 +49,6 @@ module pagetablewalker // *** modify to send to LSU // *** KMG: These are inputs/results from the ahblite whose addresses should have already been checked, so I don't think they need to be sent through the LSU input logic [`XLEN-1:0] HPTWReadPTE, - input logic MMUReady, input logic HPTWStall, // *** modify to send to LSU @@ -140,8 +139,7 @@ module pagetablewalker default: PageType = 2'b00; // kilopage endcase assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); - assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // is this really necessary? - + assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // *** is there a way to speed up HPTW? // TranslationPAdr mux diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 4f805536..8559c555 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -283,7 +283,6 @@ string tests32f[] = '{ "rv64i/WALLY-SLLI", "3000", "rv64i/WALLY-SRLI", "3000", "rv64i/WALLY-SRAI", "3000", - "rv64i/WALLY-JAL", "4000", "rv64i/WALLY-JALR", "3000", "rv64i/WALLY-STORE", "3000", @@ -511,11 +510,7 @@ string tests32f[] = '{ logic [`XLEN-1:0] PCW; logic DCacheFlushDone, DCacheFlushStart; - - - logic [`XLEN-1:0] debug; - assign debug = dut.uncore.dtim.RAM[536872960]; - + flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); From 89fd653cc1be5c2c74143050ad92130baf19b799 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 13:44:08 -0400 Subject: [PATCH 24/30] hptw: removed ITLBMissFQ --- wally-pipelined/src/mmu/pagetablewalker.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 02d20632..09f43939 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -68,7 +68,7 @@ module pagetablewalker if (`MEM_VIRTMEM) begin // Internal signals // register TLBs translation miss requests - logic ITLBMissFQ, DTLBMissMQ; + logic DTLBMissMQ; logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`XLEN-1:0] TranslationVAdr; @@ -103,7 +103,7 @@ module pagetablewalker assign SelDataTranslation = DTLBMissMQ | DTLBMissM; flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); - flopenrc #(2) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, {DTLBMissM, ITLBMissF}, {DTLBMissMQ, ITLBMissFQ}); + flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBMissMQ); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache From 3ce22a60b3ee3b005819647475066255a673bad2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 13:54:58 -0400 Subject: [PATCH 25/30] hptw: replaced PreviousWalkerState with a PageType FSM --- wally-pipelined/src/mmu/pagetablewalker.sv | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 09f43939..bf662e37 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -80,6 +80,7 @@ module pagetablewalker logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; logic StartWalk; logic EndWalk; + logic [1:0] NextPageType; typedef enum {LEVEL0_SET_ADRE, LEVEL0_WDV, LEVEL0, LEVEL1_SET_ADRE, LEVEL1_WDV, LEVEL1, @@ -87,7 +88,7 @@ module pagetablewalker LEVEL3_SET_ADRE, LEVEL3_WDV, LEVEL3, LEAF, IDLE, FAULT} statetype; - statetype WalkerState, NextWalkerState, PreviousWalkerState, InitialWalkerState; + statetype WalkerState, NextWalkerState, InitialWalkerState; logic PRegEn; logic SelDataTranslation; @@ -105,7 +106,7 @@ module pagetablewalker flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBMissMQ); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); - flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); + // flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; @@ -131,17 +132,28 @@ module pagetablewalker assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemWrite; assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemWrite; - always_comb // determine type of page being walked: +/* always_comb // determine type of page being walked: case (PreviousWalkerState) LEVEL3: PageType = 2'b11; // terapage LEVEL2: PageType = 2'b10; // gigapage LEVEL1: PageType = 2'b01; // megapage default: PageType = 2'b00; // kilopage - endcase + endcase*/ assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // *** is there a way to speed up HPTW? + // FSM to track PageType based on the levels of the page table traversed + flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); + always_comb + case (WalkerState) + LEVEL3: NextPageType = 2'b11; // terapage + LEVEL2: NextPageType = 2'b10; // gigapage + LEVEL1: NextPageType = 2'b01; // megapage + LEVEL0: NextPageType = 2'b00; // kilopage + default: NextPageType = PageType; + endcase + // TranslationPAdr mux if (`XLEN==32) begin logic [9:0] VPN1, VPN0; From 6f22e9a39360b26e848dff063e47de3d23030b69 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 14:02:59 -0400 Subject: [PATCH 26/30] hptw: renamed ADRE to ADR --- wally-pipelined/src/mmu/pagetablewalker.sv | 52 +++++++++------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index bf662e37..d69c089c 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -82,10 +82,10 @@ module pagetablewalker logic EndWalk; logic [1:0] NextPageType; - typedef enum {LEVEL0_SET_ADRE, LEVEL0_WDV, LEVEL0, - LEVEL1_SET_ADRE, LEVEL1_WDV, LEVEL1, - LEVEL2_SET_ADRE, LEVEL2_WDV, LEVEL2, - LEVEL3_SET_ADRE, LEVEL3_WDV, LEVEL3, + typedef enum {LEVEL0_SET_ADR, LEVEL0_WDV, LEVEL0, + LEVEL1_SET_ADR, LEVEL1_WDV, LEVEL1, + LEVEL2_SET_ADR, LEVEL2_WDV, LEVEL2, + LEVEL3_SET_ADR, LEVEL3_WDV, LEVEL3, LEAF, IDLE, FAULT} statetype; statetype WalkerState, NextWalkerState, InitialWalkerState; @@ -106,7 +106,6 @@ module pagetablewalker flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBMissMQ); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); - // flopenl #(.TYPE(statetype)) PreviousWalkerStateReg(clk, reset, 1'b1, WalkerState, IDLE, PreviousWalkerState); flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; @@ -132,13 +131,6 @@ module pagetablewalker assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemWrite; assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemWrite; -/* always_comb // determine type of page being walked: - case (PreviousWalkerState) - LEVEL3: PageType = 2'b11; // terapage - LEVEL2: PageType = 2'b10; // gigapage - LEVEL1: PageType = 2'b01; // megapage - default: PageType = 2'b00; // kilopage - endcase*/ assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); // *** is there a way to speed up HPTW? @@ -161,11 +153,11 @@ module pagetablewalker assign VPN0 = TranslationVAdr[21:12]; always_comb case (WalkerState) - LEVEL1_SET_ADRE: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + LEVEL1_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; LEVEL1_WDV: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; - LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this and similar - else TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; - LEVEL0_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this and similar in LEVEL0 and LEAF + else TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; LEVEL0: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; LEAF: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; @@ -179,19 +171,19 @@ module pagetablewalker assign VPN0 = TranslationVAdr[20:12]; always_comb case (WalkerState) - LEVEL3_SET_ADRE: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + LEVEL3_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; LEVEL3_WDV: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; LEVEL3: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; - LEVEL2_SET_ADRE: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + LEVEL2_SET_ADR: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; LEVEL2_WDV: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; LEVEL2: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; - LEVEL1_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + LEVEL1_SET_ADR: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; LEVEL1_WDV: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; - LEVEL0_SET_ADRE: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; LEVEL0: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; LEAF: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; @@ -200,43 +192,43 @@ module pagetablewalker end if (`XLEN == 32) begin - assign InitialWalkerState = LEVEL1_SET_ADRE; + assign InitialWalkerState = LEVEL1_SET_ADR; assign TerapageMisaligned = 0; // not applicable assign GigapageMisaligned = 0; // not applicable assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 assign HPTWPAdrE = TranslationPAdr[31:0]; // ***not right? end else begin - assign InitialWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADRE : LEVEL2_SET_ADRE; + assign InitialWalkerState = (SvMode == `SV48) ? LEVEL3_SET_ADR : LEVEL2_SET_ADR; assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 assign HPTWPAdrE = {{(`XLEN-`PA_BITS){1'b0}}, TranslationPAdr[`PA_BITS-1:0]}; end - // Walker FSM + // Page Table Walker FSM always_comb case (WalkerState) IDLE: if (StartWalk) NextWalkerState = InitialWalkerState; else NextWalkerState = IDLE; - LEVEL3_SET_ADRE: NextWalkerState = LEVEL3_WDV; + LEVEL3_SET_ADR: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; else NextWalkerState = LEVEL3; LEVEL3: if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADRE; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADR; else NextWalkerState = FAULT; - LEVEL2_SET_ADRE: NextWalkerState = LEVEL2_WDV; + LEVEL2_SET_ADR: NextWalkerState = LEVEL2_WDV; LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; else NextWalkerState = LEVEL2; LEVEL2: if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADRE; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADR; else NextWalkerState = FAULT; - LEVEL1_SET_ADRE: NextWalkerState = LEVEL1_WDV; + LEVEL1_SET_ADR: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; else NextWalkerState = LEVEL1; LEVEL1: if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADRE; + else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADR; else NextWalkerState = FAULT; - LEVEL0_SET_ADRE: NextWalkerState = LEVEL0_WDV; + LEVEL0_SET_ADR: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; else NextWalkerState = LEVEL0; LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; From 42aee1db30a13e2bdc36f1f0a21efc145e339eea Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 14:13:00 -0400 Subject: [PATCH 27/30] hptw: renamed DTLBMissQ to DTLBWalk --- wally-pipelined/src/mmu/pagetablewalker.sv | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index d69c089c..86cd3d24 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -68,7 +68,7 @@ module pagetablewalker if (`MEM_VIRTMEM) begin // Internal signals // register TLBs translation miss requests - logic DTLBMissMQ; + logic DTLBWalk; logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`XLEN-1:0] TranslationVAdr; @@ -100,11 +100,11 @@ module pagetablewalker assign MemWrite = MemRWM[0]; // Prefer data address translations over instruction address translations - assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; - assign SelDataTranslation = DTLBMissMQ | DTLBMissM; - + assign SelDataTranslation = DTLBWalk | DTLBMissM; // *** missM is probably unnecessary + assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; + flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); - flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBMissMQ); + flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBWalk); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, CurrentPTE); // Capture page table entry from data cache assign CurrentPPN = CurrentPTE[`PPN_BITS+9:10]; @@ -124,16 +124,16 @@ module pagetablewalker assign PageTableEntryM = CurrentPTE; assign SelPTW = (WalkerState != IDLE) & (WalkerState != FAULT); - assign DTLBWriteM = (WalkerState == LEAF) & DTLBMissMQ; - assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBMissMQ; + assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk; + assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk; - assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBMissMQ; //*** why do these only get raised on TLB misses? Should they always fault even for ADpagefaults, invalid addresses,etc?? - assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBMissMQ & ~MemWrite; - assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBMissMQ & MemWrite; + // Raise faults. DTLBMiss + assign WalkerInstrPageFaultF = (WalkerState == FAULT) & ~DTLBWalk; + assign WalkerLoadPageFaultM = (WalkerState == FAULT) & DTLBWalk & ~MemWrite; + assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBWalk & MemWrite; assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); - // *** is there a way to speed up HPTW? // FSM to track PageType based on the levels of the page table traversed flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); @@ -206,6 +206,7 @@ module pagetablewalker end // Page Table Walker FSM + // ***Is there a w ay to reduce the number of cycles needed to do the walk? always_comb case (WalkerState) IDLE: if (StartWalk) NextWalkerState = InitialWalkerState; From 90c5312f85637db7f3e92ddebd42ef89a6a0b485 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 14:16:33 -0400 Subject: [PATCH 28/30] hptw: Simplified TranslationVAdr calculation based just on DTLBWalk --- wally-pipelined/src/mmu/pagetablewalker.sv | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 86cd3d24..6ab7576b 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -80,6 +80,7 @@ module pagetablewalker logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; logic StartWalk; logic EndWalk; + logic PRegEn; logic [1:0] NextPageType; typedef enum {LEVEL0_SET_ADR, LEVEL0_WDV, LEVEL0, @@ -90,18 +91,14 @@ module pagetablewalker statetype WalkerState, NextWalkerState, InitialWalkerState; - logic PRegEn; - logic SelDataTranslation; - logic [`SVMODE_BITS-1:0] SvMode; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; assign MemWrite = MemRWM[0]; - // Prefer data address translations over instruction address translations - assign SelDataTranslation = DTLBWalk | DTLBMissM; // *** missM is probably unnecessary - assign TranslationVAdr = (SelDataTranslation) ? MemAdrM : PCF; + // Determine which address to translate + assign TranslationVAdr = DTLBWalk ? MemAdrM : PCF; flop #(`XLEN) HPTWPAdrMReg(clk, HPTWPAdrE, HPTWPAdrM); flopenrc #(1) TLBMissMReg(clk, reset, EndWalk, StartWalk | EndWalk, DTLBMissM, DTLBWalk); From 714eef4a1a738eb61eef86bbd46a7824980b2c7b Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 14:29:20 -0400 Subject: [PATCH 29/30] hptw: Eliminated A and D bit faults while walking page table, per spec --- wally-pipelined/src/mmu/pagetablewalker.sv | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 6ab7576b..f94d31c2 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -76,8 +76,8 @@ module pagetablewalker logic [`PA_BITS-1:0] TranslationPAdr; logic [`PPN_BITS-1:0] CurrentPPN; logic MemWrite; - logic Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid; - logic ValidPTE, ADPageFault, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; + logic Executable, Writable, Readable, Valid; + logic ValidPTE, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; logic StartWalk; logic EndWalk; logic PRegEn; @@ -110,11 +110,11 @@ module pagetablewalker assign EndWalk = (WalkerState == LEAF) || (WalkerState == FAULT); // Assign PTE descriptors common across all XLEN values - assign {Dirty, Accessed, Global, User, Executable, Writable, Readable, Valid} = CurrentPTE[7:0]; - assign LeafPTE = Executable | Readable; // leaf PTE never has only Writable + // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table + assign {Executable, Writable, Readable, Valid} = CurrentPTE[3:0]; + assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); - assign ADPageFault = ~Accessed | (MemWrite & ~Dirty); - + // Assign specific outputs to general outputs // *** try to eliminate this duplication, but attempts caused MMU to hang assign PageTableEntryF = CurrentPTE; @@ -211,25 +211,25 @@ module pagetablewalker LEVEL3_SET_ADR: NextWalkerState = LEVEL3_WDV; LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; else NextWalkerState = LEVEL3; - LEVEL3: if (ValidPTE && LeafPTE && ~(TerapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + LEVEL3: if (ValidPTE && LeafPTE && ~TerapageMisaligned) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADR; else NextWalkerState = FAULT; LEVEL2_SET_ADR: NextWalkerState = LEVEL2_WDV; LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; else NextWalkerState = LEVEL2; - LEVEL2: if (ValidPTE && LeafPTE && ~(GigapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + LEVEL2: if (ValidPTE && LeafPTE && ~GigapageMisaligned) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADR; else NextWalkerState = FAULT; LEVEL1_SET_ADR: NextWalkerState = LEVEL1_WDV; LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; else NextWalkerState = LEVEL1; - LEVEL1: if (ValidPTE && LeafPTE && ~(MegapageMisaligned || ADPageFault)) NextWalkerState = LEAF; + LEVEL1: if (ValidPTE && LeafPTE && ~MegapageMisaligned) NextWalkerState = LEAF; else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADR; else NextWalkerState = FAULT; LEVEL0_SET_ADR: NextWalkerState = LEVEL0_WDV; LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; else NextWalkerState = LEVEL0; - LEVEL0: if (ValidPTE && LeafPTE && ~ADPageFault) NextWalkerState = LEAF; + LEVEL0: if (ValidPTE && LeafPTE) NextWalkerState = LEAF; else NextWalkerState = FAULT; LEAF: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE; From 86e04c080d39be9b5d0877a1cd6cd3cf338386a5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 14:36:27 -0400 Subject: [PATCH 30/30] hptw: Added ValidLeaf and ValidNonLeaf for readability, renamed _WDV to _READ states --- wally-pipelined/src/mmu/pagetablewalker.sv | 57 ++++++++++++---------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index f94d31c2..c475919b 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -77,16 +77,17 @@ module pagetablewalker logic [`PPN_BITS-1:0] CurrentPPN; logic MemWrite; logic Executable, Writable, Readable, Valid; - logic ValidPTE, MegapageMisaligned, TerapageMisaligned, GigapageMisaligned, BadMegapage, LeafPTE; + logic MegapageMisaligned, GigapageMisaligned, TerapageMisaligned; + logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; logic StartWalk; logic EndWalk; logic PRegEn; logic [1:0] NextPageType; - typedef enum {LEVEL0_SET_ADR, LEVEL0_WDV, LEVEL0, - LEVEL1_SET_ADR, LEVEL1_WDV, LEVEL1, - LEVEL2_SET_ADR, LEVEL2_WDV, LEVEL2, - LEVEL3_SET_ADR, LEVEL3_WDV, LEVEL3, + typedef enum {LEVEL0_SET_ADR, LEVEL0_READ, LEVEL0, + LEVEL1_SET_ADR, LEVEL1_READ, LEVEL1, + LEVEL2_SET_ADR, LEVEL2_READ, LEVEL2, + LEVEL3_SET_ADR, LEVEL3_READ, LEVEL3, LEAF, IDLE, FAULT} statetype; statetype WalkerState, NextWalkerState, InitialWalkerState; @@ -114,6 +115,8 @@ module pagetablewalker assign {Executable, Writable, Readable, Valid} = CurrentPTE[3:0]; assign LeafPTE = Executable | Writable | Readable; assign ValidPTE = Valid && ~(Writable && ~Readable); + assign ValidLeafPTE = ValidPTE & LeafPTE; + assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; // Assign specific outputs to general outputs // *** try to eliminate this duplication, but attempts caused MMU to hang @@ -130,7 +133,7 @@ module pagetablewalker assign WalkerStorePageFaultM = (WalkerState == FAULT) & DTLBWalk & MemWrite; assign PRegEn = (NextWalkerState == LEVEL3) | (NextWalkerState == LEVEL2) | (NextWalkerState == LEVEL1) | (NextWalkerState == LEVEL0); - assign HPTWRead = (WalkerState == LEVEL3_WDV) | (WalkerState == LEVEL2_WDV) | (WalkerState == LEVEL1_WDV) | (WalkerState == LEVEL0_WDV); + assign HPTWRead = (WalkerState == LEVEL3_READ) | (WalkerState == LEVEL2_READ) | (WalkerState == LEVEL1_READ) | (WalkerState == LEVEL0_READ); // FSM to track PageType based on the levels of the page table traversed flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); @@ -151,11 +154,11 @@ module pagetablewalker always_comb case (WalkerState) LEVEL1_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; - LEVEL1_WDV: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; + LEVEL1_READ: TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00}; LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; // ***check this and similar in LEVEL0 and LEAF else TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; - LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; + LEVEL0_READ: TranslationPAdr = {CurrentPPN, VPN0, 2'b00}; LEVEL0: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; LEAF: TranslationPAdr = {2'b00, TranslationVAdr[31:0]}; default: TranslationPAdr = 0; // cause seg fault if this is improperly used @@ -169,19 +172,19 @@ module pagetablewalker always_comb case (WalkerState) LEVEL3_SET_ADR: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; - LEVEL3_WDV: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; + LEVEL3_READ: TranslationPAdr = {BasePageTablePPN, VPN3, 3'b000}; LEVEL3: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; LEVEL2_SET_ADR: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; - LEVEL2_WDV: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; + LEVEL2_READ: TranslationPAdr = {(SvMode == `SV48) ? CurrentPPN : BasePageTablePPN, VPN2, 3'b000}; LEVEL2: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; LEVEL1_SET_ADR: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; - LEVEL1_WDV: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; + LEVEL1_READ: TranslationPAdr = {CurrentPPN, VPN1, 3'b000}; LEVEL1: if (NextWalkerState == LEAF) TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; else TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; LEVEL0_SET_ADR: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; - LEVEL0_WDV: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; + LEVEL0_READ: TranslationPAdr = {CurrentPPN, VPN0, 3'b000}; LEVEL0: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; LEAF: TranslationPAdr = TranslationVAdr[`PA_BITS-1:0]; default: TranslationPAdr = 0; // cause seg fault if this is improperly used @@ -208,28 +211,28 @@ module pagetablewalker case (WalkerState) IDLE: if (StartWalk) NextWalkerState = InitialWalkerState; else NextWalkerState = IDLE; - LEVEL3_SET_ADR: NextWalkerState = LEVEL3_WDV; - LEVEL3_WDV: if (HPTWStall) NextWalkerState = LEVEL3_WDV; + LEVEL3_SET_ADR: NextWalkerState = LEVEL3_READ; + LEVEL3_READ: if (HPTWStall) NextWalkerState = LEVEL3_READ; else NextWalkerState = LEVEL3; - LEVEL3: if (ValidPTE && LeafPTE && ~TerapageMisaligned) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL2_SET_ADR; + LEVEL3: if (ValidLeafPTE && ~TerapageMisaligned) NextWalkerState = LEAF; + else if (ValidNonLeafPTE) NextWalkerState = LEVEL2_SET_ADR; else NextWalkerState = FAULT; - LEVEL2_SET_ADR: NextWalkerState = LEVEL2_WDV; - LEVEL2_WDV: if (HPTWStall) NextWalkerState = LEVEL2_WDV; + LEVEL2_SET_ADR: NextWalkerState = LEVEL2_READ; + LEVEL2_READ: if (HPTWStall) NextWalkerState = LEVEL2_READ; else NextWalkerState = LEVEL2; - LEVEL2: if (ValidPTE && LeafPTE && ~GigapageMisaligned) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL1_SET_ADR; + LEVEL2: if (ValidLeafPTE && ~GigapageMisaligned) NextWalkerState = LEAF; + else if (ValidNonLeafPTE) NextWalkerState = LEVEL1_SET_ADR; else NextWalkerState = FAULT; - LEVEL1_SET_ADR: NextWalkerState = LEVEL1_WDV; - LEVEL1_WDV: if (HPTWStall) NextWalkerState = LEVEL1_WDV; + LEVEL1_SET_ADR: NextWalkerState = LEVEL1_READ; + LEVEL1_READ: if (HPTWStall) NextWalkerState = LEVEL1_READ; else NextWalkerState = LEVEL1; - LEVEL1: if (ValidPTE && LeafPTE && ~MegapageMisaligned) NextWalkerState = LEAF; - else if (ValidPTE && ~LeafPTE) NextWalkerState = LEVEL0_SET_ADR; + LEVEL1: if (ValidLeafPTE && ~MegapageMisaligned) NextWalkerState = LEAF; + else if (ValidNonLeafPTE) NextWalkerState = LEVEL0_SET_ADR; else NextWalkerState = FAULT; - LEVEL0_SET_ADR: NextWalkerState = LEVEL0_WDV; - LEVEL0_WDV: if (HPTWStall) NextWalkerState = LEVEL0_WDV; + LEVEL0_SET_ADR: NextWalkerState = LEVEL0_READ; + LEVEL0_READ: if (HPTWStall) NextWalkerState = LEVEL0_READ; else NextWalkerState = LEVEL0; - LEVEL0: if (ValidPTE && LeafPTE) NextWalkerState = LEAF; + LEVEL0: if (ValidLeafPTE) NextWalkerState = LEAF; else NextWalkerState = FAULT; LEAF: NextWalkerState = IDLE; FAULT: NextWalkerState = IDLE;