Fixed size bug and cleaned up PMP csr logic

This commit is contained in:
David Harris 2024-12-30 22:22:29 -08:00
parent 55b63ff486
commit c40450cc3a
2 changed files with 4 additions and 6 deletions

View File

@ -85,8 +85,6 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
or_rows #(P.PMP_ENTRIES, P.PA_BITS) PTEOr(PMPTop, MatchingPMPTop); or_rows #(P.PMP_ENTRIES, P.PA_BITS) PTEOr(PMPTop, MatchingPMPTop);
// Matching PMP entry must match all bytes of an access, or the access fails (Priv Spec 3.7.1.3) // Matching PMP entry must match all bytes of an access, or the access fails (Priv Spec 3.7.1.3)
// *** not fully implemented
// *** check R=0,W=1 WARL is enforced
// First find the size of the access in terms of the offset to the most significant byte // First find the size of the access in terms of the offset to the most significant byte
always_comb always_comb
case (Size) case (Size)
@ -95,6 +93,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
2'b10: SizeBytesMinus1 = 3'd3; 2'b10: SizeBytesMinus1 = 3'd3;
2'b11: SizeBytesMinus1 = 3'd7; 2'b11: SizeBytesMinus1 = 3'd7;
endcase endcase
// Then find the top of the access and see if it is beyond the top of the region
assign PhysicalAddressTop = PhysicalAddress + {{P.PA_BITS-3{1'b0}}, SizeBytesMinus1}; // top of the access range assign PhysicalAddressTop = PhysicalAddress + {{P.PA_BITS-3{1'b0}}, SizeBytesMinus1}; // top of the access range
assign TooBig = PhysicalAddressTop > MatchingPMPTop; // check if the access goes beyond the top of the PMP region assign TooBig = PhysicalAddressTop > MatchingPMPTop; // check if the access goes beyond the top of the PMP region
@ -104,7 +103,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~MatchingR ; // checking R is sufficient because W implies R in PMP // exclusion-tag: immu-pmpcbom assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~MatchingR ; // checking R is sufficient because W implies R in PMP // exclusion-tag: immu-pmpcbom
assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~MatchingW ; // exclusion-tag: immu-pmpcboz assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~MatchingW ; // exclusion-tag: immu-pmpcboz
assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault; // exclusion-tag: immu-pmpcboaccess assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault; // exclusion-tag: immu-pmpcboaccess
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~MatchingX ; assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~MatchingX ;
assign PMPStoreAmoAccessFaultM = (EnforcePMP & WriteAccessM & ~MatchingW) | PMPCMOAccessFault; // exclusion-tag: immu-pmpstoreamoaccessfault assign PMPStoreAmoAccessFaultM = (EnforcePMP & WriteAccessM & ~MatchingW) | PMPCMOAccessFault; // exclusion-tag: immu-pmpstoreamoaccessfault
assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~WriteAccessM & ~MatchingR; assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~WriteAccessM & ~MatchingR;

View File

@ -103,7 +103,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
// when compressed instructions are supported, there can't be misaligned instructions // when compressed instructions are supported, there can't be misaligned instructions
localparam MEDELEG_MASK = P.ZCA_SUPPORTED ? 16'hB3FE : 16'hB3FF; localparam MEDELEG_MASK = P.ZCA_SUPPORTED ? 16'hB3FE : 16'hB3FF;
localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable
localparam PMPCFG_MASK = 8'h9F; // bits 6:5 are WARL 00
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i; genvar i;
@ -122,7 +121,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7]; assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7];
else else
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01); assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01);
assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~ADDRLocked[i]; assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~ADDRLocked[i];
flopenr #(P.PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[P.PA_BITS-3:0], PMPADDR_ARRAY_REGW[i]); flopenr #(P.PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[P.PA_BITS-3:0], PMPADDR_ARRAY_REGW[i]);
if (P.XLEN==64) begin if (P.XLEN==64) begin
@ -135,7 +134,7 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign CSRPMPWRLegalizedWriteValM[i] = {(CSRPMPWriteValM[i][1] & CSRPMPWriteValM[i][0]), CSRPMPWriteValM[i][0]}; // legalize WR fields (reserved 10 written as 00) assign CSRPMPWRLegalizedWriteValM[i] = {(CSRPMPWriteValM[i][1] & CSRPMPWriteValM[i][0]), CSRPMPWriteValM[i][0]}; // legalize WR fields (reserved 10 written as 00)
assign CSRPMPLegalizedWriteValM[i] = {CSRPMPWriteValM[i][7], 2'b00, CSRPMPWriteValM[i][4:2], CSRPMPWRLegalizedWriteValM[i]}; assign CSRPMPLegalizedWriteValM[i] = {CSRPMPWriteValM[i][7], 2'b00, CSRPMPWriteValM[i][4:2], CSRPMPWRLegalizedWriteValM[i]};
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRPMPWriteValM[i] & PMPCFG_MASK, PMPCFG_ARRAY_REGW[i]); flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRPMPLegalizedWriteValM[i], PMPCFG_ARRAY_REGW[i]);
end end
end end