From a26bf37be8747c4934b07ea094f58dfa59566dba Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 4 Jun 2021 11:59:14 -0400 Subject: [PATCH 1/3] Started MMU --- .../config/buildroot/wally-config.vh | 3 + .../config/busybear/wally-config.vh | 3 + .../config/coremark/wally-config.vh | 4 + .../config/coremark_bare/wally-config.vh | 3 + wally-pipelined/config/rv32ic/wally-config.vh | 3 + wally-pipelined/config/rv64BP/wally-config.vh | 3 + wally-pipelined/config/rv64ic/wally-config.vh | 3 + .../config/rv64icfd/wally-config.vh | 3 + .../config/rv64imc/wally-config.vh | 8 +- .../config/shared/wally-constants.vh | 18 +--- wally-pipelined/src/ifu/ifu.sv | 25 ++++- wally-pipelined/src/mmu/mmu.sv | 96 +++++++++++++++++++ .../src/{privileged => mmu}/pmachecker.sv | 2 +- .../src/{privileged => mmu}/pmpadrdec.sv | 0 .../src/{privileged => mmu}/pmpchecker.sv | 0 wally-pipelined/src/privileged/privileged.sv | 17 +--- 16 files changed, 151 insertions(+), 40 deletions(-) create mode 100644 wally-pipelined/src/mmu/mmu.sv rename wally-pipelined/src/{privileged => mmu}/pmachecker.sv (97%) rename wally-pipelined/src/{privileged => mmu}/pmpadrdec.sv (100%) rename wally-pipelined/src/{privileged => mmu}/pmpchecker.sv (100%) diff --git a/wally-pipelined/config/buildroot/wally-config.vh b/wally-pipelined/config/buildroot/wally-config.vh index 57740b687..7e8a01c4e 100644 --- a/wally-pipelined/config/buildroot/wally-config.vh +++ b/wally-pipelined/config/buildroot/wally-config.vh @@ -60,6 +60,9 @@ `define MEM_VIRTMEM 0 `define VECTORED_INTERRUPTS_SUPPORTED 1 // Domenico Ottolia 4/15: Support for vectored interrupts in _tvec csrs. Just implemented in src/privileged/trap.sv around line 75. Pretty sure this should be 1. +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000000001000 diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh index a840676df..0d3cc4f01 100644 --- a/wally-pipelined/config/busybear/wally-config.vh +++ b/wally-pipelined/config/busybear/wally-config.vh @@ -60,6 +60,9 @@ `define MEM_VIRTMEM 0 `define VECTORED_INTERRUPTS_SUPPORTED 1 // Domenico Ottolia 4/15: Support for vectored interrupts in _tvec csrs. Just implemented in src/privileged/trap.sv around line 75. Pretty sure this should be 1. +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000000001000 diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh index 47e9c7319..0e89b3d07 100644 --- a/wally-pipelined/config/coremark/wally-config.vh +++ b/wally-pipelined/config/coremark/wally-config.vh @@ -58,6 +58,10 @@ `define MEM_DTIM 1 `define MEM_ICACHE 0 `define MEM_VIRTMEM 0 +`define VECTORED_INTERRUPTS_SUPPORTED 1 + +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 // Address space `define RESET_VECTOR 64'h00000000000100b0 diff --git a/wally-pipelined/config/coremark_bare/wally-config.vh b/wally-pipelined/config/coremark_bare/wally-config.vh index b42dd678d..800cdead4 100644 --- a/wally-pipelined/config/coremark_bare/wally-config.vh +++ b/wally-pipelined/config/coremark_bare/wally-config.vh @@ -60,6 +60,9 @@ `define MEM_VIRTMEM 1 `define VECTORED_INTERRUPTS_SUPPORTED 1 +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000080000000 diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index 17daa5722..170b4a8cd 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -59,6 +59,9 @@ `define MEM_VIRTMEM 1 `define VECTORED_INTERRUPTS_SUPPORTED 1 +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 32'h80000000 diff --git a/wally-pipelined/config/rv64BP/wally-config.vh b/wally-pipelined/config/rv64BP/wally-config.vh index f85e0c228..688ea8658 100644 --- a/wally-pipelined/config/rv64BP/wally-config.vh +++ b/wally-pipelined/config/rv64BP/wally-config.vh @@ -61,6 +61,9 @@ `define MEM_VIRTMEM 1 `define VECTORED_INTERRUPTS_SUPPORTED 1 +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000000000000 diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 12d254ba8..dad3948fe 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -60,6 +60,9 @@ `define MEM_VIRTMEM 1 `define VECTORED_INTERRUPTS_SUPPORTED 1 +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000080000000 diff --git a/wally-pipelined/config/rv64icfd/wally-config.vh b/wally-pipelined/config/rv64icfd/wally-config.vh index 4b0ce324b..f5607a8c1 100644 --- a/wally-pipelined/config/rv64icfd/wally-config.vh +++ b/wally-pipelined/config/rv64icfd/wally-config.vh @@ -60,6 +60,9 @@ `define MEM_VIRTMEM 1 `define VECTORED_INTERRUPTS_SUPPORTED 1 +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 + // Address space `define RESET_VECTOR 64'h0000000080000000 diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh index 8c42cd81c..e226b9ffd 100644 --- a/wally-pipelined/config/rv64imc/wally-config.vh +++ b/wally-pipelined/config/rv64imc/wally-config.vh @@ -46,10 +46,6 @@ //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) `define N_SUPPORTED 0 -`define M_MODE (2'b11) -`define S_MODE (2'b01) -`define U_MODE (2'b00) - // Microarchitectural Features `define UARCH_PIPELINED 1 `define UARCH_SUPERSCALR 0 @@ -58,6 +54,10 @@ `define MEM_DTIM 1 `define MEM_ICACHE 0 `define MEM_VIRTMEM 0 +`define VECTORED_INTERRUPTS_SUPPORTED 1 + +`define ITLB_ENTRY_BITS 5 +`define DTLB_ENTRY_BITS 5 // Address space `define RESET_VECTOR 64'h0000000080000000 diff --git a/wally-pipelined/config/shared/wally-constants.vh b/wally-pipelined/config/shared/wally-constants.vh index ec225f8c4..be0f7688b 100644 --- a/wally-pipelined/config/shared/wally-constants.vh +++ b/wally-pipelined/config/shared/wally-constants.vh @@ -30,23 +30,6 @@ `include "wally-config.vh" -/* -// Virtual Memory Constants (sv48) -`define VPN_SEGMENT_BITS_RV64 9 -`define VPN_BITS_RV64 36 -`define PPN_HIGH_SEGMENT_BITS_RV64 17 -`define PPN_BITS_RV64 44 -`define PA_BITS_RV64 56 -`define SVMODE_BITS_RV64 4 -// Virtual Memory Constants (sv32) -`define VPN_SEGMENT_BITS_RV32 10 -`define VPN_BITS_RV32 20 -`define PPN_HIGH_SEGMENT_BITS_RV32 12 -`define PPN_BITS_RV32 22 -`define PA_BITS_RV32 34 -`define SVMODE_BITS_RV32 1 -*/ - // Virtual Memory Constants `define VPN_SEGMENT_BITS (`XLEN == 32 ? 10 : 9) `define VPN_BITS (`XLEN==32 ? (2*`VPN_SEGMENT_BITS) : (4*`VPN_SEGMENT_BITS)) @@ -61,3 +44,4 @@ `define SV32 1 `define SV39 8 `define SV48 9 + diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index e0507b63d..2aa30fc59 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -70,7 +70,17 @@ module ifu ( input logic [`XLEN-1:0] SATP_REGW, input logic STATUS_MXR, STATUS_SUM, input logic ITLBWriteF, ITLBFlushF, - output logic ITLBMissF, ITLBHitF + output logic ITLBMissF, ITLBHitF, + + // 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, + output logic ICacheableF, IIdempotentF, IAtomicAllowedF, + output logic ISquashBusAccessF, + output logic [5:0] IHSELRegionsF + ); logic [`XLEN-1:0] UnalignedPCNextF, PCNextF; @@ -86,13 +96,24 @@ module ifu ( logic BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE; - tlb #(.ENTRY_BITS(3), .ITLB(1)) itlb(.TLBAccessType(2'b10), .VirtualAddress(PCF), +/* 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), + .*); */ + 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), + .Cacheable(ICacheableF), .Idempotent(IIdempotentF), .AtomicAllowed(IAtomicAllowedF), + .SquashBusAccess(.ISquashBusAccssF), .HSELRegionsF(.IHSELRegionsF)), .*); + // branch predictor signals logic SelBPPredF; logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F, PCNext3F; diff --git a/wally-pipelined/src/mmu/mmu.sv b/wally-pipelined/src/mmu/mmu.sv new file mode 100644 index 000000000..fefce5ea7 --- /dev/null +++ b/wally-pipelined/src/mmu/mmu.sv @@ -0,0 +1,96 @@ +/////////////////////////////////////////// +// mmu.sv +// +// Written: david_harris@hmc.edu and kmacsaigoren@hmc.edu 4 June 2021 +// Modified: +// +// Purpose: Memory management unit, including TLB, PMA, PMP +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + + +`include "wally-config.vh" + +// The TLB will have 2**ENTRY_BITS total entries + +module mmu #(parameter IMMU = 0) ( + input clk, reset, + // Current value of satp CSR (from privileged unit) + input [`XLEN-1:0] SATP_REGW, + input STATUS_MXR, STATUS_SUM, + + // Current privilege level of the processeor + input [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, + + // Virtual address input + input [`XLEN-1:0] VirtualAddress, + + // Controls for writing a new entry to the TLB + input [`XLEN-1:0] PageTableEntryWrite, + input [1:0] PageTypeWrite, + input TLBWrite, + + // Invalidate all TLB entries + input TLBFlush, + + // Physical address outputs + output [`XLEN-1:0] PhysicalAddress, + output TLBMiss, + output TLBHit, + + // Faults + output TLBPageFault, + + // PMA checker signals + input logic [31:0] HADDR, + input logic [2:0] HSIZE, HBURST, + input logic HWRITE, + input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, + output logic Cacheable, Idempotent, AtomicAllowed, + output logic SquashBusAccess, + output logic [5:0] HSELRegions + +); + + // Translation lookaside buffer + + tlb tlb #(.ENTRY_BITS(.ENTRY_BITS), .ITLB(IMMU)) itlb(.*); + + /////////////////////////////////////////// + // Check physical memory accesses + /////////////////////////////////////////// + + 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 + +endmodule \ No newline at end of file diff --git a/wally-pipelined/src/privileged/pmachecker.sv b/wally-pipelined/src/mmu/pmachecker.sv similarity index 97% rename from wally-pipelined/src/privileged/pmachecker.sv rename to wally-pipelined/src/mmu/pmachecker.sv index 2526ec5e6..db4c648b2 100644 --- a/wally-pipelined/src/privileged/pmachecker.sv +++ b/wally-pipelined/src/mmu/pmachecker.sv @@ -66,7 +66,7 @@ module pmachecker ( assign ValidBootTim = '1; assign ValidTim = '1; - assign ValidCLINT = ~ExecuteAccessF && ((HSIZE == 3'b011) || (HSIZE == 3'b010)); + assign ValidCLINT = ~ExecuteAccessF && ((HSIZE == 3'b011 && `XLEN==64) || (HSIZE == 3'b010 && `XLEN==32)); assign ValidGPIO = ~ExecuteAccessF && (HSIZE == 3'b010); assign ValidUART = ~ExecuteAccessF && (HSIZE == 3'b000); assign ValidPLIC = ~ExecuteAccessF && (HSIZE == 3'b010); diff --git a/wally-pipelined/src/privileged/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv similarity index 100% rename from wally-pipelined/src/privileged/pmpadrdec.sv rename to wally-pipelined/src/mmu/pmpadrdec.sv diff --git a/wally-pipelined/src/privileged/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv similarity index 100% rename from wally-pipelined/src/privileged/pmpchecker.sv rename to wally-pipelined/src/mmu/pmpchecker.sv diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index a29fb56e6..95e757a81 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -26,6 +26,7 @@ `include "wally-config.vh" +// *** remove signals not needed by PMA/PMP now that it is moved module privileged ( input logic clk, reset, input logic FlushW, @@ -58,15 +59,6 @@ module privileged ( output logic STATUS_MXR, STATUS_SUM, output logic [2:0] FRM_REGW, input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM, - - // PMA checker signals - input logic [31:0] HADDR, - input logic [2:0] HSIZE, HBURST, - input logic HWRITE, - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, - output logic Cacheable, Idempotent, AtomicAllowed, - output logic SquashBusAccess, - output logic [5:0] HSELRegions ); logic [1:0] NextPrivilegeModeM; @@ -143,13 +135,6 @@ module privileged ( csr csr(.*); - /////////////////////////////////////////// - // Check physical memory accesses - /////////////////////////////////////////// - - pmachecker pmachecker(.*); - pmpchecker pmpchecker(.*); - /////////////////////////////////////////// // Extract exceptions by name and handle them /////////////////////////////////////////// From 1ae529c4502eba08c9422660ff60a4bb3a6bca22 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 4 Jun 2021 17:05:07 -0400 Subject: [PATCH 2/3] 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 67569f2e2..deaef9a9b 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 a31448eac..2fd763c1c 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 2aa30fc59..8df871f38 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 fefce5ea7..58935eb98 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 1828c98e7..7a6740d1c 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 95e757a81..0ca8ba4c6 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 aa252e377..a567bf55a 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; From 3493027bf5b50e0d121a6fe7551f8391c734c9a6 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 4 Jun 2021 17:05:47 -0400 Subject: [PATCH 3/3] added shared constants file list of includes --- wally-pipelined/lint-wally | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wally-pipelined/lint-wally b/wally-pipelined/lint-wally index d741d3687..fbad26515 100755 --- a/wally-pipelined/lint-wally +++ b/wally-pipelined/lint-wally @@ -7,7 +7,7 @@ verilator=`which verilator` basepath=$(dirname $0) for config in rv64ic rv32ic; do echo "$config linting..." - if !($verilator --lint-only "$@" --top-module wallypipelinedsoc "-I$basepath/config/$config" $basepath/src/*/*.sv); then + if !($verilator --lint-only "$@" --top-module wallypipelinedsoc "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/*/*.sv --relative-includes); then echo "Exiting after $config lint due to errors or warnings" exit 1 fi