From 70c8828ac272a3d9a59dee6fb2a2d300b62ae2e3 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 24 May 2023 17:20:55 -0500 Subject: [PATCH] PM(P/A) checkers parameterized based on Lim's work. --- src/mmu/mmu.sv | 4 ++-- src/mmu/pmachecker.sv | 6 ++---- src/mmu/pmpadrdec.sv | 16 +++++++--------- src/mmu/pmpchecker.sv | 28 +++++++++++++--------------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index 517b16860..636680f3c 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -102,13 +102,13 @@ module mmu import cvw::*; #(parameter cvw_t P, // Check physical memory accesses /////////////////////////////////////////// - pmachecker pmachecker(.PhysicalAddress, .Size, + pmachecker #(P.PA_BITS) pmachecker(.PhysicalAddress, .Size, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .Cacheable, .Idempotent, .SelTIM, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); if (P.PMP_ENTRIES > 0) begin : pmp - pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, + pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index ace481f74..bba1f7b6f 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -28,10 +28,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module pmachecker ( - input logic [`PA_BITS-1:0] PhysicalAddress, +module pmachecker #(parameter PA_BITS) ( + input logic [PA_BITS-1:0] PhysicalAddress, input logic [1:0] Size, input logic AtomicAccessM, // Atomic access input logic ExecuteAccessF, // Execute access diff --git a/src/mmu/pmpadrdec.sv b/src/mmu/pmpadrdec.sv index a4fb8068b..4c8e1d002 100644 --- a/src/mmu/pmpadrdec.sv +++ b/src/mmu/pmpadrdec.sv @@ -30,12 +30,10 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module pmpadrdec ( - input logic [`PA_BITS-1:0] PhysicalAddress, +module pmpadrdec import cvw::*; #(parameter cvw_t P) ( + input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [7:0] PMPCfg, - input logic [`PA_BITS-3:0] PMPAdr, + input logic [P.PA_BITS-3:0] PMPAdr, input logic PAgePMPAdrIn, output logic PAgePMPAdrOut, output logic Match, @@ -49,7 +47,7 @@ module pmpadrdec ( logic TORMatch, NAMatch; logic PAltPMPAdr; - logic [`PA_BITS-1:0] CurrentAdrFull; + logic [P.PA_BITS-1:0] CurrentAdrFull; logic [1:0] AdrMode; assign AdrMode = PMPCfg[4:3]; @@ -66,13 +64,13 @@ module pmpadrdec ( assign TORMatch = PAgePMPAdrIn & PAltPMPAdr; // exclusion-tag: PAgePMPAdrIn // Naturally aligned regions - logic [`PA_BITS-1:0] NAMask, NABase; + logic [P.PA_BITS-1:0] NAMask, NABase; assign NAMask[1:0] = {2'b11}; - assign NAMask[`PA_BITS-1:2] = (PMPAdr + {{(`PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr; + assign NAMask[P.PA_BITS-1:2] = (PMPAdr + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr; // form a mask where the bottom k bits are 1, corresponding to a size of 2^k bytes for this memory region. // This assumes we're using at least an NA4 region, but works for any size NAPOT region. - assign NABase = {(PMPAdr & ~NAMask[`PA_BITS-1:2]), 2'b00}; // base physical address of the pmp. + assign NABase = {(PMPAdr & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp. assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range diff --git a/src/mmu/pmpchecker.sv b/src/mmu/pmpchecker.sv index e7c660ca0..0b4cec4a1 100644 --- a/src/mmu/pmpchecker.sv +++ b/src/mmu/pmpchecker.sv @@ -29,10 +29,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module pmpchecker ( - input logic [`PA_BITS-1:0] PhysicalAddress, +module pmpchecker import cvw::*; #(parameter cvw_t P) ( + input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [1:0] PrivilegeModeW, // ModelSim has a switch -svinputport which controls whether input ports // are nets (wires) or vars by default. The default setting of this switch is @@ -41,8 +39,8 @@ module pmpchecker ( // this will be understood as a var. However, if we don't supply the `var` // keyword, the compiler warns us that it's interpreting the signal as a var, // which we might not intend. - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], - input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], + input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], input logic ExecuteAccessF, WriteAccessM, ReadAccessM, output logic PMPInstrAccessFaultF, output logic PMPLoadAccessFaultM, @@ -51,25 +49,25 @@ module pmpchecker ( // Bit i is high when the address falls in PMP region i logic EnforcePMP; // should PMP be checked in this privilege level - logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges - logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. - logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set - logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] + logic [P.PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges + logic [P.PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. + logic [P.PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set + logic [P.PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] - if (`PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0 - pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( + if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0 + pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0]( .PhysicalAddress, .PMPCfg(PMPCFG_ARRAY_REGW), .PMPAdr(PMPADDR_ARRAY_REGW), - .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), + .PAgePMPAdrIn({PAgePMPAdr[P.PMP_ENTRIES-2:0], 1'b1}), .PAgePMPAdrOut(PAgePMPAdr), .Match, .L, .X, .W, .R); end - priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. + priorityonehot #(P.PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. // Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region - assign EnforcePMP = (PrivilegeModeW != `M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode + assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;