removed loops and simplified mask generation logic. PMP's now pass my tests and linux tests up to around 300M instructions.

This commit is contained in:
Kip Macsai-Goren 2021-10-08 15:33:18 -07:00
parent d1c2191b1e
commit f3058f94c6
2 changed files with 11 additions and 23 deletions

View File

@ -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 :

View File

@ -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;