diff --git a/wally-pipelined/src/mmu/pmachecker.sv b/wally-pipelined/src/mmu/pmachecker.sv index 8d31f3ae..26d8ac87 100644 --- a/wally-pipelined/src/mmu/pmachecker.sv +++ b/wally-pipelined/src/mmu/pmachecker.sv @@ -32,9 +32,6 @@ 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 [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. @@ -46,7 +43,6 @@ module pmachecker ( output logic PMAStoreAccessFaultM ); - // logic BootTim, Tim, CLINT, GPIO, UART, PLIC; logic PMAAccessFault; logic AccessRW, AccessRWX, AccessRX; logic [5:0] SelRegions; diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index 3286368f..bdd46bef 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -31,7 +31,6 @@ module pmpadrdec ( 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, @@ -46,20 +45,19 @@ module pmpadrdec ( logic TORMatch, NAMatch; logic AdrBelowCurrentPMP; logic [`PA_BITS-1:0] CurrentAdrFull; -// 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}; + // The two lsb of the physical address don't matter for this checking. + // The following code includes them, but hardwires the PMP checker lsbs to 00 + // and masks them later. Logic synthesis should optimize away these bottom bits. // Top-of-range (TOR) // Append two implicit trailing 0's to PMPAdr value assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00}; - assign AdrBelowCurrentPMP = PhysicalAddress < CurrentAdrFull; // *** make sure unsigned comparison works correctly + assign AdrBelowCurrentPMP = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP; assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP; // Naturally aligned regions - // *** should be able to optimize away bottom 2 bits // verilator lint_off UNOPTFLAT logic [`PA_BITS-1:0] Mask; @@ -76,60 +74,6 @@ module pmpadrdec ( assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask); - /* generate - if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes - // priority encoder to translate address to range - // *** We'd like to replace this with a better priority encoder - // *** We should not be truncating 64 bit physical addresses to 32 bits... - // *** there is an easy combinatinoal way to do this with a cascade of AND gates O(32) rather than O(32^2) dh - always_comb - if (AdrMode == NA4) Range = (2**2) - 1; - else casez (CurrentPMPAdr[31:0]) // NAPOT regions - 32'b???????????????????????????????0: Range = (2**3) - 1; - 32'b??????????????????????????????01: Range = (2**4) - 1; - 32'b?????????????????????????????011: Range = (2**5) - 1; - 32'b????????????????????????????0111: Range = (2**6) - 1; - 32'b???????????????????????????01111: Range = (2**7) - 1; - 32'b??????????????????????????011111: Range = (2**8) - 1; - 32'b?????????????????????????0111111: Range = (2**9) - 1; - 32'b????????????????????????01111111: Range = (2**10) - 1; - 32'b???????????????????????011111111: Range = (2**11) - 1; - 32'b??????????????????????0111111111: Range = (2**12) - 1; - 32'b?????????????????????01111111111: Range = (2**13) - 1; - 32'b????????????????????011111111111: Range = (2**14) - 1; - 32'b???????????????????0111111111111: Range = (2**15) - 1; - 32'b??????????????????01111111111111: Range = (2**16) - 1; - 32'b?????????????????011111111111111: Range = (2**17) - 1; - 32'b????????????????0111111111111111: Range = (2**18) - 1; - 32'b???????????????01111111111111111: Range = (2**19) - 1; - 32'b??????????????011111111111111111: Range = (2**20) - 1; - 32'b?????????????0111111111111111111: Range = (2**21) - 1; - 32'b????????????01111111111111111111: Range = (2**22) - 1; - 32'b???????????011111111111111111111: Range = (2**23) - 1; - 32'b??????????0111111111111111111111: Range = (2**24) - 1; - 32'b?????????01111111111111111111111: Range = (2**25) - 1; - 32'b????????011111111111111111111111: Range = (2**26) - 1; - 32'b???????0111111111111111111111111: Range = (2**27) - 1; - 32'b??????01111111111111111111111111: Range = (2**28) - 1; - 32'b?????011111111111111111111111111: Range = (2**29) - 1; - 32'b????0111111111111111111111111111: Range = (2**30) - 1; - 32'b???01111111111111111111111111111: Range = (2**31) - 1; - 32'b??011111111111111111111111111111: Range = (2**32) - 1; - 32'b?0111111111111111111111111111111: Range = (2**33) - 1; - 32'b01111111111111111111111111111111: Range = (2**34) - 1; - 32'b11111111111111111111111111111111: Range = (2**35) - 1; - default: Range = '0; - endcase - end else begin - assign Range = '0; - end - endgenerate - - // *** Range should not be truncated... but our physical address space is - // currently only 32 bits wide. - // with a bit of combining of range selection, this could be shared with NA4Match *** - assign NAMatch = &((HADDR ~^ CurrentAdrFull) | Range[31:0]);*/ - assign Match = (AdrMode == TOR) ? TORMatch : (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : 0; diff --git a/wally-pipelined/src/mmu/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv index 409e2ccb..0d45229a 100644 --- a/wally-pipelined/src/mmu/pmpchecker.sv +++ b/wally-pipelined/src/mmu/pmpchecker.sv @@ -29,12 +29,8 @@ `include "wally-config.vh" module pmpchecker ( -// input logic clk, reset, //*** it seems like clk, reset is also not needed here? input logic [`PA_BITS-1:0] PhysicalAddress, -// input logic [31:0] HADDR, - - input logic [1:0] PrivilegeModeW, - + 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 @@ -43,10 +39,6 @@ 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. - // However, it's still bad form to pass 512 or 1024 signals across a module - // boundary. It would be better to store the PMP address registers in a module - // somewhere in the CSR hierarchy and do PMP checking _within_ that module, so - // we don't have to pass around 16 whole registers. input var logic [63:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0], input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], @@ -61,7 +53,6 @@ module pmpchecker ( // Bit i is high when the address falls in PMP region i logic [`PMP_ENTRIES-1:0] Regions, FirstMatch; - //logic [3:0] MatchedRegion; logic EnforcePMP; logic [7:0] PMPCFG [`PMP_ENTRIES-1:0]; @@ -74,7 +65,6 @@ module pmpchecker ( logic [`PMP_ENTRIES-1:0] ActiveRegion; logic [`PMP_ENTRIES-1:0] L_Bits, X_Bits, W_Bits, R_Bits; - //logic InvalidExecute, InvalidWrite, InvalidRead; genvar i,j; @@ -100,11 +90,8 @@ module pmpchecker ( end endgenerate - //assign Match = |Regions; - // verilator lint_off UNOPTFLAT logic [`PMP_ENTRIES-1:0] NoLowerMatch; -// assign NoLowerMatch[0] = 1; generate // verilator lint_off WIDTH for (j=0; j<`PMP_ENTRIES; j = j+8) begin @@ -127,36 +114,6 @@ module pmpchecker ( end // verilator lint_on UNOPTFLAT endgenerate -/* // *** extend to up to 64, fold bit extraction to avoid need for binary encoding of region - always_comb - casez (Regions) - 16'b???????????????1: MatchedRegion = 0; - 16'b??????????????10: MatchedRegion = 1; - 16'b?????????????100: MatchedRegion = 2; - 16'b????????????1000: MatchedRegion = 3; - 16'b???????????10000: MatchedRegion = 4; - 16'b??????????100000: MatchedRegion = 5; - 16'b?????????1000000: MatchedRegion = 6; - 16'b????????10000000: MatchedRegion = 7; - 16'b???????100000000: MatchedRegion = 8; - 16'b??????1000000000: MatchedRegion = 9; - 16'b?????10000000000: MatchedRegion = 10; - 16'b????100000000000: MatchedRegion = 11; - 16'b???1000000000000: MatchedRegion = 12; - 16'b??10000000000000: MatchedRegion = 13; - 16'b?100000000000000: MatchedRegion = 14; - 16'b1000000000000000: MatchedRegion = 15; - 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 InvalidExecute = ExecuteAccessF && ~X_Bit; - assign InvalidWrite = WriteAccessM && ~W_Bit; - assign InvalidRead = ReadAccessM && ~R_Bit;*/ // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L_Bits : |ActiveRegion;