From ac597d78c8d579a1efca814d23e680945eba4870 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Thu, 24 Jun 2021 19:59:29 -0400 Subject: [PATCH] Removed AHB address, etc signals from physical memory checkers, replaced with physical address from cpu or ptw. Passes lint but not simulations. --- wally-pipelined/src/ifu/ifu.sv | 30 +++++++++++--------- wally-pipelined/src/lsu/lsu.sv | 18 ++++++------ wally-pipelined/src/mmu/adrdec.sv | 20 ++++++------- wally-pipelined/src/mmu/adrdecs.sv | 21 +++++++------- wally-pipelined/src/mmu/mmu.sv | 12 ++++---- wally-pipelined/src/mmu/pmachecker.sv | 31 ++++++++++---------- wally-pipelined/src/mmu/pmpadrdec.sv | 11 +++---- wally-pipelined/src/mmu/pmpchecker.sv | 41 ++++++++++++++------------- 8 files changed, 96 insertions(+), 88 deletions(-) diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 2fa5cbfd..6cf6220f 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -75,15 +75,15 @@ module ifu ( output logic ITLBMissF, ITLBHitF, // 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, - input logic HWRITE, +// input logic [31:0] HADDR, +// input logic [2:0] HSIZE, +// input logic HWRITE, input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so they're gonna have to come over into ifu and dmem input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF, - output logic ISquashBusAccessF, - output logic [5:0] IHSELRegionsF + output logic ISquashBusAccessF +// output logic [5:0] IHSELRegionsF ); @@ -104,13 +104,17 @@ module ifu ( 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. - logic [`PA_BITS-1:0] PCPFmmu; + logic [`PA_BITS-1:0] PCPFmmu, PCNextFPhys; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width. +; generate - if (`XLEN==32) + if (`XLEN==32) begin assign PCPF = PCPFmmu[31:0]; - else + assign PCNextFPhys = {{(`PA_BITS-`XLEN){1'b0}}, PCNextF}; + end else begin assign PCPF = {8'b0, PCPFmmu}; + assign PCNextFPhys = PCNextF[`PA_BITS-1:0]; + end endgenerate mmu #(.ENTRY_BITS(`ITLB_ENTRY_BITS), .IMMU(1)) @@ -125,12 +129,12 @@ module ifu ( .TLBMiss(ITLBMissF), .TLBHit(ITLBHitF), .TLBPageFault(ITLBInstrPageFaultF), - .ExecuteAccessF(1'b1), + .InstrReadF(InstrReadF), .AtomicAccessM(1'b0), - .WriteAccessM(1'b0), - .ReadAccessM(1'b0), + .MemReadM(1'b0), + .MemWriteM(1'b0), .SquashBusAccess(ISquashBusAccessF), - .HSELRegions(IHSELRegionsF), +// .HSELRegions(IHSELRegionsF), .DisableTranslation(1'b0), .*); @@ -147,7 +151,7 @@ module ifu ( // assign InstrReadF = 1; // *** & ICacheMissF; add later icache icache(.*, - .PCNextF(PCNextF[`PA_BITS-1:0]), + .PCNextF(PCNextFPhys), .PCPF(PCPFmmu)); flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD); diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index c537393b..096dd07c 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -92,8 +92,8 @@ module lsu ( 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 DSquashBusAccessM, - output logic [5:0] DHSELRegionsM + output logic DSquashBusAccessM +// output logic [5:0] DHSELRegionsM ); @@ -127,12 +127,12 @@ module lsu ( .TLBMiss(DTLBMissM), .TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM), - .ExecuteAccessF(1'b0), - .AtomicAccessM(|AtomicM), - .WriteAccessM(MemRWM[0]), - .ReadAccessM(MemRWM[1]), + .InstrReadF(1'b0), + .AtomicAccessM(AtomicMaskedM[1]), + .MemWriteM(MemRWM[0]), + .MemReadM(MemRWM[1]), .SquashBusAccess(DSquashBusAccessM), - .HSELRegions(DHSELRegionsM), +// .SelRegions(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 @@ -214,13 +214,13 @@ module lsu ( else NextState = STATE_READY; STATE_FETCH_AMO: if (MemAckW) NextState = STATE_FETCH; else NextState = STATE_FETCH_AMO; - STATE_FETCH: if (MemAckW & ~StallW) NextState = STATE_READY; + STATE_FETCH: if (MemAckW & ~StallW) NextState = STATE_READY; // StallW will stay high if datastall stays high, so right now, once we get into STATE_FETCH, datastall goes high, and we never leave else if (MemAckW & StallW) NextState = STATE_STALLED; else NextState = STATE_FETCH; STATE_STALLED: if (~StallW) NextState = STATE_READY; else NextState = STATE_STALLED; default: NextState = STATE_READY; - endcase // case (CurrState) + endcase end endmodule diff --git a/wally-pipelined/src/mmu/adrdec.sv b/wally-pipelined/src/mmu/adrdec.sv index e2c63731..5995d8e3 100644 --- a/wally-pipelined/src/mmu/adrdec.sv +++ b/wally-pipelined/src/mmu/adrdec.sv @@ -26,13 +26,13 @@ `include "wally-config.vh" module adrdec ( - input logic [31:0] HADDR, - input logic [31:0] Base, Range, - input logic Supported, - input logic AccessValid, - input logic [2:0] Size, - input logic [3:0] SizeMask, - output logic HSEL + input logic [`PA_BITS-1:0] PhysicalAddress, + input logic [`PA_BITS-1:0] Base, Range, + input logic Supported, + input logic AccessValid, + input logic [1:0] Size, + input logic [3:0] SizeMask, + output logic Sel ); logic Match; @@ -41,12 +41,12 @@ module adrdec ( // determine if an address is in a range starting at the base // for example, if Base = 0x04002000 and range = 0x00000FFF, // then anything address between 0x04002000 and 0x04002FFF should match (HSEL=1) - assign Match = &((HADDR ~^ Base) | Range); + assign Match = &((PhysicalAddress ~^ Base) | Range); // determine if legal size of access is being made (byte, halfword, word, doubleword) - assign SizeValid = SizeMask[Size[1:0]]; + assign SizeValid = SizeMask[Size]; - assign HSEL = Match && Supported && AccessValid && SizeValid; + assign Sel = Match && Supported && AccessValid && SizeValid; endmodule diff --git a/wally-pipelined/src/mmu/adrdecs.sv b/wally-pipelined/src/mmu/adrdecs.sv index 17f78d51..8585a4ee 100644 --- a/wally-pipelined/src/mmu/adrdecs.sv +++ b/wally-pipelined/src/mmu/adrdecs.sv @@ -26,19 +26,20 @@ `include "wally-config.vh" module adrdecs ( - input logic [31:0] HADDR, // *** will need to use PAdr in mmu, stick with HADDR in uncore - input logic AccessRW, AccessRX, AccessRWX, - input logic [2:0] HSIZE, - output logic [5:0] HSELRegions + input logic [`PA_BITS-1:0] PhysicalAddress, + input logic AccessRW, AccessRX, AccessRWX, + input logic [1:0] Size, + output logic [5:0] SelRegions ); // Determine which region of physical memory (if any) is being accessed // *** eventually uncomment Access signals - adrdec boottimdec(HADDR, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, HSIZE, 4'b1111, HSELRegions[5]); - adrdec timdec(HADDR, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, HSIZE, 4'b1111, HSELRegions[4]); - adrdec clintdec(HADDR, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, HSIZE, 4'b1111, HSELRegions[3]); - adrdec gpiodec(HADDR, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[2]); - adrdec uartdec(HADDR, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, HSIZE, 4'b0001, HSELRegions[1]); - adrdec plicdec(HADDR, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[0]); + adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, Size, 4'b1111, SelRegions[5]); + adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, Size, 4'b1111, SelRegions[4]); + adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[3]); + adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]); + adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[1]); + adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[0]); + endmodule diff --git a/wally-pipelined/src/mmu/mmu.sv b/wally-pipelined/src/mmu/mmu.sv index 60f46b04..b6224cc4 100644 --- a/wally-pipelined/src/mmu/mmu.sv +++ b/wally-pipelined/src/mmu/mmu.sv @@ -67,17 +67,17 @@ module mmu #(parameter ENTRY_BITS = 3, output logic TLBPageFault, // PMA checker signals - input logic [31:0] HADDR, - input logic [2:0] HSIZE, - input logic HWRITE, - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, +// input logic [31:0] HADDR, +// input logic [2:0] HSIZE, +// input logic HWRITE, + input logic AtomicAccessM, InstrReadF, MemWriteM, MemReadM, 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 var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], output logic SquashBusAccess, // *** send to privileged unit output logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM, - output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM, - output logic [5:0] HSELRegions + output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM +// output logic [5:0] SelRegions ); diff --git a/wally-pipelined/src/mmu/pmachecker.sv b/wally-pipelined/src/mmu/pmachecker.sv index 1d8cc3ee..da8efe97 100644 --- a/wally-pipelined/src/mmu/pmachecker.sv +++ b/wally-pipelined/src/mmu/pmachecker.sv @@ -32,17 +32,15 @@ module pmachecker ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic [1:0] Size, - input logic [31:0] HADDR, - input logic [2:0] HSIZE, +// input logic [31:0] HADDR, +// input logic [2:0] HSIZE, // input logic [2:0] HBURST, // *** in AHBlite, HBURST is hardwired to zero for single bursts only allowed. consider removing from this module if unused. - input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use. + input logic AtomicAccessM, InstrReadF, MemWriteM, MemReadM, // *** atomicaccessM is unused but might want to stay in for future use. output logic Cacheable, Idempotent, AtomicAllowed, output logic PMASquashBusAccess, - output logic [5:0] HSELRegions, - output logic PMAInstrAccessFaultF, output logic PMALoadAccessFaultM, output logic PMAStoreAccessFaultM @@ -51,24 +49,25 @@ module pmachecker ( // logic BootTim, Tim, CLINT, GPIO, UART, PLIC; logic PMAAccessFault; logic AccessRW, AccessRWX, AccessRX; + logic [5:0] SelRegions; // Determine what type of access is being made - assign AccessRW = ReadAccessM | WriteAccessM; - assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF; - assign AccessRX = ReadAccessM | ExecuteAccessF; + assign AccessRW = MemReadM | MemWriteM; + assign AccessRWX = MemReadM | MemWriteM | InstrReadF; + assign AccessRX = MemReadM | InstrReadF; // Determine which region of physical memory (if any) is being accessed - adrdecs adrdecs(HADDR, AccessRW, AccessRX, AccessRWX, HSIZE, HSELRegions); + adrdecs adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions); // Only RAM memory regions are cacheable - assign Cacheable = HSELRegions[5] | HSELRegions[4]; - assign Idempotent = HSELRegions[4]; - assign AtomicAllowed = HSELRegions[4]; + assign Cacheable = SelRegions[5] | SelRegions[4]; + assign Idempotent = SelRegions[4]; + assign AtomicAllowed = SelRegions[4]; // Detect access faults - assign PMAAccessFault = (~|HSELRegions) && AccessRWX; - assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault; - assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault; - assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault; + assign PMAAccessFault = (~|SelRegions) & AccessRWX; + assign PMAInstrAccessFaultF = InstrReadF & PMAAccessFault; + assign PMALoadAccessFaultM = MemReadM & PMAAccessFault; + assign PMAStoreAccessFaultM = MemWriteM & PMAAccessFault; assign PMASquashBusAccess = PMAAccessFault; endmodule diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index 87f5d8f1..3286368f 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -30,7 +30,8 @@ `include "wally-config.vh" module pmpadrdec ( - input logic [31:0] HADDR, // *** replace with PAdr + input logic [`PA_BITS-1:0] PhysicalAddress, +// input logic [31:0] HADDR, // *** replace with PAdr input logic [1:0] AdrMode, input logic [`XLEN-1:0] CurrentPMPAdr, input logic AdrAtLeastPreviousPMP, @@ -45,15 +46,15 @@ module pmpadrdec ( logic TORMatch, NAMatch; logic AdrBelowCurrentPMP; logic [`PA_BITS-1:0] CurrentAdrFull; - logic [`PA_BITS-1:0] FakePhysAdr; +// logic [`PA_BITS-1:0] FakePhysAdr; // ***replace this when the true physical address from MMU is available - assign FakePhysAdr = {{(`PA_BITS-32){1'b0}}, HADDR}; +// assign FakePhysAdr = {{(`PA_BITS-32){1'b0}}, HADDR}; // Top-of-range (TOR) // Append two implicit trailing 0's to PMPAdr value assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00}; - assign AdrBelowCurrentPMP = /*HADDR */FakePhysAdr < CurrentAdrFull; // *** make sure unsigned comparison works correctly + assign AdrBelowCurrentPMP = PhysicalAddress < CurrentAdrFull; // *** make sure unsigned comparison works correctly assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP; assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP; @@ -73,7 +74,7 @@ module pmpadrdec ( endgenerate // verilator lint_on UNOPTFLAT - assign NAMatch = &((FakePhysAdr ~^ CurrentAdrFull) | Mask); + assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask); /* generate if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes diff --git a/wally-pipelined/src/mmu/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv index f88d56fa..08153a99 100644 --- a/wally-pipelined/src/mmu/pmpchecker.sv +++ b/wally-pipelined/src/mmu/pmpchecker.sv @@ -30,8 +30,8 @@ module pmpchecker ( // input logic clk, reset, //*** it seems like clk, reset is also not needed here? - - input logic [31:0] HADDR, + input logic [`PA_BITS-1:0] PhysicalAddress, +// input logic [31:0] HADDR, input logic [1:0] PrivilegeModeW, @@ -50,7 +50,7 @@ module pmpchecker ( // we don't have to pass around 16 whole registers. input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], - input logic ExecuteAccessF, WriteAccessM, ReadAccessM, + input logic InstrReadF, MemWriteM, MemReadM, output logic PMPSquashBusAccess, @@ -84,17 +84,20 @@ module pmpchecker ( assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4], PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW; - pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[0][4:3]), + pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress), + .AdrMode(PMPCFG[0][4:3]), .CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]), .AdrAtLeastPreviousPMP(1'b1), .AdrAtLeastCurrentPMP(AboveRegion[0]), .Match(Regions[0])); + assign ActiveRegion[0] = |PMPCFG[0][4:3]; generate // *** only for PMP_ENTRIES > 0 genvar i; for (i = 1; i < `PMP_ENTRIES; i++) begin - pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[i][4:3]), + pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress), + .AdrMode(PMPCFG[i][4:3]), .CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]), .AdrAtLeastPreviousPMP(AboveRegion[i-1]), .AdrAtLeastCurrentPMP(AboveRegion[i]), @@ -131,26 +134,26 @@ module pmpchecker ( default: MatchedRegion = 0; // Should only occur if there is no match endcase - assign L_Bit = PMPCFG[MatchedRegion][7] && Match; - assign X_Bit = PMPCFG[MatchedRegion][2] && Match; - assign W_Bit = PMPCFG[MatchedRegion][1] && Match; - assign R_Bit = PMPCFG[MatchedRegion][0] && Match; + assign L_Bit = PMPCFG[MatchedRegion][7] & Match; + assign X_Bit = PMPCFG[MatchedRegion][2] & Match; + assign W_Bit = PMPCFG[MatchedRegion][1] & Match; + assign R_Bit = PMPCFG[MatchedRegion][0] & Match; - assign InvalidExecute = ExecuteAccessF && ~X_Bit; - assign InvalidWrite = WriteAccessM && ~W_Bit; - assign InvalidRead = ReadAccessM && ~R_Bit; + assign InvalidExecute = InstrReadF & ~X_Bit; + assign InvalidWrite = MemWriteM & ~W_Bit; + assign InvalidRead = MemReadM & ~R_Bit; // *** don't cause faults when there are no PMPs assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ? - Match && L_Bit && InvalidExecute : - EnforcePMP && InvalidExecute; + Match & L_Bit & InvalidExecute : + EnforcePMP & InvalidExecute; assign PMPStoreAccessFaultM = (PrivilegeModeW == `M_MODE) ? - Match && L_Bit && InvalidWrite : - EnforcePMP && InvalidWrite; + Match & L_Bit & InvalidWrite : + EnforcePMP & InvalidWrite; assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ? - Match && L_Bit && InvalidRead : - EnforcePMP && InvalidRead; + Match & L_Bit & InvalidRead : + EnforcePMP & InvalidRead; - assign PMPSquashBusAccess = PMPInstrAccessFaultF || PMPLoadAccessFaultM || PMPStoreAccessFaultM; + assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM; endmodule