From 1b39481a16b909461619888b6cc4151036c2563c Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 12:53:52 -0400 Subject: [PATCH 1/7] TLB mux and swizzling cleanup --- wally-pipelined/src/mmu/tlb.sv | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index bd365280..6d8ed46a 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -101,6 +101,7 @@ module tlb #(parameter ENTRY_BITS = 3, logic [`VPN_BITS-1:0] VirtualPageNumber; logic [`PPN_BITS-1:0] PhysicalPageNumber, PhysicalPageNumberMixed; logic [`PA_BITS-1:0] PhysicalAddressFull; + logic [`XLEN+1:0] VAExt; // Sections of the page table entry logic [7:0] PTEAccessBits; @@ -137,7 +138,7 @@ module tlb #(parameter ENTRY_BITS = 3, endgenerate // Whether translation should occur - assign Translate = (SvMode != `NO_TRANSLATE) & (PrivilegeModeW != `M_MODE) & ~ DisableTranslation; + assign Translate = (SvMode != `NO_TRANSLATE) & (PrivilegeModeW != `M_MODE) & ~ DisableTranslation; // *** needs to account for mprv // Determine how the TLB is currently being used // Note that we use ReadAccess for both loads and instruction fetches @@ -155,11 +156,8 @@ module tlb #(parameter ENTRY_BITS = 3, tlbcam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlbcam(.*); // unswizzle useful PTE bits - assign PTE_U = PTEAccessBits[4]; - assign PTE_X = PTEAccessBits[3]; - assign PTE_W = PTEAccessBits[2]; - assign PTE_R = PTEAccessBits[1]; - + assign {PTE_U, PTE_X, PTE_W, PTE_R} = PTEAccessBits[4:1]; + // Check whether the access is allowed, page faulting if not. // *** We might not have S mode. generate @@ -198,17 +196,22 @@ module tlb #(parameter ENTRY_BITS = 3, // Provide physical address only on TLBHits to cause catastrophic errors if // garbage address is used. - assign PhysicalAddressFull = (TLBHit) ? - {PhysicalPageNumberMixed, PageOffset} : '0; + assign PhysicalAddressFull = (TLBHit) ? {PhysicalPageNumberMixed, PageOffset} : '0; // Output the hit physical address if translation is currently on. - generate +/* generate if (`XLEN == 32) begin + VirtualAddressPALen = {2'b0, VirtualAddress}; + mux2 #(`PA_BITS) addressmux({2'b0, VirtualAddress}, PhysicalAddressFull, Translate, PhysicalAddress); end else begin + VirtualAddressPALen = VirtualAddress[`PA_BITS-1:0]; mux2 #(`PA_BITS) addressmux(VirtualAddress[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress); end - endgenerate + endgenerate*/ + + assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32 + mux2 #(`PA_BITS) addressmux(VAExt[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress); assign TLBHit = CAMHit & TLBAccess; assign TLBMiss = ~TLBHit & ~TLBFlush & Translate & TLBAccess; From 7e22ae973e0c4b4fc0368130481ba1a74c5d0276 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 13:20:29 -0400 Subject: [PATCH 2/7] Fixed MPRV and MXR checks in TLB --- wally-pipelined/src/ifu/ifu.sv | 3 +- wally-pipelined/src/lsu/lsu.sv | 3 +- wally-pipelined/src/mmu/mmu.sv | 3 +- wally-pipelined/src/mmu/tlb.sv | 29 ++++++++++--------- wally-pipelined/src/privileged/csr.sv | 3 +- wally-pipelined/src/privileged/privileged.sv | 6 ++-- .../src/wally/wallypipelinedhart.sv | 3 +- 7 files changed, 28 insertions(+), 22 deletions(-) diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 714119e6..65f8a9b8 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -70,7 +70,8 @@ module ifu ( input logic [`XLEN-1:0] PageTableEntryF, input logic [1:0] PageTypeF, input logic [`XLEN-1:0] SATP_REGW, - input logic STATUS_MXR, STATUS_SUM, + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, input logic ITLBWriteF, ITLBFlushF, input logic WalkerInstrPageFaultF, diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index 2a88b25f..d7ff78d7 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -75,7 +75,8 @@ module lsu ( input logic [`XLEN-1:0] PageTableEntryM, input logic [1:0] PageTypeM, input logic [`XLEN-1:0] SATP_REGW, // from csr - input logic STATUS_MXR, STATUS_SUM, // from csr + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, input logic DTLBWriteM, output logic DTLBMissM, input logic DisableTranslation, // used to stop intermediate PTE physical addresses being saved to TLB. diff --git a/wally-pipelined/src/mmu/mmu.sv b/wally-pipelined/src/mmu/mmu.sv index 303076b0..e28db2e7 100644 --- a/wally-pipelined/src/mmu/mmu.sv +++ b/wally-pipelined/src/mmu/mmu.sv @@ -34,7 +34,8 @@ module mmu #(parameter ENTRY_BITS = 3, input logic clk, reset, // Current value of satp CSR (from privileged unit) input logic [`XLEN-1:0] SATP_REGW, - input logic STATUS_MXR, STATUS_SUM, + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 6d8ed46a..9f6a4d25 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -55,7 +55,8 @@ module tlb #(parameter ENTRY_BITS = 3, // Current value of satp CSR (from privileged unit) input logic [`XLEN-1:0] SATP_REGW, - input logic STATUS_MXR, STATUS_SUM, + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, @@ -92,6 +93,7 @@ module tlb #(parameter ENTRY_BITS = 3, // Store current virtual memory mode (SV32, SV39, SV48, ect...) logic [`SVMODE_BITS-1:0] SvMode; + logic [1:0] EffectivePrivilegeMode; // privilege mode, possibly modified by MPRV // Index (currently random) to write the next TLB entry logic [ENTRY_BITS-1:0] WriteIndex; @@ -137,16 +139,15 @@ module tlb #(parameter ENTRY_BITS = 3, end endgenerate - // Whether translation should occur - assign Translate = (SvMode != `NO_TRANSLATE) & (PrivilegeModeW != `M_MODE) & ~ DisableTranslation; // *** needs to account for mprv - + // Whether translation should occur; ITLB ignores MPRVW + assign Translate = (SvMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; + // Determine how the TLB is currently being used // Note that we use ReadAccess for both loads and instruction fetches assign ReadAccess = TLBAccessType[1]; assign WriteAccess = TLBAccessType[0]; assign TLBAccess = ReadAccess || WriteAccess; - assign PageOffset = VirtualAddress[11:0]; // TLB entries are evicted according to the LRU algorithm @@ -164,28 +165,30 @@ module tlb #(parameter ENTRY_BITS = 3, if (ITLB == 1) begin logic ImproperPrivilege; + assign EffectivePrivilegeMode = PrivilegeModeW; // ITLB ignores MPRV + // User mode may only execute user mode pages, and supervisor mode may // only execute non-user mode pages. - assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) || - ((PrivilegeModeW == `S_MODE) && PTE_U); + assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) || + ((EffectivePrivilegeMode == `S_MODE) && PTE_U); assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || ~PTE_X); end else begin logic ImproperPrivilege, InvalidRead, InvalidWrite; + assign EffectivePrivilegeMode = STATUS_MPRV ? STATUS_MPP : PrivilegeModeW; // DTLB uses MPP mode when MPRV is 1 + // User mode may only load/store from user mode pages, and supervisor mode // may only access user mode pages when STATUS_SUM is low. - assign ImproperPrivilege = ((PrivilegeModeW == `U_MODE) && ~PTE_U) || - ((PrivilegeModeW == `S_MODE) && PTE_U && ~STATUS_SUM); + assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) || + ((EffectivePrivilegeMode == `S_MODE) && PTE_U && ~STATUS_SUM); // Check for read error. Reads are invalid when the page is not readable // (and executable pages are not readable) or when the page is neither // readable nor executable (and executable pages are readable). - assign InvalidRead = ReadAccess && - ((~STATUS_MXR && ~PTE_R) || (STATUS_MXR && ~PTE_R && PTE_X)); + assign InvalidRead = ReadAccess && ~PTE_R && (~STATUS_MXR | ~PTE_X); // Check for write error. Writes are invalid when the page's write bit is // low. assign InvalidWrite = WriteAccess && ~PTE_W; - assign TLBPageFault = Translate && TLBHit && - (ImproperPrivilege || InvalidRead || InvalidWrite); + assign TLBPageFault = Translate && TLBHit && (ImproperPrivilege || InvalidRead || InvalidWrite); end endgenerate diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index ba2362c3..7162263c 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -58,8 +58,7 @@ module csr #(parameter output logic [`XLEN-1:0] SATP_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, output logic STATUS_MIE, STATUS_SIE, - output logic STATUS_MXR, STATUS_SUM, - output logic STATUS_MPRV, + output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], input logic [4:0] SetFflagsM, diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 618b3214..90830137 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -67,7 +67,8 @@ module privileged ( output logic IllegalFPUInstrE, output logic [1:0] PrivilegeModeW, output logic [`XLEN-1:0] SATP_REGW, - output logic STATUS_MXR, STATUS_SUM, + output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + output logic [1:0] STATUS_MPP, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], output logic [2:0] FRM_REGW @@ -94,8 +95,7 @@ module privileged ( logic MTrapM, STrapM, UTrapM; logic InterruptM; - logic [1:0] STATUS_MPP; - logic STATUS_SPP, STATUS_TSR, STATUS_MPRV; // **** status mprv is unused outside of the csr module as of 4 June 2021. should it be deleted alltogether from the module, or should I leav the pin here in case someone needs it? + logic STATUS_SPP, STATUS_TSR; logic STATUS_MIE, STATUS_SIE; logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW; logic md, sd; diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index be59c18b..33d2e13f 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -112,7 +112,8 @@ module wallypipelinedhart logic ITLBMissF, ITLBHitF; logic DTLBMissM, DTLBHitM; logic [`XLEN-1:0] SATP_REGW; - logic STATUS_MXR, STATUS_SUM; + logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; + logic [1:0] STATUS_MPP; logic [1:0] PrivilegeModeW; logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; logic [1:0] PageTypeF, PageTypeM; From 152923e5526a315a7a900e55977b282e40587003 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 14:30:56 -0400 Subject: [PATCH 3/7] TLB minor organization --- wally-pipelined/src/mmu/tlb.sv | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 9f6a4d25..1c28aa9c 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -119,8 +119,9 @@ module tlb #(parameter ENTRY_BITS = 3, // Whether the virtual address has a match in the CAM logic CAMHit; - // Grab the sv mode from SATP + // Grab the sv mode from SATP and determine whether translation should occur assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; + assign Translate = (SvMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; // Decode the integer encoded WriteIndex into the one-hot encoded WriteLines decoder #(ENTRY_BITS) writedecoder(WriteIndex, WriteLines); @@ -139,8 +140,6 @@ module tlb #(parameter ENTRY_BITS = 3, end endgenerate - // Whether translation should occur; ITLB ignores MPRVW - assign Translate = (SvMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; // Determine how the TLB is currently being used // Note that we use ReadAccess for both loads and instruction fetches From 81742ef9e28d4a8247138c52e67690351141ac71 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 14:37:53 -0400 Subject: [PATCH 4/7] TLB cleanup --- wally-pipelined/src/mmu/tlb.sv | 10 ++++------ .../{physicalpagemask.sv => tlbphysicalpagemask.sv} | 9 ++++----- 2 files changed, 8 insertions(+), 11 deletions(-) rename wally-pipelined/src/mmu/{physicalpagemask.sv => tlbphysicalpagemask.sv} (93%) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 1c28aa9c..a4326ce8 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -121,6 +121,7 @@ module tlb #(parameter ENTRY_BITS = 3, // Grab the sv mode from SATP and determine whether translation should occur assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; + assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1 assign Translate = (SvMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; // Decode the integer encoded WriteIndex into the one-hot encoded WriteLines @@ -152,6 +153,7 @@ module tlb #(parameter ENTRY_BITS = 3, // TLB entries are evicted according to the LRU algorithm tlblru #(ENTRY_BITS) lru(.*); + // TLB memory tlbram #(ENTRY_BITS) tlbram(.*); tlbcam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlbcam(.*); @@ -164,8 +166,6 @@ module tlb #(parameter ENTRY_BITS = 3, if (ITLB == 1) begin logic ImproperPrivilege; - assign EffectivePrivilegeMode = PrivilegeModeW; // ITLB ignores MPRV - // User mode may only execute user mode pages, and supervisor mode may // only execute non-user mode pages. assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) || @@ -174,8 +174,6 @@ module tlb #(parameter ENTRY_BITS = 3, end else begin logic ImproperPrivilege, InvalidRead, InvalidWrite; - assign EffectivePrivilegeMode = STATUS_MPRV ? STATUS_MPP : PrivilegeModeW; // DTLB uses MPP mode when MPRV is 1 - // User mode may only load/store from user mode pages, and supervisor mode // may only access user mode pages when STATUS_SUM is low. assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) && ~PTE_U) || @@ -194,11 +192,11 @@ module tlb #(parameter ENTRY_BITS = 3, // Replace segments of the virtual page number with segments of the physical // page number. For 4 KB pages, the entire virtual page number is replaced. // For superpages, some segments are considered offsets into a larger page. - physicalpagemask PageNumberMixer(VirtualPageNumber, PhysicalPageNumber, HitPageType, PhysicalPageNumberMixed); + tlbphysicalpagemask PageMask(VirtualPageNumber, PhysicalPageNumber, HitPageType, PhysicalPageNumberMixed); // Provide physical address only on TLBHits to cause catastrophic errors if // garbage address is used. - assign PhysicalAddressFull = (TLBHit) ? {PhysicalPageNumberMixed, PageOffset} : '0; + assign PhysicalAddressFull = TLBHit ? {PhysicalPageNumberMixed, PageOffset} : '0; // Output the hit physical address if translation is currently on. /* generate diff --git a/wally-pipelined/src/mmu/physicalpagemask.sv b/wally-pipelined/src/mmu/tlbphysicalpagemask.sv similarity index 93% rename from wally-pipelined/src/mmu/physicalpagemask.sv rename to wally-pipelined/src/mmu/tlbphysicalpagemask.sv index b1f77e2d..858c3939 100644 --- a/wally-pipelined/src/mmu/physicalpagemask.sv +++ b/wally-pipelined/src/mmu/tlbphysicalpagemask.sv @@ -1,5 +1,5 @@ /////////////////////////////////////////// -// physicalpagemask.sv +// tlbphysicalpagemask.sv // // Written: David Harris and kmacsaigoren@hmc.edu 7 June 2021 // Modified: @@ -40,13 +40,11 @@ module physicalpagemask ( logic [`PPN_BITS-1:0] ZeroExtendedVPN; logic [`PPN_BITS-1:0] PageNumberMask; - assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. - generate if (`XLEN == 32) begin always_comb case (PageType[0]) - // *** the widths of these constansts are hardocded here to match `PPN_BITS in the wally-constants file. + // the widths of these constansts are hardocded here to match `PPN_BITS in the wally-constants file. 0: PageNumberMask = 22'h3FFFFF; // kilopage: 22 bits of PPN, 0 bits of VPN 1: PageNumberMask = 22'h3FFC00; // megapage: 12 bits of PPN, 10 bits of VPN endcase @@ -57,7 +55,7 @@ module physicalpagemask ( 1: PageNumberMask = 44'hFFFFFFFFE00; // megapage: 35 bits of PPN, 9 bits of VPN 2: PageNumberMask = 44'hFFFFFFC0000; // gigapage: 26 bits of PPN, 18 bits of VPN 3: PageNumberMask = 44'hFFFF8000000; // terapage: 17 bits of PPN, 27 bits of VPN - // *** make sure that this doesnt break when using sv39. In that case, all of these + // Bus widths accomodate SV48. In SV39, all of these // busses are the widths for sv48, but extra bits should be zeroed out by the mux // in the tlb when it generates VPN from the full virtualadress. endcase @@ -65,6 +63,7 @@ module physicalpagemask ( endgenerate // merge low segments of VPN with high segments of PPN decided by the pagetype. + assign ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. assign MixedPageNumber = (ZeroExtendedVPN & ~PageNumberMask) | (PPN & PageNumberMask); endmodule From c281539f36adbd0fbd281445b7caf9c40a998496 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 14:59:04 -0400 Subject: [PATCH 5/7] TLB cleanup --- wally-pipelined/src/mmu/priorityencoder.sv | 2 +- wally-pipelined/src/mmu/tlb.sv | 29 +++++-------------- wally-pipelined/src/mmu/tlbcam.sv | 22 +++----------- .../src/mmu/{camline.sv => tlbcamline.sv} | 8 ++--- .../src/mmu/tlbphysicalpagemask.sv | 2 +- wally-pipelined/src/mmu/tlbram.sv | 11 +------ 6 files changed, 19 insertions(+), 55 deletions(-) rename wally-pipelined/src/mmu/{camline.sv => tlbcamline.sv} (93%) diff --git a/wally-pipelined/src/mmu/priorityencoder.sv b/wally-pipelined/src/mmu/priorityencoder.sv index d56da3d6..44ce88da 100644 --- a/wally-pipelined/src/mmu/priorityencoder.sv +++ b/wally-pipelined/src/mmu/priorityencoder.sv @@ -31,7 +31,7 @@ `include "wally-config.vh" -module priorityencoder #(parameter BINARY_BITS = 3) ( +module tlbpriority #(parameter BINARY_BITS = 3) ( input logic [2**BINARY_BITS - 1:0] onehot, output logic [BINARY_BITS - 1:0] binary ); diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index a4326ce8..8aaf6570 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -148,7 +148,6 @@ module tlb #(parameter ENTRY_BITS = 3, assign WriteAccess = TLBAccessType[0]; assign TLBAccess = ReadAccess || WriteAccess; - assign PageOffset = VirtualAddress[11:0]; // TLB entries are evicted according to the LRU algorithm tlblru #(ENTRY_BITS) lru(.*); @@ -157,11 +156,15 @@ module tlb #(parameter ENTRY_BITS = 3, tlbram #(ENTRY_BITS) tlbram(.*); tlbcam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlbcam(.*); + // Replace segments of the virtual page number with segments of the physical + // page number. For 4 KB pages, the entire virtual page number is replaced. + // For superpages, some segments are considered offsets into a larger page. + tlbphysicalpagemask PageMask(VirtualPageNumber, PhysicalPageNumber, HitPageType, PhysicalPageNumberMixed); + // unswizzle useful PTE bits assign {PTE_U, PTE_X, PTE_W, PTE_R} = PTEAccessBits[4:1]; // Check whether the access is allowed, page faulting if not. - // *** We might not have S mode. generate if (ITLB == 1) begin logic ImproperPrivilege; @@ -189,28 +192,12 @@ module tlb #(parameter ENTRY_BITS = 3, end endgenerate - // Replace segments of the virtual page number with segments of the physical - // page number. For 4 KB pages, the entire virtual page number is replaced. - // For superpages, some segments are considered offsets into a larger page. - tlbphysicalpagemask PageMask(VirtualPageNumber, PhysicalPageNumber, HitPageType, PhysicalPageNumberMixed); - - // Provide physical address only on TLBHits to cause catastrophic errors if - // garbage address is used. - assign PhysicalAddressFull = TLBHit ? {PhysicalPageNumberMixed, PageOffset} : '0; // Output the hit physical address if translation is currently on. -/* generate - if (`XLEN == 32) begin - VirtualAddressPALen = {2'b0, VirtualAddress}; - - mux2 #(`PA_BITS) addressmux({2'b0, VirtualAddress}, PhysicalAddressFull, Translate, PhysicalAddress); - end else begin - VirtualAddressPALen = VirtualAddress[`PA_BITS-1:0]; - mux2 #(`PA_BITS) addressmux(VirtualAddress[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress); - end - endgenerate*/ - + // Provide physical address of zero if not TLBHits, to cause segmentation error if miss somehow percolated through signal assign VAExt = {2'b00, VirtualAddress}; // extend length of virtual address if necessary for RV32 + assign PageOffset = VirtualAddress[11:0]; + assign PhysicalAddressFull = TLBHit ? {PhysicalPageNumberMixed, PageOffset} : '0; mux2 #(`PA_BITS) addressmux(VAExt[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress); assign TLBHit = CAMHit & TLBAccess; diff --git a/wally-pipelined/src/mmu/tlbcam.sv b/wally-pipelined/src/mmu/tlbcam.sv index e45b124a..07ec38ff 100644 --- a/wally-pipelined/src/mmu/tlbcam.sv +++ b/wally-pipelined/src/mmu/tlbcam.sv @@ -34,8 +34,6 @@ module tlbcam #(parameter ENTRY_BITS = 3, input logic clk, reset, input logic [KEY_BITS-1:0] VirtualPageNumber, input logic [1:0] PageTypeWriteVal, -// input logic [`SVMODE_BITS-1:0] SvMode, // *** may not need to be used. -// input logic TLBWrite, input logic TLBFlush, input logic [2**ENTRY_BITS-1:0] WriteEnables, @@ -56,23 +54,11 @@ module tlbcam #(parameter ENTRY_BITS = 3, // of page type. However, matches are determined based on a subset of the // page number segments. - camline #(KEY_BITS, SEGMENT_BITS) camlines[NENTRIES-1:0]( + tlbcamline #(KEY_BITS, SEGMENT_BITS) camlines[NENTRIES-1:0]( .CAMLineWrite(WriteEnables), - .PageType(PageTypeList), - .Match(Matches), - .*); -/* - generate - genvar i; - for (i = 0; i < NENTRIES; i++) begin - camline #(KEY_BITS, SEGMENT_BITS) camline( - .CAMLineWrite(WriteEnables[i]), - .PageType(PageTypeList[i]), - .Match(Matches[i]), - .*); - end - endgenerate - */ + .PageType(PageTypeList), + .Match(Matches), + .*); // In case there are multiple matches in the CAM, select only one // *** it might be guaranteed that the CAM will never have multiple matches. diff --git a/wally-pipelined/src/mmu/camline.sv b/wally-pipelined/src/mmu/tlbcamline.sv similarity index 93% rename from wally-pipelined/src/mmu/camline.sv rename to wally-pipelined/src/mmu/tlbcamline.sv index 6e3f705c..3e882cf1 100644 --- a/wally-pipelined/src/mmu/camline.sv +++ b/wally-pipelined/src/mmu/tlbcamline.sv @@ -1,5 +1,5 @@ /////////////////////////////////////////// -// camline.sv +// tlbcamline.sv // // Written: tfleming@hmc.edu & jtorrey@hmc.edu 6 April 2021 // Modified: kmacsaigoren@hmc.edu 1 June 2021 @@ -28,7 +28,7 @@ `include "wally-config.vh" -module camline #(parameter KEY_BITS = 20, +module tlbcamline #(parameter KEY_BITS = 20, parameter SEGMENT_BITS = 10) ( input logic clk, reset, @@ -85,12 +85,12 @@ module camline #(parameter KEY_BITS = 20, assign {Key3, Key2, Key1, Key0} = Key; // Calculate the actual match value based on the input vpn and the page type. - // For example, a gigapage in SV only cares about VPN[2], so VPN[0] and VPN[1] + // For example, a gigapage in SV39 only cares about VPN[2], so VPN[0] and VPN[1] // should automatically match. assign Match0 = (Query0 == Key0) || (PageType > 2'd0); // least signifcant section assign Match1 = (Query1 == Key1) || (PageType > 2'd1); assign Match2 = (Query2 == Key2) || (PageType > 2'd2); - assign Match3 = (Query3 == Key3); // *** this should always match in sv39 since both vPN3 and key3 are zeroed by the pagetable walker before getting to the cam + assign Match3 = (Query3 == Key3); // this should always match in sv39 since both vPN3 and key3 are zeroed by the pagetable walker before getting to the cam assign Match = Match0 & Match1 & Match2 & Match3 & Valid; end diff --git a/wally-pipelined/src/mmu/tlbphysicalpagemask.sv b/wally-pipelined/src/mmu/tlbphysicalpagemask.sv index 858c3939..dd791e48 100644 --- a/wally-pipelined/src/mmu/tlbphysicalpagemask.sv +++ b/wally-pipelined/src/mmu/tlbphysicalpagemask.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" -module physicalpagemask ( +module tlbphysicalpagemask ( input logic [`VPN_BITS-1:0] VPN, input logic [`PPN_BITS-1:0] PPN, input logic [1:0] PageType, diff --git a/wally-pipelined/src/mmu/tlbram.sv b/wally-pipelined/src/mmu/tlbram.sv index f13666bc..9482cd6f 100644 --- a/wally-pipelined/src/mmu/tlbram.sv +++ b/wally-pipelined/src/mmu/tlbram.sv @@ -46,16 +46,7 @@ module tlbram #(parameter ENTRY_BITS = 3) ( // Generate a flop for every entry in the RAM flopenr #(`XLEN) pteflops[NENTRIES-1:0](clk, reset, WriteEnables, PTEWriteVal, ram); -/* - generate - genvar i; - for (i = 0; i < NENTRIES; i++) begin: tlb_ram_flops - flopenr #(`XLEN) pteflop(clk, reset, WriteEnables[i], - PTEWriteVal, ram[i]); - end - endgenerate -*/ - + assign PageTableEntry = ram[VPNIndex]; assign PTEAccessBits = PageTableEntry[7:0]; assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10]; From 8337d6df68466a3e8631d77d981257dc28072c7f Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 4 Jul 2021 16:33:13 -0400 Subject: [PATCH 6/7] Reorganized TLB to use one-hot read/write select signals to eliminate decoders and encoders --- wally-pipelined/src/mmu/tlb.sv | 11 ++-- wally-pipelined/src/mmu/tlbcam.sv | 13 ++--- wally-pipelined/src/mmu/tlbcamline.sv | 4 +- wally-pipelined/src/mmu/tlblru.sv | 21 ++++---- .../{priorityencoder.sv => tlbpriority.sv} | 50 +++++++------------ wally-pipelined/src/mmu/tlbram.sv | 40 ++++++++++++--- 6 files changed, 77 insertions(+), 62 deletions(-) rename wally-pipelined/src/mmu/{priorityencoder.sv => tlbpriority.sv} (62%) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 8aaf6570..2741f958 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -88,6 +88,8 @@ module tlb #(parameter ENTRY_BITS = 3, output logic TLBPageFault ); + localparam NENTRIES = 2**ENTRY_BITS; + logic Translate; logic TLBAccess, ReadAccess, WriteAccess; @@ -95,9 +97,8 @@ module tlb #(parameter ENTRY_BITS = 3, logic [`SVMODE_BITS-1:0] SvMode; logic [1:0] EffectivePrivilegeMode; // privilege mode, possibly modified by MPRV - // Index (currently random) to write the next TLB entry - logic [ENTRY_BITS-1:0] WriteIndex; - logic [(2**ENTRY_BITS)-1:0] WriteLines, WriteEnables; // used as the one-hot encoding of WriteIndex + //logic [ENTRY_BITS-1:0] WriteIndex; + logic [NENTRIES-1:0] ReadLines, WriteLines, WriteEnables; // used as the one-hot encoding of WriteIndex // Sections of the virtual and physical addresses logic [`VPN_BITS-1:0] VirtualPageNumber; @@ -113,7 +114,7 @@ module tlb #(parameter ENTRY_BITS = 3, logic PTE_U, PTE_X, PTE_W, PTE_R; // Pattern location in the CAM and type of page hit - logic [ENTRY_BITS-1:0] VPNIndex; + //ogic [ENTRY_BITS-1:0] VPNIndex; logic [1:0] HitPageType; // Whether the virtual address has a match in the CAM @@ -125,7 +126,7 @@ module tlb #(parameter ENTRY_BITS = 3, assign Translate = (SvMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; // Decode the integer encoded WriteIndex into the one-hot encoded WriteLines - decoder #(ENTRY_BITS) writedecoder(WriteIndex, WriteLines); + //decoder #(ENTRY_BITS) writedecoder(WriteIndex, WriteLines); assign WriteEnables = WriteLines & {(2**ENTRY_BITS){TLBWrite}}; // The bus width is always the largest it could be for that XLEN. For example, vpn will be 36 bits wide in rv64 diff --git a/wally-pipelined/src/mmu/tlbcam.sv b/wally-pipelined/src/mmu/tlbcam.sv index 07ec38ff..f10442cd 100644 --- a/wally-pipelined/src/mmu/tlbcam.sv +++ b/wally-pipelined/src/mmu/tlbcam.sv @@ -37,7 +37,8 @@ module tlbcam #(parameter ENTRY_BITS = 3, input logic TLBFlush, input logic [2**ENTRY_BITS-1:0] WriteEnables, - output logic [ENTRY_BITS-1:0] VPNIndex, + //output logic [ENTRY_BITS-1:0] VPNIndex, + output logic [2**ENTRY_BITS-1:0] ReadLines, output logic [1:0] HitPageType, output logic CAMHit ); @@ -56,16 +57,16 @@ module tlbcam #(parameter ENTRY_BITS = 3, tlbcamline #(KEY_BITS, SEGMENT_BITS) camlines[NENTRIES-1:0]( .CAMLineWrite(WriteEnables), - .PageType(PageTypeList), - .Match(Matches), + .MatchedPageType(PageTypeList), // *** change name to agree + .Match(ReadLines), // *** change name to agree .*); // In case there are multiple matches in the CAM, select only one // *** it might be guaranteed that the CAM will never have multiple matches. // If so, this is just an encoder - priorityencoder #(ENTRY_BITS) matchencoder(Matches, VPNIndex); + //priorityencoder #(ENTRY_BITS) matchencoder(Matches, VPNIndex); - assign CAMHit = |Matches & ~TLBFlush; - assign HitPageType = PageTypeList[VPNIndex]; + assign CAMHit = |ReadLines & ~TLBFlush; + assign HitPageType = PageTypeList.or; // applies OR to elements of the (NENTRIES x 2) array to get 2-bit result endmodule diff --git a/wally-pipelined/src/mmu/tlbcamline.sv b/wally-pipelined/src/mmu/tlbcamline.sv index 3e882cf1..2eaa3a01 100644 --- a/wally-pipelined/src/mmu/tlbcamline.sv +++ b/wally-pipelined/src/mmu/tlbcamline.sv @@ -50,13 +50,14 @@ module tlbcamline #(parameter KEY_BITS = 20, // PageType == 2'b01 --> megapage // PageType == 2'b10 --> gigapage // PageType == 2'b11 --> terapage - output logic [1:0] PageType, // *** should this be the stored version or the always updated one? + output logic [1:0] MatchedPageType, // *** should this be the stored version or the always updated one? output logic Match ); // This entry has KEY_BITS for the key plus one valid bit. logic Valid; logic [KEY_BITS-1:0] Key; + logic [1:0] PageType; // Split up key and query into sections for each page table level. @@ -98,6 +99,7 @@ module tlbcamline #(parameter KEY_BITS = 20, // On a write, update the type of the page referred to by this line. flopenr #(2) pagetypeflop(clk, reset, CAMLineWrite, PageTypeWriteVal, PageType); + assign MatchedPageType = PageType & {2{Match}}; //mux2 #(2) pagetypemux(StoredPageType, PageTypeWrite, CAMLineWrite, PageType); // On a write, set the valid bit high and update the stored key. diff --git a/wally-pipelined/src/mmu/tlblru.sv b/wally-pipelined/src/mmu/tlblru.sv index e86598f7..f1ac4db2 100644 --- a/wally-pipelined/src/mmu/tlblru.sv +++ b/wally-pipelined/src/mmu/tlblru.sv @@ -28,11 +28,9 @@ module tlblru #(parameter ENTRY_BITS = 3) ( input logic clk, reset, input logic TLBWrite, input logic TLBFlush, - input logic [ENTRY_BITS-1:0] VPNIndex, + input logic [2**ENTRY_BITS-1:0] ReadLines, input logic CAMHit, - input logic [2**ENTRY_BITS-1:0] WriteLines, - - output logic [ENTRY_BITS-1:0] WriteIndex + output logic [2**ENTRY_BITS-1:0] WriteLines ); localparam NENTRIES = 2**ENTRY_BITS; @@ -41,26 +39,27 @@ module tlblru #(parameter ENTRY_BITS = 3) ( logic [NENTRIES-1:0] RUBits, RUBitsNext, RUBitsAccessed; // One-hot encodings of which line is being accessed - logic [NENTRIES-1:0] ReadLineOneHot, AccessLineOneHot; + logic [NENTRIES-1:0] AccessLines; // High if the next access causes all RU bits to be 1 logic AllUsed; // Convert indices to one-hot encodings - decoder #(ENTRY_BITS) readdecoder(VPNIndex, ReadLineOneHot); + //decoder #(ENTRY_BITS) readdecoder(VPNIndex, ReadLineOneHot); // Find the first line not recently used - priorityencoder #(ENTRY_BITS) firstnru(~RUBits, WriteIndex); + tlbpriority #(NENTRIES) nru(~RUBits, WriteLines); + //priorityencoder #(ENTRY_BITS) firstnru(~RUBits, WriteIndex); // Access either the hit line or written line - assign AccessLineOneHot = (TLBWrite) ? WriteLines : ReadLineOneHot; + assign AccessLines = TLBWrite ? WriteLines : ReadLines; // Raise the bit of the recently accessed line - assign RUBitsAccessed = AccessLineOneHot | RUBits; + assign RUBitsAccessed = AccessLines | RUBits; // Determine whether we need to reset the RU bits to all zeroes - assign AllUsed = &(RUBitsAccessed); - assign RUBitsNext = (AllUsed) ? AccessLineOneHot : RUBitsAccessed; + assign AllUsed = &RUBitsAccessed; + assign RUBitsNext = AllUsed ? AccessLines : RUBitsAccessed; // *** seems it should set to 0, not to AccessLines // Update LRU state on any TLB hit or write flopenrc #(NENTRIES) lrustate(clk, reset, TLBFlush, (CAMHit || TLBWrite), diff --git a/wally-pipelined/src/mmu/priorityencoder.sv b/wally-pipelined/src/mmu/tlbpriority.sv similarity index 62% rename from wally-pipelined/src/mmu/priorityencoder.sv rename to wally-pipelined/src/mmu/tlbpriority.sv index 44ce88da..a061f622 100644 --- a/wally-pipelined/src/mmu/priorityencoder.sv +++ b/wally-pipelined/src/mmu/tlbpriority.sv @@ -1,16 +1,15 @@ /////////////////////////////////////////// -// priorityencoder.sv +// tlbpriority.sv // // Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021 -// Based on implementation from https://www.allaboutcircuits.com/ip-cores/communication-controller/priority-encoder/ -// *** Give proper LGPL attribution for above source // Modified: Teo Ene 15 Apr 2021: // Temporarily removed paramterized priority encoder for non-parameterized one // To get synthesis working quickly // Kmacsaigoren@hmc.edu 28 May 2021: // Added working version of parameterized priority encoder. +// David_Harris@Hmc.edu switched to one-hot output // -// Purpose: One-hot encoding to binary encoder +// Purpose: Priority circuit to choose most significant one-hot output // // A component of the Wally configurable RISC-V project. // @@ -31,35 +30,20 @@ `include "wally-config.vh" -module tlbpriority #(parameter BINARY_BITS = 3) ( - input logic [2**BINARY_BITS - 1:0] onehot, - output logic [BINARY_BITS - 1:0] binary +module tlbpriority #(parameter ENTRIES = 8) ( + input logic [ENTRIES-1:0] a, + output logic [ENTRIES-1:0] y ); + // verilator lint_off UNOPTFLAT + logic [ENTRIES-1:0] nolower; - integer i; - always_comb begin - binary = 0; - for (i = 0; i < 2**BINARY_BITS; i++) begin - // verilator lint_off WIDTH - if (onehot[i]) binary = i; // prioritizes the most significant bit - // verilator lint_on WIDTH - end - end - // *** triple check synthesizability here - - // Ideally this mimics the following: - /* - always_comb begin - casex (one_hot) - 1xx ... x: binary = BINARY_BITS - 1; - 01x ... x: binary = BINARY_BITS - 2; - 001 ... x: binary = BINARY_BITS - 3; - - {...} - - 00 ... 1xx: binary = 2; - 00 ... 01x: binary = 1; - 00 ... 001: binary = 0; - end - */ + // generate thermometer code mask + genvar i; + generate + assign nolower[0] = 1; + for (i=1; i Date: Sun, 4 Jul 2021 17:01:22 -0400 Subject: [PATCH 7/7] Restructured TLB Read as AND-OR operation with one-hot match/read line --- wally-pipelined/src/mmu/tlbcam.sv | 9 +++---- wally-pipelined/src/mmu/tlbcamline.sv | 16 +++++------ wally-pipelined/src/mmu/tlblru.sv | 19 +++----------- wally-pipelined/src/mmu/tlbram.sv | 31 +--------------------- wally-pipelined/src/mmu/tlbramline.sv | 38 +++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 58 deletions(-) create mode 100644 wally-pipelined/src/mmu/tlbramline.sv diff --git a/wally-pipelined/src/mmu/tlbcam.sv b/wally-pipelined/src/mmu/tlbcam.sv index f10442cd..ef64e0d6 100644 --- a/wally-pipelined/src/mmu/tlbcam.sv +++ b/wally-pipelined/src/mmu/tlbcam.sv @@ -45,8 +45,7 @@ module tlbcam #(parameter ENTRY_BITS = 3, localparam NENTRIES = 2**ENTRY_BITS; - - logic [1:0] PageTypeList [NENTRIES-1:0]; + logic [1:0] PageTypeRead [NENTRIES-1:0]; logic [NENTRIES-1:0] Matches; // Create NENTRIES CAM lines, each of which will independently consider @@ -56,8 +55,8 @@ module tlbcam #(parameter ENTRY_BITS = 3, // page number segments. tlbcamline #(KEY_BITS, SEGMENT_BITS) camlines[NENTRIES-1:0]( - .CAMLineWrite(WriteEnables), - .MatchedPageType(PageTypeList), // *** change name to agree + .WriteEnable(WriteEnables), + .PageTypeRead, // *** change name to agree .Match(ReadLines), // *** change name to agree .*); @@ -67,6 +66,6 @@ module tlbcam #(parameter ENTRY_BITS = 3, //priorityencoder #(ENTRY_BITS) matchencoder(Matches, VPNIndex); assign CAMHit = |ReadLines & ~TLBFlush; - assign HitPageType = PageTypeList.or; // applies OR to elements of the (NENTRIES x 2) array to get 2-bit result + assign HitPageType = PageTypeRead.or; // applies OR to elements of the (NENTRIES x 2) array to get 2-bit result endmodule diff --git a/wally-pipelined/src/mmu/tlbcamline.sv b/wally-pipelined/src/mmu/tlbcamline.sv index 2eaa3a01..605d8f30 100644 --- a/wally-pipelined/src/mmu/tlbcamline.sv +++ b/wally-pipelined/src/mmu/tlbcamline.sv @@ -39,7 +39,7 @@ module tlbcamline #(parameter KEY_BITS = 20, input logic [KEY_BITS-1:0] VirtualPageNumber, // Signals to write a new entry to this line - input logic CAMLineWrite, + input logic WriteEnable, input logic [1:0] PageTypeWriteVal, // Flush this line (set valid to 0) @@ -50,7 +50,7 @@ module tlbcamline #(parameter KEY_BITS = 20, // PageType == 2'b01 --> megapage // PageType == 2'b10 --> gigapage // PageType == 2'b11 --> terapage - output logic [1:0] MatchedPageType, // *** should this be the stored version or the always updated one? + output logic [1:0] PageTypeRead, // *** should this be the stored version or the always updated one? output logic Match ); @@ -59,11 +59,12 @@ module tlbcamline #(parameter KEY_BITS = 20, logic [KEY_BITS-1:0] Key; logic [1:0] PageType; - // Split up key and query into sections for each page table level. logic [SEGMENT_BITS-1:0] Key0, Key1, Query0, Query1; logic Match0, Match1; + // *** need to add ASID and G bit support + generate if (`XLEN == 32) begin @@ -98,15 +99,14 @@ module tlbcamline #(parameter KEY_BITS = 20, endgenerate // On a write, update the type of the page referred to by this line. - flopenr #(2) pagetypeflop(clk, reset, CAMLineWrite, PageTypeWriteVal, PageType); - assign MatchedPageType = PageType & {2{Match}}; - //mux2 #(2) pagetypemux(StoredPageType, PageTypeWrite, CAMLineWrite, PageType); + flopenr #(2) pagetypeflop(clk, reset, WriteEnable, PageTypeWriteVal, PageType); + assign PageTypeRead = PageType & {2{Match}}; // On a write, set the valid bit high and update the stored key. // On a flush, zero the valid bit and leave the key unchanged. // *** Might we want to update stored key right away to output match on the // write cycle? (using a mux) - flopenrc #(1) validbitflop(clk, reset, TLBFlush, CAMLineWrite, 1'b1, Valid); - flopenr #(KEY_BITS) keyflop(clk, reset, CAMLineWrite, VirtualPageNumber, Key); + flopenrc #(1) validbitflop(clk, reset, TLBFlush, WriteEnable, 1'b1, Valid); + flopenr #(KEY_BITS) keyflop(clk, reset, WriteEnable, VirtualPageNumber, Key); endmodule diff --git a/wally-pipelined/src/mmu/tlblru.sv b/wally-pipelined/src/mmu/tlblru.sv index f1ac4db2..5dc1f846 100644 --- a/wally-pipelined/src/mmu/tlblru.sv +++ b/wally-pipelined/src/mmu/tlblru.sv @@ -44,25 +44,14 @@ module tlblru #(parameter ENTRY_BITS = 3) ( // High if the next access causes all RU bits to be 1 logic AllUsed; - // Convert indices to one-hot encodings - //decoder #(ENTRY_BITS) readdecoder(VPNIndex, ReadLineOneHot); - // Find the first line not recently used tlbpriority #(NENTRIES) nru(~RUBits, WriteLines); - //priorityencoder #(ENTRY_BITS) firstnru(~RUBits, WriteIndex); - // Access either the hit line or written line + // Track recently used lines, updating on a CAM Hit or TLB write assign AccessLines = TLBWrite ? WriteLines : ReadLines; - - // Raise the bit of the recently accessed line assign RUBitsAccessed = AccessLines | RUBits; - - // Determine whether we need to reset the RU bits to all zeroes - assign AllUsed = &RUBitsAccessed; - assign RUBitsNext = AllUsed ? AccessLines : RUBitsAccessed; // *** seems it should set to 0, not to AccessLines - - // Update LRU state on any TLB hit or write - flopenrc #(NENTRIES) lrustate(clk, reset, TLBFlush, (CAMHit || TLBWrite), - RUBitsNext, RUBits); + assign AllUsed = &RUBitsAccessed; // if all recently used, then clear to none + assign RUBitsNext = AllUsed ? 0 : RUBitsAccessed; + flopenrc #(NENTRIES) lrustate(clk, reset, TLBFlush, (CAMHit || TLBWrite), RUBitsNext, RUBits); endmodule diff --git a/wally-pipelined/src/mmu/tlbram.sv b/wally-pipelined/src/mmu/tlbram.sv index 70e7bb6c..f70cb44c 100644 --- a/wally-pipelined/src/mmu/tlbram.sv +++ b/wally-pipelined/src/mmu/tlbram.sv @@ -41,42 +41,13 @@ module tlbram #(parameter ENTRY_BITS = 3) ( localparam NENTRIES = 2**ENTRY_BITS; - //logic [`XLEN-1:0] ram[NENTRIES-1:0]; logic [`XLEN-1:0] RamRead[NENTRIES-1:0]; logic [`XLEN-1:0] PageTableEntry; -// logic [ENTRY_BITS-1:0] VPNIndex; - // Generate a flop for every entry in the RAM - //flopenr #(`XLEN) pteflops[NENTRIES-1:0](clk, reset, WriteEnables, PTEWriteVal, ram); tlbramline #(`XLEN) tlblineram[NENTRIES-1:0](clk, reset, ReadLines, WriteEnables, PTEWriteVal, RamRead); -/* - // temporary code for read - // verilator lint_off WIDTH - integer i; - generate - always_comb begin - VPNIndex = 0; - for (i=0; i