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 [7:0] PMPCfg,
input logic [`XLEN-1:0] PMPAdr, input logic [`XLEN-1:0] PMPAdr,
input logic PAgePMPAdrIn, input logic PAgePMPAdrIn,
// input logic NoLowerMatchIn,
input logic FirstMatch, input logic FirstMatch,
output logic PAgePMPAdrOut, output logic PAgePMPAdrOut,
// output logic NoLowerMatchOut,
output logic Match, Active, output logic Match, Active,
output logic L, X, W, R output logic L, X, W, R
); );
@ -48,7 +46,6 @@ module pmpadrdec (
logic TORMatch, NAMatch; logic TORMatch, NAMatch;
logic PAltPMPAdr; logic PAltPMPAdr;
// logic FirstMatch;
logic [`PA_BITS-1:0] CurrentAdrFull; logic [`PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode; logic [1:0] AdrMode;
@ -67,25 +64,15 @@ module pmpadrdec (
assign TORMatch = PAgePMPAdrIn && PAltPMPAdr; assign TORMatch = PAgePMPAdrIn && PAltPMPAdr;
// Naturally aligned regions // Naturally aligned regions
logic [`PA_BITS-1:0] NAMask; logic [`PA_BITS-1:0] NAMask, NABase;
//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
assign NAMask[1:0] = {2'b11}; assign NAMask[1:0] = {2'b11};
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.
prioritythemometer #(`PA_BITS-2) namaskgen( assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range
.a({PMPAdr[`PA_BITS-4:0], (AdrMode == NAPOT)}),
.y(NAMask[`PA_BITS-1:2]));
assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | NAMask);
assign Match = (AdrMode == TOR) ? TORMatch : assign Match = (AdrMode == TOR) ? TORMatch :
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : (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 // Bit i is high when the address falls in PMP region i
logic EnforcePMP; logic EnforcePMP;
logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; // logic [7:0] PMPCfg[`PMP_ENTRIES-1:0];
logic [`PMP_ENTRIES-1:0] Match, FirstMatch; // PMP Entry matches 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] 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] L, X, W, R; // PMP matches and has flag set
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
@ -69,7 +70,7 @@ module pmpchecker (
.PAgePMPAdrOut(PAgePMPAdr), .PAgePMPAdrOut(PAgePMPAdr),
.FirstMatch, .Match, .Active, .L, .X, .W, .R); .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 // 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; assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;