From 394f2d65f24062727f59e1e6394d5d4b37f7dd59 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 5 Apr 2023 13:20:04 -0500 Subject: [PATCH] Progress on bug 203. --- src/lsu/lsu.sv | 6 +++--- src/mmu/hptw.sv | 30 ++++++++++++++++++++++++------ src/privileged/privileged.sv | 8 +++++--- src/privileged/privpiperegs.sv | 28 +++++++++++++++------------- src/wally/wallypipelinedcore.sv | 6 +++--- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index f2e147f00..51efeccb2 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -62,7 +62,7 @@ module lsu ( output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions output logic LoadMisalignedFaultM, // Load address misaligned fault output logic LoadAccessFaultM, // Load access fault (PMA) - output logic HPTWInstrAccessFaultM, // HPTW generated access fault during instruction fetch + output logic HPTWInstrAccessFaultF, // HPTW generated access fault during instruction fetch // cpu hazard unit (trap) output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault output logic StoreAmoAccessFaultM, // Store or AMO access fault @@ -159,7 +159,7 @@ module lsu ( .IEUAdrExtM, .PTE, .IHWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IHAdrM, .HPTWStall, .SelHPTW, .IgnoreRequestTLB, .LSULoadAccessFaultM, .LSUStoreAmoAccessFaultM, - .LoadAccessFaultM, .StoreAmoAccessFaultM, .HPTWInstrAccessFaultM); + .LoadAccessFaultM, .StoreAmoAccessFaultM, .HPTWInstrAccessFaultF); end else begin // No HPTW, so signals are not multiplexed assign PreLSURWM = MemRWM; assign IHAdrM = IEUAdrExtM; @@ -170,7 +170,7 @@ module lsu ( assign LoadAccessFaultM = LSULoadAccessFaultM; assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM; assign {HPTWStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0; - assign HPTWInstrAccessFaultM = '0; + assign HPTWInstrAccessFaultF = '0; end // CommittedM indicates the cache, bus, or HPTW are busy with a multiple cycle operation. diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index b093167cf..95ab43360 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -64,7 +64,7 @@ module hptw ( output logic SelHPTW, output logic HPTWStall, input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, - output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM + output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultF ); typedef enum logic [3:0] {L0_ADR, L0_RD, @@ -98,12 +98,25 @@ module hptw ( logic [1:0] HPTWRW; logic [2:0] HPTWSize; // 32 or 64 bit access statetype WalkerState, NextWalkerState, InitialWalkerState; + logic HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault; + logic HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay; + logic HPTWAccessFaultDelay; + logic TakeHPTWFault, TakeHPTWFaultDelay; // map hptw access faults onto either the original LSU load/store fault or instruction access fault assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM; - assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0]; - assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[0]; - assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: LSUAccessFaultM & ~DTLBWalk; + assign HPTWLoadAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0]; + assign HPTWStoreAmoAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[0]; + assign HPTWInstrAccessFault = LSUAccessFaultM & ~DTLBWalk; + + flopr #(4) HPTWAccesFaultReg(clk, reset, {TakeHPTWFault, HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault}, + {TakeHPTWFaultDelay, HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay}); + + assign TakeHPTWFault = WalkerState != IDLE; + + assign LoadAccessFaultM = TakeHPTWFaultDelay ? HPTWLoadAccessFaultDelay : LSULoadAccessFaultM; + assign StoreAmoAccessFaultM = TakeHPTWFaultDelay ? HPTWStoreAmoAccessFaultDelay : LSUStoreAmoAccessFaultM; + assign HPTWInstrAccessFaultF = TakeHPTWFaultDelay ? HPTWInstrAccessFaultDelay : 1'b0; // Extract bits from CSRs and inputs assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; @@ -247,22 +260,26 @@ module hptw ( flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); always_comb case (WalkerState) - IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState; + IDLE: if (TLBMiss & ~DCacheStallM & ~HPTWAccessFaultDelay) NextWalkerState = InitialWalkerState; else NextWalkerState = IDLE; L3_ADR: NextWalkerState = L3_RD; // first access in SV48 L3_RD: if (DCacheStallM) NextWalkerState = L3_RD; + else if(LSUAccessFaultM) NextWalkerState = IDLE; else NextWalkerState = L2_ADR; L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39 else NextWalkerState = LEAF; L2_RD: if (DCacheStallM) NextWalkerState = L2_RD; + else if(LSUAccessFaultM) NextWalkerState = IDLE; else NextWalkerState = L1_ADR; L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32 else NextWalkerState = LEAF; L1_RD: if (DCacheStallM) NextWalkerState = L1_RD; + else if(LSUAccessFaultM) NextWalkerState = IDLE; else NextWalkerState = L0_ADR; L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; else NextWalkerState = LEAF; L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; + else if(LSUAccessFaultM) NextWalkerState = IDLE; else NextWalkerState = LEAF; LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE; else NextWalkerState = IDLE; @@ -273,7 +290,8 @@ module hptw ( assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss; assign SelHPTW = WalkerState != IDLE; - assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss); + assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay; + assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss & ~(HPTWAccessFaultDelay)); assign ITLBMissOrUpdateDAF = ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF); assign DTLBMissOrUpdateDAM = DTLBMissM | (`SVADU_SUPPORTED & DataUpdateDAM); diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 6fa8dcf98..37e7d1752 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -65,7 +65,7 @@ module privileged ( // fault sources input logic InstrAccessFaultF, // instruction access fault input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault - input logic HPTWInstrAccessFaultM, // hardware page table access fault while fetching instruction PTE + input logic HPTWInstrAccessFaultF, // hardware page table access fault while fetching instruction PTE input logic InstrPageFaultF, // page faults input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults input logic InstrMisalignedFaultM, // misaligned instruction fault @@ -114,6 +114,8 @@ module privileged ( logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi logic InterruptM; // interrupt occuring logic ExceptionM; // Memory stage instruction caused a fault + logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE + // track the current privilege level privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, @@ -144,8 +146,8 @@ module privileged ( // pipeline early-arriving trap sources privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, - .InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUFPUInstrD, - .InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUFPUInstrM); + .InstrPageFaultF, .InstrAccessFaultF, .HPTWInstrAccessFaultF, .IllegalIEUFPUInstrD, + .InstrPageFaultM, .InstrAccessFaultM, .HPTWInstrAccessFaultM, .IllegalIEUFPUInstrM); // trap logic trap trap(.reset, diff --git a/src/privileged/privpiperegs.sv b/src/privileged/privpiperegs.sv index c3d308c11..684b0ad73 100644 --- a/src/privileged/privpiperegs.sv +++ b/src/privileged/privpiperegs.sv @@ -33,24 +33,26 @@ module privpiperegs ( input logic StallD, StallE, StallM, input logic FlushD, FlushE, FlushM, input logic InstrPageFaultF, InstrAccessFaultF, // instruction faults + input logic HPTWInstrAccessFaultF, // hptw fault during instruction page fetch input logic IllegalIEUFPUInstrD, // illegal IEU instruction decoded output logic InstrPageFaultM, InstrAccessFaultM, // delayed instruction faults - output logic IllegalIEUFPUInstrM // delayed illegal IEU instruction + output logic IllegalIEUFPUInstrM, // delayed illegal IEU instruction + output logic HPTWInstrAccessFaultM // hptw fault during instruction page fetch ); // Delayed fault signals - logic InstrPageFaultD, InstrAccessFaultD; - logic InstrPageFaultE, InstrAccessFaultE; + logic InstrPageFaultD, InstrAccessFaultD, HPTWInstrAccessFaultD; + logic InstrPageFaultE, InstrAccessFaultE, HPTWInstrAccessFaultE; logic IllegalIEUFPUInstrE; // pipeline fault signals - flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD, - {InstrPageFaultF, InstrAccessFaultF}, - {InstrPageFaultD, InstrAccessFaultD}); - flopenrc #(3) faultregE(clk, reset, FlushE, ~StallE, - {IllegalIEUFPUInstrD, InstrPageFaultD, InstrAccessFaultD}, - {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE}); - flopenrc #(3) faultregM(clk, reset, FlushM, ~StallM, - {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE}, - {IllegalIEUFPUInstrM, InstrPageFaultM, InstrAccessFaultM}); -endmodule \ No newline at end of file + flopenrc #(3) faultregD(clk, reset, FlushD, ~StallD, + {InstrPageFaultF, InstrAccessFaultF, HPTWInstrAccessFaultF}, + {InstrPageFaultD, InstrAccessFaultD, HPTWInstrAccessFaultD}); + flopenrc #(4) faultregE(clk, reset, FlushE, ~StallE, + {IllegalIEUFPUInstrD, InstrPageFaultD, InstrAccessFaultD, HPTWInstrAccessFaultD}, + {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE, HPTWInstrAccessFaultE}); + flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM, + {IllegalIEUFPUInstrE, InstrPageFaultE, InstrAccessFaultE, HPTWInstrAccessFaultE}, + {IllegalIEUFPUInstrM, InstrPageFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM}); +endmodule diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 343cf1fdb..d37e871d8 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -146,7 +146,7 @@ module wallypipelinedcore ( logic RASPredPCWrongM; logic IClassWrongM; logic [3:0] InstrClassM; - logic InstrAccessFaultF, HPTWInstrAccessFaultM; + logic InstrAccessFaultF, HPTWInstrAccessFaultF; logic [2:0] LSUHSIZE; logic [2:0] LSUHBURST; logic [1:0] LSUHTRANS; @@ -236,7 +236,7 @@ module wallypipelinedcore ( .StoreAmoPageFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege .LoadAccessFaultM, // connects to privilege - .HPTWInstrAccessFaultM, // connects to privilege + .HPTWInstrAccessFaultF, // connects to privilege .StoreAmoMisalignedFaultM, // connects to privilege .StoreAmoAccessFaultM, // connects to privilege .InstrUpdateDAF, @@ -288,7 +288,7 @@ module wallypipelinedcore ( .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .IEUAdrM, .SetFflagsM, - .InstrAccessFaultF, .HPTWInstrAccessFaultM, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, + .InstrAccessFaultF, .HPTWInstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW, .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,