diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index 61816782..4f747ffb 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -34,10 +34,8 @@ module pmpadrdec ( input logic [7:0] PMPCfg, input logic [`XLEN-1:0] PMPAdr, input logic PAgePMPAdrIn, -// input logic NoLowerMatchIn, input logic FirstMatch, output logic PAgePMPAdrOut, -// output logic NoLowerMatchOut, output logic Match, Active, output logic L, X, W, R ); @@ -48,7 +46,6 @@ module pmpadrdec ( logic TORMatch, NAMatch; logic PAltPMPAdr; -// logic FirstMatch; logic [`PA_BITS-1:0] CurrentAdrFull; logic [1:0] AdrMode; @@ -67,25 +64,15 @@ module pmpadrdec ( assign TORMatch = PAgePMPAdrIn && PAltPMPAdr; // Naturally aligned regions - logic [`PA_BITS-1:0] NAMask; - //genvar i; - - // create a mask of which bits to ignore - // generate - // assign Mask[1:0] = 2'b11; - // assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region - // for (i=3; i < `PA_BITS; i=i+1) begin:mask - // assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore - // end - // endgenerate + logic [`PA_BITS-1:0] NAMask, NABase; assign NAMask[1:0] = {2'b11}; - - prioritythemometer #(`PA_BITS-2) namaskgen( - .a({PMPAdr[`PA_BITS-4:0], (AdrMode == NAPOT)}), - .y(NAMask[`PA_BITS-1:2])); - - assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | NAMask); + assign NAMask[`PA_BITS-1:2] = (PMPAdr[`PA_BITS-3:0] + {{(`PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr[`PA_BITS-3:0]; + // generates 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[`PA_BITS-3:0] & ~NAMask[`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 assign Match = (AdrMode == TOR) ? TORMatch : (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : diff --git a/wally-pipelined/src/mmu/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv index 7dc37163..11cb7ccb 100644 --- a/wally-pipelined/src/mmu/pmpchecker.sv +++ b/wally-pipelined/src/mmu/pmpchecker.sv @@ -54,8 +54,9 @@ module pmpchecker ( // Bit i is high when the address falls in PMP region i logic EnforcePMP; - logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; - logic [`PMP_ENTRIES-1:0] Match, FirstMatch; // PMP Entry matches +// logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; + 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] Active; // PMP register i is non-null 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] @@ -69,7 +70,7 @@ module pmpchecker ( .PAgePMPAdrOut(PAgePMPAdr), .FirstMatch, .Match, .Active, .L, .X, .W, .R); - priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // Take the ripple gates/signals out of the pmpadrdec and into another unit. + priorityonehot #(`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 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 : |Active;