mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-06-27 08:50:26 -04:00
Initial pmpadrdec grain implementation
This commit is contained in:
parent
90b4337a49
commit
18a7a231ce
2 changed files with 11 additions and 8 deletions
|
@ -48,10 +48,11 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
localparam TOR = 2'b01;
|
||||
localparam NA4 = 2'b10;
|
||||
localparam NAPOT = 2'b11;
|
||||
localparam Gm1 = P.PMP_G > 0 ? P.PMP_G - 1 : 0; // max(G-1, 0)
|
||||
|
||||
logic TORMatch, NAMatch;
|
||||
logic PAltPMPAdr;
|
||||
logic [P.PA_BITS-1:0] CurrentAdrFull;
|
||||
logic [P.PA_BITS-1:0] PMPAdrTORGrain, PMPAdrNAPOTGrain, CurrentAdrFull;
|
||||
logic [1:0] AdrMode;
|
||||
logic [P.PA_BITS-1:0] PMPTop1, PMPTopTOR, PMPTopNaturallyAligned;
|
||||
|
||||
|
@ -63,7 +64,8 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// Top-of-range (TOR)
|
||||
// Append two implicit trailing 0's to PMPAdr value
|
||||
assign CurrentAdrFull = {PMPAdr, 2'b00};
|
||||
assign PMPAdrTORGrain = (P.PMP_G > 0) ? {PMPAdr[P.PA_BITS-3:P.PMP_G], {P.PMP_G{1'b0}}} : PMPAdr; // In TOR, bottom G bits read as 0
|
||||
assign CurrentAdrFull = {PMPAdrTORGrain, 2'b00};
|
||||
assign PAltPMPAdr = {1'b0, PhysicalAddress} < {1'b0, CurrentAdrFull}; // unsigned comparison
|
||||
assign PAgePMPAdrOut = ~PAltPMPAdr;
|
||||
assign TORMatch = PAgePMPAdrIn & PAltPMPAdr; // exclusion-tag: PAgePMPAdrIn
|
||||
|
@ -71,11 +73,12 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
// Naturally aligned regions
|
||||
logic [P.PA_BITS-1:0] NAMask, NABase;
|
||||
|
||||
assign PMPAdrNAPOTGrain = {PMPAdr[P.PA_BITS-3:Gm1], {Gm1{1'b1}}}; // in NAPOT, if G >= 2, bottom G-1 bits read as all 1s
|
||||
assign NAMask[1:0] = {2'b11};
|
||||
assign NAMask[P.PA_BITS-1:2] = (PMPAdr + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdr;
|
||||
assign NAMask[P.PA_BITS-1:2] = (PMPAdrNAPOTGrain + {{(P.PA_BITS-3){1'b0}}, (AdrMode == NAPOT)}) ^ PMPAdrNAPOTGrain;
|
||||
// form 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 & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
||||
assign NABase = {(PMPAdrNAPOTGrain & ~NAMask[P.PA_BITS-1:2]), 2'b00}; // base physical address of the pmp region
|
||||
assign NAMatch = &((NABase ~^ PhysicalAddress) | NAMask); // check if upper bits of base address match, ignore lower bits correspoonding to inside the memory range
|
||||
|
||||
// finally pick the appropriate match for the access type
|
||||
|
@ -85,8 +88,8 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
|
|||
|
||||
// Report top of region for first matching region
|
||||
// PMP should match but fail if the size is too big (8-byte accesses spanning to TOR or NA4 region)
|
||||
assign PMPTopTOR = {PMPAdr-1, 2'b11}; // TOR goes to (pmpaddr << 2) - 1
|
||||
assign PMPTopNaturallyAligned = {PMPAdr,2'b00} | NAMask; // top of the pmp region for NA4 and NAPOT. All 1s in the lower bits. Used to check the address doesn't pass the top
|
||||
assign PMPTopTOR = {PMPAdrTORGrain-1, 2'b11}; // TOR goes to (pmpaddr << 2) - 1
|
||||
assign PMPTopNaturallyAligned = {PMPAdrNAPOTGrain, 2'b00} | NAMask; // top of the pmp region for NA4 and NAPOT. All 1s in the lower bits. Used to check the address doesn't pass the top
|
||||
assign PMPTop1 = (AdrMode == TOR) ? PMPTopTOR : PMPTopNaturallyAligned;
|
||||
assign PMPTop = FirstMatch ? PMPTop1 : '0; // AND portion of distributed AND-OR mux (OR portion in pmpchhecker)
|
||||
|
||||
|
|
|
@ -232,8 +232,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
|
|||
pmpaddr = {{(P.XLEN-(P.PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]}; // raw value in PMP registers
|
||||
if (P.PMP_G > 0) begin // bottom bits read as 0/1 depending on mode
|
||||
napot = PMPCFG_ARRAY_REGW[CSRAdrM - PMPADDR0][4]; // read from corresponding pmpcfg register, indicating NAPOT mode
|
||||
if ((P.PMP_G > 1) & napot) pmpaddr = {pmpaddr[P.XLEN-1:Gm1], {Gm1 {1'b1}}}; // in NAPOT, bottom G-1 bits read as all 1s
|
||||
else if (!napot) pmpaddr = {pmpaddr[P.XLEN-1:P.PMP_G], {P.PMP_G{1'b0}}}; // in TOR/OFF, bottom G bits read as 0s
|
||||
if (napot) pmpaddr = {pmpaddr[P.XLEN-1:Gm1], {Gm1 {1'b1}}}; // in NAPOT, bottom G-1 bits read as all 1s
|
||||
else pmpaddr = {pmpaddr[P.XLEN-1:P.PMP_G], {P.PMP_G{1'b0}}}; // in TOR/OFF, bottom G bits read as 0s
|
||||
end
|
||||
CSRMReadValM = pmpaddr;
|
||||
end else if ($unsigned(CSRAdrM) >= PMPCFG0 & $unsigned(CSRAdrM) < PMPCFG0 + P.PMP_ENTRIES/4 & (P.XLEN==32 | CSRAdrM[0] == 0)) begin
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue