From 1ae529c4502eba08c9422660ff60a4bb3a6bca22 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 4 Jun 2021 17:05:07 -0400 Subject: [PATCH] restructured so that pma/pmp are a part of mmu --- wally-pipelined/src/dmem/dmem.sv | 39 ++++++++++--- wally-pipelined/src/ebu/ahblite.sv | 4 +- wally-pipelined/src/ifu/ifu.sv | 32 ++++++----- wally-pipelined/src/mmu/mmu.sv | 57 ++++++++++--------- wally-pipelined/src/mmu/tlb.sv | 30 +++++----- wally-pipelined/src/privileged/privileged.sv | 27 +++++---- .../src/wally/wallypipelinedhart.sv | 17 ++++-- 7 files changed, 125 insertions(+), 81 deletions(-) diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv index 67569f2e..deaef9a9 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/dmem/dmem.sv @@ -53,18 +53,36 @@ module dmem ( output logic DTLBLoadPageFaultM, DTLBStorePageFaultM, output logic LoadMisalignedFaultM, LoadAccessFaultM, output logic StoreMisalignedFaultM, StoreAccessFaultM, - // TLB management + + // mmu management input logic [1:0] PrivilegeModeW, input logic [`XLEN-1:0] PageTableEntryM, input logic [1:0] PageTypeM, 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 DTLBWriteM, DTLBFlushM, - output logic DTLBMissM, DTLBHitM + output logic DTLBMissM, DTLBHitM, + + // PMA/PMP (inside mmu) signals + input logic [31:0] HADDR, // *** replace all of these H inputs with physical adress once pma checkers have been edited to use paddr as well. + input logic [2:0] HSIZE, HBURST, + input logic HWRITE, + input logic AtomicAccessM, WriteAccessM, ReadAccessM, // execute access is hardwired to zero in this mmu because we're only working with data in the M stage. + input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem + input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15], // *** this one especially has a large note attached to it in pmpchecker. + + output logic PMALoadAccessFaultM, PMAStoreAccessFaultM, + output logic PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa. + + output logic DCacheableM, DIdempotentM, DAtomicAllowedM, + output logic DSquashBusAccessM, + output logic [5:0] DHSELRegionsM + ); - logic SquashSCM; - logic DTLBPageFaultM; + logic SquashSCM; + logic DTLBPageFaultM; logic MemAccessM; logic [1:0] CurrState, NextState; @@ -74,12 +92,19 @@ module dmem ( localparam STATE_FETCH_AMO = 2; localparam STATE_STALLED = 3; - tlb #(.ENTRY_BITS(3), .ITLB(0)) dtlb(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM), + logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem + // *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete. + + mmu #(.ENTRY_BITS(`DTLB_ENTRY_BITS), .IMMU(0)) dmmu(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM), .PageTableEntryWrite(PageTableEntryM), .PageTypeWrite(PageTypeM), .TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM), .PhysicalAddress(MemPAdrM), .TLBMiss(DTLBMissM), .TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM), - .*); + + .ExecuteAccessF(1'b0), + .Cacheable(DCacheableM), .Idempotent(DIdempotentM), .AtomicAllowed(DAtomicAllowedM), + .SquashBusAccess(DSquashBusAccessM), .HSELRegions(DHSELRegionsM), + .*); // *** the pma/pmp instruction acess faults don't really matter here. is it possible to parameterize which outputs exist? // Specify which type of page fault is occurring assign DTLBLoadPageFaultM = DTLBPageFaultM & MemRWM[1]; diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index a31448ea..2fd763c1 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -58,7 +58,7 @@ module ahblite ( output logic [`XLEN-1:0] MMUReadPTE, output logic MMUReady, // Signals from PMA checker - input logic SquashBusAccess, + input logic DSquashBusAccessM, ISquashBusAccessF, // Signals to PMA checker (metadata of proposed access) output logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // Return from bus @@ -147,7 +147,7 @@ module ahblite ( (ProposedNextBusState == MMUTRANSLATE); // The PMA and PMP checkers can decide to squash the access - assign NextBusState = (SquashBusAccess) ? IDLE : ProposedNextBusState; + assign NextBusState = (DSquashBusAccessM || ISquashBusAccessF) ? IDLE : ProposedNextBusState; // stall signals // Note that we need to extend both stalls when MMUTRANSLATE goes to idle, diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 2aa30fc5..8df871f3 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -63,20 +63,27 @@ module ifu ( output logic IllegalIEUInstrFaultD, output logic InstrMisalignedFaultM, output logic [`XLEN-1:0] InstrMisalignedAdrM, - // TLB management + + + // mmu management input logic [1:0] PrivilegeModeW, 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, // *** the last two are for the pmp checker. input logic ITLBWriteF, ITLBFlushF, output logic ITLBMissF, ITLBHitF, - // MMU signals. *** temporarily from AHB bus but eventually replace with internal versions pre H + // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H input logic [31:0] HADDR, input logic [2:0] HSIZE, HBURST, input logic HWRITE, - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, + input logic ExecuteAccessF, //read, write, and atomic access are all set to zero because this mmu is onlt working with instructinos in the F stage. + input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem + input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15], // *** this one especially has a large note attached to it in pmpchecker. + + output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF, output logic ICacheableF, IIdempotentF, IAtomicAllowedF, output logic ISquashBusAccessF, output logic [5:0] IHSELRegionsF @@ -94,28 +101,25 @@ module ifu ( logic reset_q; // *** look at this later. logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE; - -/* tlb #(.ENTRY_BITS(3), .ITLB(1)) itlb(.TLBAccessType(2'b10), .VirtualAddress(PCF), - .PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF), - .TLBWrite(ITLBWriteF), .TLBFlush(ITLBFlushF), - .PhysicalAddress(PCPF), .TLBMiss(ITLBMissF), - .TLBHit(ITLBHitF), .TLBPageFault(ITLBInstrPageFaultF), - .*); */ + logic PMALoadAccessFaultM, PMAStoreAccessFaultM; + logic PMPLoadAccessFaultM, PMPStoreAccessFaultM; // *** these are just so that the mmu has somewhere to put these outputs, they're unused in this stage + // if you're allowed to parameterize outputs/ inputs existence, these are an easy delete. + mmu #(.ENTRY_BITS(`ITLB_ENTRY_BITS), .IMMU(1)) itlb(.TLBAccessType(2'b10), .VirtualAddress(PCF), .PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF), .TLBWrite(ITLBWriteF), .TLBFlush(ITLBFlushF), .PhysicalAddress(PCPF), .TLBMiss(ITLBMissF), .TLBHit(ITLBHitF), .TLBPageFault(ITLBInstrPageFaultF), - .AtomicAccessM(1'b0), .WriteAccessM(1'b0), .ReadAccessM(1'b0), + .AtomicAccessM(1'b0), .WriteAccessM(1'b0), .ReadAccessM(1'b0), // *** is this the right way force these bits constant? should they be someething else? .Cacheable(ICacheableF), .Idempotent(IIdempotentF), .AtomicAllowed(IAtomicAllowedF), - .SquashBusAccess(.ISquashBusAccssF), .HSELRegionsF(.IHSELRegionsF)), + .SquashBusAccess(ISquashBusAccessF), .HSELRegions(IHSELRegionsF), .*); // branch predictor signals - logic SelBPPredF; + logic SelBPPredF; logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F, PCNext3F; logic [4:0] InstrClassD, InstrClassE; diff --git a/wally-pipelined/src/mmu/mmu.sv b/wally-pipelined/src/mmu/mmu.sv index fefce5ea..58935eb9 100644 --- a/wally-pipelined/src/mmu/mmu.sv +++ b/wally-pipelined/src/mmu/mmu.sv @@ -28,54 +28,65 @@ // The TLB will have 2**ENTRY_BITS total entries -module mmu #(parameter IMMU = 0) ( - input clk, reset, +module mmu #(parameter ENTRY_BITS = 3, + parameter IMMU = 0) ( + + input logic clk, reset, // Current value of satp CSR (from privileged unit) - input [`XLEN-1:0] SATP_REGW, - input STATUS_MXR, STATUS_SUM, + input logic [`XLEN-1:0] SATP_REGW, + input logic STATUS_MXR, STATUS_SUM, // Current privilege level of the processeor - input [1:0] PrivilegeModeW, + input logic [1:0] PrivilegeModeW, // 00 - TLB is not being accessed // 1x - TLB is accessed for a read (or an instruction) // x1 - TLB is accessed for a write // 11 - TLB is accessed for both read and write - input [1:0] TLBAccessType, + input logic [1:0] TLBAccessType, // Virtual address input - input [`XLEN-1:0] VirtualAddress, + input logic [`XLEN-1:0] VirtualAddress, // Controls for writing a new entry to the TLB - input [`XLEN-1:0] PageTableEntryWrite, - input [1:0] PageTypeWrite, - input TLBWrite, + input logic [`XLEN-1:0] PageTableEntryWrite, + input logic [1:0] PageTypeWrite, + input logic TLBWrite, // Invalidate all TLB entries - input TLBFlush, + input logic TLBFlush, // Physical address outputs - output [`XLEN-1:0] PhysicalAddress, - output TLBMiss, - output TLBHit, + output logic [`XLEN-1:0] PhysicalAddress, + output logic TLBMiss, + output logic TLBHit, // Faults - output TLBPageFault, + output logic TLBPageFault, - // PMA checker signals + // PMA checker signals input logic [31:0] HADDR, input logic [2:0] HSIZE, HBURST, input logic HWRITE, input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, + input logic STATUS_MPRV, + input logic [1:0] STATUS_MPP, + input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem + input logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15], // *** this one especially has a large note attached to it in pmpchecker. + output logic Cacheable, Idempotent, AtomicAllowed, - output logic SquashBusAccess, + output logic SquashBusAccess, // *** send to privileged unit + output logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM, + output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM, output logic [5:0] HSELRegions ); + logic PMPSquashBusAccess, PMASquashBusAccess; + // Translation lookaside buffer - tlb tlb #(.ENTRY_BITS(.ENTRY_BITS), .ITLB(IMMU)) itlb(.*); + tlb #(.ENTRY_BITS(ENTRY_BITS), .ITLB(IMMU)) tlb(.*); /////////////////////////////////////////// // Check physical memory accesses @@ -84,13 +95,7 @@ module mmu #(parameter IMMU = 0) ( pmachecker pmachecker(.*); pmpchecker pmpchecker(.*); - *** to edit - edit PMP/PMA to use phyisical address information instead of HADDR / AHB signals [Later after it works] - *move PMA checker to MMU from privileged - *move PMP checker to MMU from privileged - *delete PMA/PMP signals from priviliged & above no longer needed - replace TLB with MMU in IFU and DMEM - adjust for two PMA/PMP outputs (IFU, DMEM) instead of just one for Bus - Move M_MODE, other constants from each config file to wally-constants, #include wally-constants as needed + + assign SquashBusAccess = PMASquashBusAccess || PMPSquashBusAccess; endmodule \ No newline at end of file diff --git a/wally-pipelined/src/mmu/tlb.sv b/wally-pipelined/src/mmu/tlb.sv index 1828c98e..7a6740d1 100644 --- a/wally-pipelined/src/mmu/tlb.sv +++ b/wally-pipelined/src/mmu/tlb.sv @@ -52,39 +52,39 @@ // The TLB will have 2**ENTRY_BITS total entries module tlb #(parameter ENTRY_BITS = 3, parameter ITLB = 0) ( - input clk, reset, + input logic clk, reset, // Current value of satp CSR (from privileged unit) - input [`XLEN-1:0] SATP_REGW, - input STATUS_MXR, STATUS_SUM, + input logic [`XLEN-1:0] SATP_REGW, + input logic STATUS_MXR, STATUS_SUM, // Current privilege level of the processeor - input [1:0] PrivilegeModeW, + input logic [1:0] PrivilegeModeW, // 00 - TLB is not being accessed // 1x - TLB is accessed for a read (or an instruction) // x1 - TLB is accessed for a write // 11 - TLB is accessed for both read and write - input [1:0] TLBAccessType, + input logic [1:0] TLBAccessType, // Virtual address input - input [`XLEN-1:0] VirtualAddress, + input logic [`XLEN-1:0] VirtualAddress, // Controls for writing a new entry to the TLB - input [`XLEN-1:0] PageTableEntryWrite, - input [1:0] PageTypeWrite, - input TLBWrite, + input logic [`XLEN-1:0] PageTableEntryWrite, + input logic [1:0] PageTypeWrite, + input logic TLBWrite, // Invalidate all TLB entries - input TLBFlush, + input logic TLBFlush, // Physical address outputs - output [`XLEN-1:0] PhysicalAddress, - output TLBMiss, - output TLBHit, + output logic [`XLEN-1:0] PhysicalAddress, + output logic TLBMiss, + output logic TLBHit, // Faults - output TLBPageFault + output logic TLBPageFault ); logic Translate; @@ -144,7 +144,7 @@ module tlb #(parameter ENTRY_BITS = 3, assign PageOffset = VirtualAddress[11:0]; // TLB entries are evicted according to the LRU algorithm - tlb_lru lru(.*); + tlb_lru #(ENTRY_BITS) lru(.*); tlb_ram #(ENTRY_BITS) tlb_ram(.*); tlb_cam #(ENTRY_BITS, `VPN_BITS, `VPN_SEGMENT_BITS) tlb_cam(.*); diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 95e757a8..0ca8ba4c 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -53,12 +53,25 @@ module privileged ( input logic TimerIntM, ExtIntM, SwIntM, input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [4:0] SetFflagsM, + + // Trap signals from pmp/pma in mmu + // *** do these need to be split up into one for dmem and one for ifu? + // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem? + + input logic PMAInstrAccessFaultF, PMPInstrAccessFaultF, + input logic PMALoadAccessFaultM, PMPLoadAccessFaultM, + input logic PMAStoreAccessFaultM, PMPStoreAccessFaultM, + 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 logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, + output logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15], //*** to be sent up through wallypipelinedhart into the pma/pmp in ifu and dmem. *** is it a bad idea to have this huge bus running all over? output logic [2:0] FRM_REGW, - input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM, + input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM + ); logic [1:0] NextPrivilegeModeM; @@ -82,19 +95,11 @@ module privileged ( logic MTrapM, STrapM, UTrapM; logic InterruptM; - logic [1:0] STATUS_MPP; logic STATUS_SPP, STATUS_TSR; logic STATUS_MIE, STATUS_SIE; - logic STATUS_MPRV; logic [11:0] MIP_REGW, MIE_REGW; logic md, sd; - logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW; - logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15]; - - logic PMASquashBusAccess, PMPSquashBusAccess; - logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM; - logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM; /////////////////////////////////////////// // track the current privilege level @@ -154,8 +159,6 @@ module privileged ( assign LoadAccessFaultM = PMALoadAccessFaultM || PMPLoadAccessFaultM; assign StoreAccessFaultM = PMAStoreAccessFaultM || PMPStoreAccessFaultM; - assign SquashBusAccess = PMASquashBusAccess || PMPSquashBusAccess; - // pipeline fault signals flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD, {InstrPageFaultF, InstrAccessFaultF}, diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index aa252e37..a567bf55 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -110,16 +110,23 @@ module wallypipelinedhart ( logic ITLBMissF, ITLBHitF; logic DTLBMissM, DTLBHitM; logic [`XLEN-1:0] SATP_REGW; - logic STATUS_MXR, STATUS_SUM; - logic [1:0] PrivilegeModeW; + logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; + logic [1:0] PrivilegeModeW, STATUS_MPP; logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; logic [1:0] PageTypeF, PageTypeM; // PMA checker signals logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM; - logic Cacheable, Idempotent, AtomicAllowed; - logic SquashBusAccess; + logic DCacheableM, DIdempotentM, DAtomicAllowedM; + logic ICacheableF, IIdempotentF, IAtomicAllowedF; + logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM; + logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM; + logic DSquashBusAccessM, ISquashBusAccessF; + logic [5:0] DHSELRegionsM, IHSELRegionsF; + logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:15]; // *** again, this is a huge bus to be sending all around. + logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW; // signals being sent from privileged unit to pmp/pma in dmem and ifu. + assign HSELRegions = ExecuteAccessF ? IHSELRegionsF : DHSELRegionsM; // *** this is a pure guess on how one of these should be selected. it passes tests, but is it the right way to do this? // IMem stalls logic ICacheStallF; @@ -185,7 +192,7 @@ module wallypipelinedhart ( privileged priv(.*); - fpu fpu(.*); // floating point unit + fpu fpu(.*); // floating point unit // add FPU here, with SetFflagsM, FRM_REGW // presently stub out SetFlagsM and FloatRegWriteW //assign SetFflagsM = 0;