diff --git a/wally-pipelined/src/ebu/pmachecker.sv b/wally-pipelined/src/ebu/pmachecker.sv new file mode 100644 index 00000000..bb2a124c --- /dev/null +++ b/wally-pipelined/src/ebu/pmachecker.sv @@ -0,0 +1,85 @@ +/////////////////////////////////////////// +// pmachecker.sv +// +// Written: tfleming@hmc.edu & jtorrey@hmc.edu 20 April 2021 +// Modified: +// +// Purpose: Examines all physical memory accesses and identifies attributes of +// the memory region accessed. +// Can report illegal accesses to the trap unit and cause a fault. +// +// 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" + +module pmachecker ( + input logic [31:0] HADDR, + input logic HSIZE, + input logic HWRITE, + input logic HBURST, + + input logic Atomic, Execute, Write, Read, + + output logic Cacheable, Idempotent, AtomicAllowed, + output logic SquashAHBAccess, + + output logic [5:0] HSELRegions, + + output logic InstrAccessFaultF, + output logic LoadAccessFaultM, + output logic StoreAccessFaultM +); + + // Signals are high if the memory access is within the given region + logic HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC; + + logic PreHSELUART; + + logic Empty; + + // Determine which region of physical memory (if any) is being accessed + adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim); + adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim); + adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT); + adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO); + adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART); + adrdec plicdec(HADDR, `PLICBASE, `PLICRANGE, HSELPLIC); + + assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported + + // Swizzle region bits + assign HSELRegions = {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC}; + + // Only RAM memory regions are cacheable + assign Cacheable = HSELBootTim | HSELTim; + + // *** Temporarily assume only RAM regions are idempotent -- likely wrong + assign Idempotent = HSELBootTim | HSELTim; + + // *** Temporarily assume only RAM regions allow full atomic operations -- likely wrong + assign AtomicAllowed = HSELBootTim | HSELTim; + + assign Empty = ~|HSELRegions; + + assign InstrAccessFaultF = Empty && Execute; + assign LoadAccessFaultM = Empty && Read; + assign StoreAccessFaultM = Empty && Write; + + assign SquashAHBAccess = InstrAccessFaultF || LoadAccessFaultM || StoreAccessFaultM; + +endmodule \ No newline at end of file diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 94767592..f4b9e74c 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -42,9 +42,9 @@ module privileged ( input logic PrivilegedM, input logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM, input logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM, - input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD, - input logic LoadMisalignedFaultM, LoadAccessFaultM, - input logic StoreMisalignedFaultM, StoreAccessFaultM, + input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, + input logic LoadMisalignedFaultM, + input logic StoreMisalignedFaultM, input logic TimerIntM, ExtIntM, SwIntM, input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [4:0] SetFflagsM, @@ -52,7 +52,15 @@ module privileged ( output logic [`XLEN-1:0] SATP_REGW, output logic STATUS_MXR, STATUS_SUM, output logic [2:0] FRM_REGW, - input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM + input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM, + + // PMA checker signals + input logic [31:0] HADDR, + input logic HSIZE, HWRITE, HBURST, + input logic Atomic, Execute, Write, Read, + output logic Cacheable, Idempotent, AtomicAllowed, + output logic SquashAHBAccess, + output logic [5:0] HSELRegions ); logic [1:0] NextPrivilegeModeM; @@ -67,7 +75,8 @@ module privileged ( logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM; logic LoadPageFaultM, StorePageFaultM; logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM; - logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM; + logic InstrAccessFaultF, InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM; + logic LoadAccessFaultM, StoreAccessFaultM; logic IllegalInstrFaultM; logic BreakpointFaultM, EcallFaultM; @@ -118,6 +127,12 @@ module privileged ( csr csr(.*); + /////////////////////////////////////////// + // Check physical memory accesses + /////////////////////////////////////////// + + pmachecker pmachecker(.*); + /////////////////////////////////////////// // Extract exceptions by name and handle them /////////////////////////////////////////// diff --git a/wally-pipelined/src/uncore/uncore.sv b/wally-pipelined/src/uncore/uncore.sv index 014ac556..0eae1e61 100644 --- a/wally-pipelined/src/uncore/uncore.sv +++ b/wally-pipelined/src/uncore/uncore.sv @@ -47,8 +47,11 @@ module uncore ( input logic [2:0] HADDRD, input logic [3:0] HSIZED, input logic HWRITED, + // PMA checker signals + input logic [5:0] HSELRegions, // bus interface - output logic DataAccessFaultM, + // PMA checker now handles access faults. *** This can be deleted + // output logic DataAccessFaultM, // peripheral pins output logic TimerIntM, SwIntM, ExtIntM, input logic [31:0] GPIOPinsIn, @@ -68,8 +71,11 @@ module uncore ( logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim; logic [1:0] MemRWboottim; logic UARTIntr,GPIOIntr; - + // unswizzle HSEL signals + assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC} = HSELRegions; + + /* PMA checker now handles decoding addresses. *** This can be deleted. // AHB Address decoder adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim); adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim); @@ -78,6 +84,7 @@ module uncore ( adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO); adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART); assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported + */ // subword accesses: converts HWDATAIN to HWDATA subwordwrite sww(.*); @@ -115,9 +122,10 @@ module uncore ( HSELBootTimD & HREADYBootTim | HSELUARTD & HREADYUART; + /* PMA checker now handles access faults. *** This can be deleted // Faults assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD | HSELPLICD | HSELGPIOD | HSELBootTimD | HSELUARTD); - + */ // Address Decoder Delay (figure 4-2 in spec) flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD); diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index a3487cba..46803ff0 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -48,6 +48,7 @@ module wallypipelinedhart ( output logic [3:0] HPROT, output logic [1:0] HTRANS, output logic HMASTLOCK, + output logic [5:0] HSELRegions, // Delayed signals for subword write output logic [2:0] HADDRD, output logic [3:0] HSIZED, @@ -110,6 +111,11 @@ module wallypipelinedhart ( logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM; logic [1:0] PageTypeF, PageTypeM; + // PMA checker signals + logic Atomic, Execute, Write, Read; + logic Cacheable, Idempotent, AtomicAllowed; + logic SquashAHBAccess; + // IMem stalls logic ICacheStallF; logic [`XLEN-1:0] MMUPAdr, MMUReadPTE; diff --git a/wally-pipelined/src/wally/wallypipelinedsoc.sv b/wally-pipelined/src/wally/wallypipelinedsoc.sv index 9111b59a..7974b7ac 100644 --- a/wally-pipelined/src/wally/wallypipelinedsoc.sv +++ b/wally-pipelined/src/wally/wallypipelinedsoc.sv @@ -60,6 +60,7 @@ module wallypipelinedsoc ( // Uncore signals logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore logic HREADY, HRESP; + logic [5:0] HSELRegions; logic InstrAccessFaultF, DataAccessFaultM; logic TimerIntM, SwIntM; // from CLINT logic ExtIntM; // from PLIC @@ -72,8 +73,6 @@ module wallypipelinedsoc ( // instantiate processor and memories wallypipelinedhart hart(.*); - // *** Temporary driving of access fault to low until PMA checker is complete - assign InstrAccessFaultF = '0; // instructions now come from uncore memory. This line can be removed at any time. // imem imem(.AdrF(PCF[`XLEN-1:1]), .*); // temporary until uncore memory is finished*** uncore uncore(.HWDATAIN(HWDATA), .*);