From d58cad89a80fbbac3df6a58ba9d2d5501f62226a Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 6 Jul 2021 10:38:30 -0400 Subject: [PATCH 1/2] Replaced muxing of upper address bits with disregarding their match. Moved WriteEnables gate into tlblru to eliminate WriteLines --- wally-pipelined/src/mmu/tlb.sv | 22 +++++----------------- wally-pipelined/src/mmu/tlbcam.sv | 1 + wally-pipelined/src/mmu/tlbcamline.sv | 3 ++- wally-pipelined/src/mmu/tlbcontrol.sv | 11 ++++++++--- wally-pipelined/src/mmu/tlblru.sv | 4 +++- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index d16a97a4..95325dcf 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -91,10 +91,10 @@ module tlb #(parameter TLB_ENTRIES = 8, logic Translate; // Store current virtual memory mode (SV32, SV39, SV48, ect...) - logic [`SVMODE_BITS-1:0] SvMode; + //logic [`SVMODE_BITS-1:0] SvMode; logic [1:0] EffectivePrivilegeMode; // privilege mode, possibly modified by MPRV - logic [TLB_ENTRIES-1:0] ReadLines, WriteLines, WriteEnables, PTE_G; // used as the one-hot encoding of WriteIndex + logic [TLB_ENTRIES-1:0] ReadLines, WriteEnables, PTE_G; // used as the one-hot encoding of WriteIndex // Sections of the virtual and physical addresses logic [`VPN_BITS-1:0] VirtualPageNumber; @@ -106,29 +106,17 @@ module tlb #(parameter TLB_ENTRIES = 8, logic [7:0] PTEAccessBits; logic [11:0] PageOffset; - logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R; // Useful PTE Control Bits + logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R; // Useful PTE Control Bits logic [1:0] HitPageType; logic CAMHit; + logic SV39Mode; logic [`ASID_BITS-1:0] ASID; // Grab the sv mode from SATP and determine whether translation should occur assign ASID = SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]; // Determine whether to write TLB - assign WriteEnables = WriteLines & {(TLB_ENTRIES){TLBWrite}}; - - // The bus width is always the largest it could be for that XLEN. For example, vpn will be 36 bits wide in rv64 - // this, even though it could be 27 bits (SV39) or 36 bits (SV48) wide. When the value of VPN is narrower, - // is shorter, the extra bits are used as padded zeros on the left of the full value. - generate - if (`XLEN == 32) begin - assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12]; - end else begin - assign VirtualPageNumber = (SvMode == `SV48) ? - VirtualAddress[`VPN_BITS+11:12] : - {{`VPN_SEGMENT_BITS{1'b0}}, VirtualAddress[3*`VPN_SEGMENT_BITS+11:12]}; - end - endgenerate + assign VirtualPageNumber = VirtualAddress[`VPN_BITS+11:12]; tlbcontrol tlbcontrol(.*); diff --git a/wally-pipelined/src/mmu/tlbcam.sv b/wally-pipelined/src/mmu/tlbcam.sv index 0ad81605..35a6fb3f 100644 --- a/wally-pipelined/src/mmu/tlbcam.sv +++ b/wally-pipelined/src/mmu/tlbcam.sv @@ -34,6 +34,7 @@ module tlbcam #(parameter TLB_ENTRIES = 8, input logic clk, reset, input logic [`VPN_BITS-1:0] VirtualPageNumber, input logic [1:0] PageTypeWriteVal, + input logic SV39Mode, input logic TLBFlush, input logic [TLB_ENTRIES-1:0] WriteEnables, input logic [TLB_ENTRIES-1:0] PTE_G, diff --git a/wally-pipelined/src/mmu/tlbcamline.sv b/wally-pipelined/src/mmu/tlbcamline.sv index ebb9ce3f..95bc57fe 100644 --- a/wally-pipelined/src/mmu/tlbcamline.sv +++ b/wally-pipelined/src/mmu/tlbcamline.sv @@ -33,6 +33,7 @@ module tlbcamline #(parameter KEY_BITS = 20, input logic clk, reset, input logic [`VPN_BITS-1:0] VirtualPageNumber, // The requested page number to compare against the key input logic [`ASID_BITS-1:0] ASID, + input logic SV39Mode, input logic WriteEnable, // Write a new entry to this line input logic PTE_G, input logic [1:0] PageTypeWriteVal, @@ -86,7 +87,7 @@ module tlbcamline #(parameter KEY_BITS = 20, 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) || SV39Mode; // this should always match in sv39 because they aren't used assign Match = Match0 & Match1 & Match2 & Match3 & Valid; end diff --git a/wally-pipelined/src/mmu/tlbcontrol.sv b/wally-pipelined/src/mmu/tlbcontrol.sv index 21f42dae..1301b815 100644 --- a/wally-pipelined/src/mmu/tlbcontrol.sv +++ b/wally-pipelined/src/mmu/tlbcontrol.sv @@ -49,21 +49,26 @@ module tlbcontrol #(parameter TLB_ENTRIES = 8, output logic TLBHit, output logic TLBPageFault, output logic [1:0] EffectivePrivilegeMode, - output logic [`SVMODE_BITS-1:0] SvMode, + output logic SV39Mode, output logic Translate ); // Sections of the page table entry logic [11:0] PageOffset; + logic [`SVMODE_BITS-1:0] SVMode; logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R; // Useful PTE Control Bits logic DAFault; logic TLBAccess; // Grab the sv mode from SATP and determine whether translation should occur - assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; + 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; + assign Translate = (SVMode != `NO_TRANSLATE) & (EffectivePrivilegeMode != `M_MODE) & ~ DisableTranslation; + generate + if (`XLEN==64) assign SV39Mode = (SVMode == `SV39); + else assign SV39Mode = 0; + endgenerate // Determine whether TLB is being used assign TLBAccess = ReadAccess || WriteAccess; diff --git a/wally-pipelined/src/mmu/tlblru.sv b/wally-pipelined/src/mmu/tlblru.sv index ae933f80..72555ab9 100644 --- a/wally-pipelined/src/mmu/tlblru.sv +++ b/wally-pipelined/src/mmu/tlblru.sv @@ -30,10 +30,11 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( input logic TLBFlush, input logic [TLB_ENTRIES-1:0] ReadLines, input logic CAMHit, - output logic [TLB_ENTRIES-1:0] WriteLines + output logic [TLB_ENTRIES-1:0] WriteEnables ); logic [TLB_ENTRIES-1:0] RUBits, RUBitsNext, RUBitsAccessed; + logic [TLB_ENTRIES-1:0] WriteLines; logic [TLB_ENTRIES-1:0] AccessLines; // One-hot encodings of which line is being accessed logic AllUsed; // High if the next access causes all RU bits to be 1 @@ -41,6 +42,7 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( tlbpriority #(TLB_ENTRIES) nru(~RUBits, WriteLines); // Track recently used lines, updating on a CAM Hit or TLB write + assign WriteEnables = WriteLines & {(TLB_ENTRIES){TLBWrite}}; assign AccessLines = TLBWrite ? WriteLines : ReadLines; assign RUBitsAccessed = AccessLines | RUBits; assign AllUsed = &RUBitsAccessed; // if all recently used, then clear to none From 30fdd7abc829018005a5414d9f4f08d9ab898941 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 6 Jul 2021 10:44:05 -0400 Subject: [PATCH 2/2] Cleaned up tlb output muxing --- wally-pipelined/src/mmu/tlb.sv | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 95325dcf..f2ab9435 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -135,7 +135,6 @@ module tlb #(parameter TLB_ENTRIES = 8, // Output the hit physical address if translation is currently on. // 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; // *** in block diagram TLB just works on page numbers + mux2 #(`PA_BITS) hitmux('0, {PhysicalPageNumberMixed, VirtualAddress[11:0]}, TLBHit, PhysicalAddressFull); // set PA to 0 if TLB misses, to cause segementation error if this miss somehow passes through system mux2 #(`PA_BITS) addressmux(VAExt[`PA_BITS-1:0], PhysicalAddressFull, Translate, PhysicalAddress); endmodule