Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/regression-wally
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ standard_tests = [
"arch64d_divsqrt", "arch64zfh_divsqrt", "arch64zfaf", "arch64zfad", "coverage64gc", "arch64i", "arch64priv",
"arch64c", "arch64m", "arch64zcb", "arch64zifencei", "arch64zicond", "arch64a_amo", "wally64a_lrsc",
"wally64periph", "wally64priv", "arch64zbkb", "arch64zbkc", "arch64zbkx", "arch64zknd", "arch64zkne", "arch64zknh",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64vm_sv39", "arch64vm_sv48", "arch64pmp", "arch64zicboz"]]
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64vm_sv39", "arch64vm_sv48", "arch64vm_sv57", "arch64pmp", "arch64zicboz"]]
]

# Separate test for short buildroot run through OpenSBI UART output
Expand Down
3 changes: 2 additions & 1 deletion config/shared/config-shared.vh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ localparam U_MODE = (2'b00);

// Virtual Memory Constants
localparam VPN_SEGMENT_BITS = (XLEN == 32 ? 32'd10 : 32'd9);
localparam VPN_BITS = (XLEN==32 ? (2*VPN_SEGMENT_BITS) : (4*VPN_SEGMENT_BITS));
localparam VPN_BITS = (XLEN==32 ? (2*VPN_SEGMENT_BITS) : (5*VPN_SEGMENT_BITS));
localparam PPN_BITS = (XLEN==32 ? 32'd22 : 32'd44);
localparam PA_BITS = (XLEN==32 ? 32'd34 : 32'd56);
localparam SVMODE_BITS = (XLEN==32 ? 32'd1 : 32'd4);
Expand All @@ -22,6 +22,7 @@ localparam NO_TRANSLATE = 4'd0;
localparam SV32 = 4'd1;
localparam SV39 = 4'd8;
localparam SV48 = 4'd9;
localparam SV57 = 4'd10;

// macros to define supported modes
localparam logic I_SUPPORTED = (!E_SUPPORTED);
Expand Down
1 change: 1 addition & 0 deletions config/shared/parameter-defs.vh
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ localparam cvw_t P = '{
SV32 : SV32,
SV39 : SV39,
SV48 : SV48,
SV57 : SV57,
A_SUPPORTED : A_SUPPORTED,
B_SUPPORTED : B_SUPPORTED,
C_SUPPORTED : C_SUPPORTED,
Expand Down
1 change: 1 addition & 0 deletions src/cvw.sv
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ typedef struct packed {
logic [3:0] SV32;
logic [3:0] SV39;
logic [3:0] SV48;
logic [3:0] SV57;

// macros to define supported modes
logic A_SUPPORTED;
Expand Down
2 changes: 1 addition & 1 deletion src/ifu/ifu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// mmu management
input logic [1:0] PrivilegeModeW, // Privilege mode in Writeback stage
input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
input logic [2:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
input logic [P.XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
input logic STATUS_MXR, // Status CSR: make executable page readable
Expand Down
2 changes: 1 addition & 1 deletion src/lsu/lsu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
input logic ITLBMissOrUpdateAF, // ITLB miss causes HPTW (hardware pagetable walker) walk or update access bit
output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB
output logic [1:0] PageType, // Type of page table entry to write to ITLB
output logic [2:0] PageType, // Type of page table entry to write to ITLB
output logic ITLBWriteF, // Write PTE to ITLB
output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
Expand Down
46 changes: 30 additions & 16 deletions src/mmu/hptw.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
// adding support for terapage encoding, and for setting the HPTWAdr using the new level,
// adding the internal SvMode signal
//
// implemented SV57 on top of SV8, SV39. This included, adding a level of the FSM for the extra page number segment
// adding support for petapage encoding, and for setting the HPTWAdr using the new level,
// adding the internal SvMode signal
// Purpose: Hardware Page Table Walker
//
// Documentation: RISC-V System on Chip Design
Expand Down Expand Up @@ -51,7 +54,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
input logic FlushW,
input logic [3:0] CMOpM,
output logic [P.XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs
output logic [2:0] PageType, // page type to TLBs
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [1:0] PreLSURWM,
output logic [P.XLEN+1:0] IHAdrM,
Expand All @@ -73,6 +76,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
L1_ADR, L1_RD,
L2_ADR, L2_RD,
L3_ADR, L3_RD,
L4_ADR, L4_RD,
LEAF, IDLE, UPDATE_PTE,
FAULT} statetype;

Expand All @@ -85,7 +89,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic StartWalk;
logic TLBMissOrUpdateDA;
logic PRegEn;
logic [1:0] NextPageType;
logic [2:0] NextPageType;
logic [P.SVMODE_BITS-1:0] SvMode;
logic [P.XLEN-1:0] TranslationVAdr;
logic [P.XLEN-1:0] NextPTE, NextPTE2;
Expand Down Expand Up @@ -179,7 +183,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); // NextPTE = ReadDataM when ADUE = 0 because UpdatePTE = 0
flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);

assign SaveHPTWAdr = (NextWalkerState == L0_RD | NextWalkerState == L1_RD | NextWalkerState == L2_RD | NextWalkerState == L3_RD); // save the HPTWAdr when the walker is about to read the PTE at any level; the last level read is the one to write during UpdatePTE
assign SaveHPTWAdr = (NextWalkerState == L0_RD | NextWalkerState == L1_RD | NextWalkerState == L2_RD | NextWalkerState == L3_RD | NextWalkerState == L4_RD ); // save the HPTWAdr when the walker is about to read the PTE at any level; the last level read is the one to write during UpdatePTE
assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0];
mux2 #(P.PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr);

Expand All @@ -194,7 +198,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (

// Check for page faults
vm64check #(P) vm64check(.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), .VAdr(TranslationVAdr),
.SV39Mode(), .UpperBitsUnequal);
.SV39Mode(), .SV48Mode(), .UpperBitsUnequal);
// This register is not functionally necessary, but improves the critical path.
flopr #(1) upperbitsunequalreg(clk, reset, UpperBitsUnequal, UpperBitsUnequalD);
assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable);
Expand All @@ -221,18 +225,19 @@ module hptw import cvw::*; #(parameter cvw_t P) (

// Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMissOrUpdateDA;
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign HPTWRW[1] = (WalkerState == L4_RD) | (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;

// FSM to track PageType based on the levels of the page table traversed
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
flopr #(3) PageTypeReg(clk, reset, NextPageType, PageType);
always_comb
case (WalkerState)
L3_RD: NextPageType = 2'b11; // terapage
L2_RD: NextPageType = 2'b10; // gigapage
L1_RD: NextPageType = 2'b01; // megapage
L0_RD: NextPageType = 2'b00; // kilopage
L4_RD: NextPageType = 3'b100; // petapage
L3_RD: NextPageType = 3'b011; // terapage
L2_RD: NextPageType = 3'b010; // gigapage
L1_RD: NextPageType = 3'b001; // megapage
L0_RD: NextPageType = 3'b000; // kilopage
default: NextPageType = PageType;
endcase

Expand All @@ -249,13 +254,15 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic [P.PPN_BITS-1:0] PPN;
always_comb
case (WalkerState) // select VPN field based on HPTW state
L4_ADR, L4_RD: VPN = TranslationVAdr[56:48]; // Extracted top 9 bits for sv57
L3_ADR, L3_RD: VPN = TranslationVAdr[47:39];
L2_ADR, L2_RD: VPN = TranslationVAdr[38:30];
L1_ADR, L1_RD: VPN = TranslationVAdr[29:21];
default: VPN = TranslationVAdr[20:12];
endcase
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
(SvMode != P.SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
assign PPN = ( (SvMode == P.SV57 & (WalkerState == L4_ADR | WalkerState == L4_RD)) | // added 4th level for sv57
(SvMode == P.SV48 & (WalkerState == L3_ADR | WalkerState == L3_RD)) |
(SvMode == P.SV39 & (WalkerState == L2_ADR | WalkerState == L2_RD)) ) ? BasePageTablePPN : CurrentPPN;
assign HPTWReadAdr = {PPN, VPN, 3'b000};
assign HPTWSize = 3'b011;
end
Expand All @@ -266,12 +273,13 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
end else begin
logic GigapageMisaligned, TerapageMisaligned;
assign InitialWalkerState = (SvMode == P.SV48) ? L3_ADR : L2_ADR;
logic PetapageMisaligned, GigapageMisaligned, TerapageMisaligned;
assign InitialWalkerState = (SvMode == P.SV57) ? L4_ADR : (SvMode == P.SV48) ? L3_ADR : L2_ADR ;
assign PetapageMisaligned = |(CurrentPPN[35:0]); // Must have zero PPN3, PPN2, PPN1, PPN0 for sv57
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 Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
assign Misaligned = ((WalkerState == L3_ADR) & PetapageMisaligned) | ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
end

// Page Table Walker FSM
Expand All @@ -280,7 +288,13 @@ module hptw import cvw::*; #(parameter cvw_t P) (
case (WalkerState)
IDLE: if (TLBMissOrUpdateDA) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // First access in SV48
L4_ADR: NextWalkerState = L4_RD; // First access in SV57
L4_RD: if (HPTWFaultM) NextWalkerState = FAULT;
else if (DCacheBusStallM) NextWalkerState = L4_RD;
else NextWalkerState = L3_ADR; // Transition to level 3
L3_ADR: if (HPTWFaultM) NextWalkerState = FAULT;
else if (InitialWalkerState == L3_ADR | ValidNonLeafPTE) NextWalkerState = L3_RD; // First access in SV48
else NextWalkerState = LEAF;
L3_RD: if (HPTWFaultM) NextWalkerState = FAULT;
else if (DCacheBusStallM) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR;
Expand Down
2 changes: 1 addition & 1 deletion src/mmu/mmu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
input logic [P.XLEN-1:0] PTE, // page table entry
input logic [1:0] PageTypeWriteVal, // page type
input logic [2:0] PageTypeWriteVal, // page type
input logic TLBWrite, // write TLB entry
input logic TLBFlush, // Invalidate all TLB entries
output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
Expand Down
22 changes: 13 additions & 9 deletions src/mmu/tlb/tlb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic DisableTranslation,
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
input logic [P.XLEN-1:0] PTE, // page table entry to write
input logic [1:0] PageTypeWriteVal,
input logic [2:0] PageTypeWriteVal,
input logic TLBWrite,
input logic TLBFlush,
output logic [P.PA_BITS-1:0] TLBPAdr,
Expand All @@ -84,26 +84,30 @@ module tlb import cvw::*; #(parameter cvw_t P,
logic [P.PPN_BITS-1:0] PPN;
// Sections of the page table entry
logic [11:0] PTEAccessBits;
logic [1:0] HitPageType;
logic [2:0] HitPageType;
logic CAMHit;
logic TLBHit;
logic SV39Mode;
logic SV48Mode;
logic Misaligned;
logic MegapageMisaligned;
logic PTE_N; // NAPOT page table entry
logic NAPOT4; // pte.ppn[3:0] = 1000, indicating 64 KiB continuous NAPOT region

if(P.XLEN == 32) begin
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0
assign Misaligned = (HitPageType == 2'b01) & MegapageMisaligned;
assign Misaligned = (HitPageType == 3'b001) & MegapageMisaligned;
end else begin // 64-bit
logic GigapageMisaligned, TerapageMisaligned;
logic GigapageMisaligned, TerapageMisaligned, PetapageMisaligned;
assign PetapageMisaligned = |(PPN[35:0]); // must have zero PPN3, PPN2, PPN1, PPN0
assign TerapageMisaligned = |(PPN[26:0]); // must have zero PPN2, PPN1, PPN0
assign GigapageMisaligned = |(PPN[17:0]); // must have zero PPN1 and PPN0
assign MegapageMisaligned = |(PPN[8:0]); // must have zero PPN0
assign Misaligned = ((HitPageType == 2'b11) & TerapageMisaligned) |
((HitPageType == 2'b10) & GigapageMisaligned) |
((HitPageType == 2'b01) & MegapageMisaligned);
assign Misaligned =
((HitPageType == 3'b100) & PetapageMisaligned) |
((HitPageType == 3'b011) & TerapageMisaligned) |
((HitPageType == 3'b010) & GigapageMisaligned) |
((HitPageType == 3'b001) & MegapageMisaligned);
end

assign VPN = VAdr[P.VPN_BITS+11:12];
Expand All @@ -113,11 +117,11 @@ module tlb import cvw::*; #(parameter cvw_t P,
.EffectivePrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation,
.PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4,
.TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);
.UpdateDA, .SV39Mode, .SV48Mode, .Translate, .PTE_N, .PBMemoryType);

tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .Matches, .TLBHit, .WriteEnables);
tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS)
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs,
tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .SV48Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs,
.SATP_ASID, .Matches, .HitPageType, .CAMHit);
tlbram #(P, TLB_ENTRIES) tlbram(.clk, .reset, .PTE, .Matches, .WriteEnables, .PPN, .PTEAccessBits, .PTE_Gs, .PTE_NAPOTs);

Expand Down
11 changes: 6 additions & 5 deletions src/mmu/tlb/tlbcam.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,20 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
parameter TLB_ENTRIES = 8, KEY_BITS = 20, SEGMENT_BITS = 10) (
input logic clk, reset,
input logic [P.VPN_BITS-1:0] VPN,
input logic [1:0] PageTypeWriteVal,
input logic [2:0] PageTypeWriteVal,
input logic SV39Mode,
input logic SV48Mode,
input logic TLBFlush,
input logic [TLB_ENTRIES-1:0] WriteEnables,
input logic [TLB_ENTRIES-1:0] PTE_Gs,
input logic [TLB_ENTRIES-1:0] PTE_NAPOTs, // entry is in NAPOT mode (N bit set and PPN[3:0] = 1000)
input logic [P.ASID_BITS-1:0] SATP_ASID,
output logic [TLB_ENTRIES-1:0] Matches,
output logic [1:0] HitPageType,
output logic [2:0] HitPageType,
output logic CAMHit
);

logic [1:0] PageTypeRead [TLB_ENTRIES-1:0];
logic [2:0] PageTypeRead [TLB_ENTRIES-1:0];

// TLB_ENTRIES CAM lines, each of which will independently consider
// whether the requested virtual address is a match. Each line stores the
Expand All @@ -55,8 +56,8 @@ module tlbcam import cvw::*; #(parameter cvw_t P,
// page number segments.

tlbcamline #(P, KEY_BITS, SEGMENT_BITS) camlines[TLB_ENTRIES-1:0](
.clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs), .PageTypeWriteVal, .TLBFlush,
.clk, .reset, .VPN, .SATP_ASID, .SV39Mode, .SV48Mode, .PTE_G(PTE_Gs), .PTE_NAPOT(PTE_NAPOTs), .PageTypeWriteVal, .TLBFlush,
.WriteEnable(WriteEnables), .PageTypeRead, .Match(Matches));
assign CAMHit = |Matches & ~TLBFlush;
or_rows #(TLB_ENTRIES,2) PageTypeOr(PageTypeRead, HitPageType);
or_rows #(TLB_ENTRIES,3) PageTypeOr(PageTypeRead, HitPageType);
endmodule
Loading
Loading