From 8241dd4599b0bc3f1db21836e40faf7a61e8d6b8 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 17 Jul 2021 03:10:17 -0400 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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;