forked from Github_Repos/cvw
		
	Optimized PMP checker logic and added support for configurable number of PMP registers
This commit is contained in:
		
							parent
							
								
									751e606fb7
								
							
						
					
					
						commit
						c85e0df1ff
					
				@ -79,7 +79,7 @@ module ifu (
 | 
			
		||||
  input  logic [2:0]       HSIZE, HBURST,
 | 
			
		||||
  input  logic             HWRITE,
 | 
			
		||||
  input  logic             ExecuteAccessF, //read, write, and atomic access are all set to zero because this mmu is onlt working with instructinos in the F stage.
 | 
			
		||||
  input  logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so they're gonna have to come over into ifu and dmem
 | 
			
		||||
  input  var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  input  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], 
 | 
			
		||||
 | 
			
		||||
  output logic             PMPInstrAccessFaultF, PMAInstrAccessFaultF,
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ module lsu (
 | 
			
		||||
  input  logic [2:0]       HSIZE, HBURST,
 | 
			
		||||
  input  logic             HWRITE,
 | 
			
		||||
  input  logic             AtomicAccessM, WriteAccessM, ReadAccessM, // execute access is hardwired to zero in this mmu because we're only working with data in the M stage.
 | 
			
		||||
  input  logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem
 | 
			
		||||
  input  var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  input  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // *** this one especially has a large note attached to it in pmpchecker.
 | 
			
		||||
 | 
			
		||||
  output  logic            PMALoadAccessFaultM, PMAStoreAccessFaultM,
 | 
			
		||||
 | 
			
		||||
@ -70,8 +70,8 @@ module mmu #(parameter ENTRY_BITS = 3,
 | 
			
		||||
  input  logic [2:0]       HSIZE, HBURST,
 | 
			
		||||
  input  logic             HWRITE,
 | 
			
		||||
  input  logic             AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
 | 
			
		||||
  input  logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem
 | 
			
		||||
  input  var logic  [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], 
 | 
			
		||||
  input  var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  input  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], 
 | 
			
		||||
 | 
			
		||||
  output logic             SquashBusAccess, // *** send to privileged unit
 | 
			
		||||
  output logic             PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM,
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,6 @@ module pmpchecker (
 | 
			
		||||
 | 
			
		||||
  input  logic [1:0]       PrivilegeModeW,
 | 
			
		||||
 | 
			
		||||
  input  logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW,
 | 
			
		||||
 | 
			
		||||
  // *** ModelSim has a switch -svinputport which controls whether input ports
 | 
			
		||||
  // are nets (wires) or vars by default. The default setting of this switch is
 | 
			
		||||
@ -48,6 +47,7 @@ module pmpchecker (
 | 
			
		||||
  // boundary. It would be better to store the PMP address registers in a module
 | 
			
		||||
  // somewhere in the CSR hierarchy and do PMP checking _within_ that module, so
 | 
			
		||||
  // we don't have to pass around 16 whole registers.
 | 
			
		||||
  input  var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  input  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
 | 
			
		||||
 | 
			
		||||
  input  logic             ExecuteAccessF, WriteAccessM, ReadAccessM,
 | 
			
		||||
@ -60,29 +60,23 @@ module pmpchecker (
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  // Bit i is high when the address falls in PMP region i
 | 
			
		||||
  logic [15:0] Regions;
 | 
			
		||||
  logic [3:0]  MatchedRegion;
 | 
			
		||||
  logic        Match, EnforcePMP;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] Regions, FirstMatch;
 | 
			
		||||
  //logic [3:0]  MatchedRegion;
 | 
			
		||||
  logic        EnforcePMP;
 | 
			
		||||
 | 
			
		||||
  logic [7:0] PMPCFG [15:0];
 | 
			
		||||
  logic [7:0] PMPCFG [`PMP_ENTRIES-1:0];
 | 
			
		||||
 | 
			
		||||
  // Bit i is high when the address is greater than or equal to PMPADR[i]
 | 
			
		||||
  // Used for determining whether TOR PMP regions match
 | 
			
		||||
  logic [15:0] AboveRegion;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] AboveRegion;
 | 
			
		||||
 | 
			
		||||
  // Bit i is high if PMP register i is non-null
 | 
			
		||||
  logic [15:0] ActiveRegion;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] ActiveRegion;
 | 
			
		||||
 | 
			
		||||
  logic L_Bit, X_Bit, W_Bit, R_Bit;
 | 
			
		||||
  logic InvalidExecute, InvalidWrite, InvalidRead;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] L_Bits, X_Bits, W_Bits, R_Bits;
 | 
			
		||||
  //logic InvalidExecute, InvalidWrite, InvalidRead;
 | 
			
		||||
 | 
			
		||||
  // *** extend to optionally 64 configurations
 | 
			
		||||
 | 
			
		||||
  assign {PMPCFG[15], PMPCFG[14], PMPCFG[13], PMPCFG[12],
 | 
			
		||||
          PMPCFG[11], PMPCFG[10], PMPCFG[9], PMPCFG[8]} = PMPCFG23_REGW;
 | 
			
		||||
 | 
			
		||||
  assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
 | 
			
		||||
          PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW;
 | 
			
		||||
  genvar i,j;
 | 
			
		||||
 | 
			
		||||
  pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[0][4:3]),
 | 
			
		||||
                      .CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
 | 
			
		||||
@ -92,7 +86,6 @@ module pmpchecker (
 | 
			
		||||
  assign ActiveRegion[0] = |PMPCFG[0][4:3];
 | 
			
		||||
 | 
			
		||||
  generate // *** only for PMP_ENTRIES > 0
 | 
			
		||||
    genvar i;
 | 
			
		||||
    for (i = 1; i < `PMP_ENTRIES; i++) begin
 | 
			
		||||
      pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[i][4:3]),
 | 
			
		||||
                          .CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
 | 
			
		||||
@ -104,12 +97,34 @@ module pmpchecker (
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  assign Match = |Regions;
 | 
			
		||||
  //assign Match = |Regions; 
 | 
			
		||||
 | 
			
		||||
  // Only enforce PMP checking for S and U modes when at least one PMP is active
 | 
			
		||||
  assign EnforcePMP = |ActiveRegion;
 | 
			
		||||
 | 
			
		||||
  // *** extend to up to 64, fold bit extraction to avoid need for binary encoding of region
 | 
			
		||||
  // verilator lint_off UNOPTFLAT
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0] NoLowerMatch;
 | 
			
		||||
//  assign NoLowerMatch[0] = 1;
 | 
			
		||||
  generate
 | 
			
		||||
    // verilator lint_off WIDTH
 | 
			
		||||
    for (j=0; j<`PMP_ENTRIES; j = j+8) begin
 | 
			
		||||
      assign {PMPCFG[j+7], PMPCFG[j+6], PMPCFG[j+5], PMPCFG[j+4],
 | 
			
		||||
              PMPCFG[j+3], PMPCFG[j+2], PMPCFG[j+1], PMPCFG[j]} = PMPCFG_ARRAY_REGW[j/8];
 | 
			
		||||
    end
 | 
			
		||||
    // verilator lint_on WIDTH
 | 
			
		||||
    for (i=0; i<`PMP_ENTRIES; i++) begin
 | 
			
		||||
      if (i==0) begin
 | 
			
		||||
	 assign FirstMatch[i] = Regions[i];
 | 
			
		||||
	assign NoLowerMatch[i] = ~Regions[i];
 | 
			
		||||
      end else begin
 | 
			
		||||
	 assign FirstMatch[i] = Regions[i] & NoLowerMatch[i];
 | 
			
		||||
	assign NoLowerMatch[i] = NoLowerMatch[i-1] & ~Regions[i];
 | 
			
		||||
      end
 | 
			
		||||
      assign L_Bits[i] = PMPCFG[i][7] & FirstMatch[i];
 | 
			
		||||
      assign X_Bits[i] = PMPCFG[i][2] & FirstMatch[i];
 | 
			
		||||
      assign W_Bits[i] = PMPCFG[i][1] & FirstMatch[i];
 | 
			
		||||
      assign R_Bits[i] = PMPCFG[i][0] & FirstMatch[i];
 | 
			
		||||
    end
 | 
			
		||||
    // verilator lint_on UNOPTFLAT
 | 
			
		||||
  endgenerate
 | 
			
		||||
/*  // *** extend to up to 64, fold bit extraction to avoid need for binary encoding of region
 | 
			
		||||
  always_comb
 | 
			
		||||
    casez (Regions)
 | 
			
		||||
      16'b???????????????1: MatchedRegion = 0;
 | 
			
		||||
@ -134,22 +149,18 @@ module pmpchecker (
 | 
			
		||||
  assign L_Bit = PMPCFG[MatchedRegion][7] && Match;
 | 
			
		||||
  assign X_Bit = PMPCFG[MatchedRegion][2] && Match;
 | 
			
		||||
  assign W_Bit = PMPCFG[MatchedRegion][1] && Match;
 | 
			
		||||
  assign R_Bit = PMPCFG[MatchedRegion][0] && Match;
 | 
			
		||||
  assign R_Bit = PMPCFG[MatchedRegion][0] && Match; 
 | 
			
		||||
 | 
			
		||||
  assign InvalidExecute = ExecuteAccessF && ~X_Bit;
 | 
			
		||||
  assign InvalidWrite   = WriteAccessM   && ~W_Bit;
 | 
			
		||||
  assign InvalidRead    = ReadAccessM    && ~R_Bit;
 | 
			
		||||
  assign InvalidRead    = ReadAccessM    && ~R_Bit;*/
 | 
			
		||||
 | 
			
		||||
  // *** don't cause faults when there are no PMPs
 | 
			
		||||
  assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
 | 
			
		||||
                                  Match && L_Bit && InvalidExecute :
 | 
			
		||||
                                  EnforcePMP && InvalidExecute;
 | 
			
		||||
  assign PMPStoreAccessFaultM = (PrivilegeModeW == `M_MODE) ?
 | 
			
		||||
                                  Match && L_Bit && InvalidWrite :
 | 
			
		||||
                                  EnforcePMP && InvalidWrite;
 | 
			
		||||
  assign PMPLoadAccessFaultM  = (PrivilegeModeW == `M_MODE) ?
 | 
			
		||||
                                  Match && L_Bit && InvalidRead :
 | 
			
		||||
                                  EnforcePMP && InvalidRead;
 | 
			
		||||
  // 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_Bits : |ActiveRegion;
 | 
			
		||||
 | 
			
		||||
  assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X_Bits;
 | 
			
		||||
  assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM   && ~|W_Bits;
 | 
			
		||||
  assign PMPLoadAccessFaultM  = EnforcePMP && ReadAccessM    && ~|R_Bits;
 | 
			
		||||
 | 
			
		||||
  assign PMPSquashBusAccess = PMPInstrAccessFaultF || PMPLoadAccessFaultM || PMPStoreAccessFaultM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ module csr #(parameter
 | 
			
		||||
  output logic             STATUS_MIE, STATUS_SIE,
 | 
			
		||||
  output logic             STATUS_MXR, STATUS_SUM,
 | 
			
		||||
  output logic             STATUS_MPRV,
 | 
			
		||||
  output logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW,
 | 
			
		||||
  output var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
 | 
			
		||||
  input  logic [4:0]       SetFflagsM,
 | 
			
		||||
  output logic [2:0]       FRM_REGW, 
 | 
			
		||||
 | 
			
		||||
@ -48,25 +48,9 @@ module csrm #(parameter
 | 
			
		||||
  MTVAL = 12'h343,
 | 
			
		||||
  MIP = 12'h344,
 | 
			
		||||
  PMPCFG0 = 12'h3A0,
 | 
			
		||||
  PMPCFG1 = 12'h3A1,
 | 
			
		||||
  PMPCFG2 = 12'h3A2,
 | 
			
		||||
  PMPCFG3 = 12'h3A3,
 | 
			
		||||
  // .. up to 15 more at consecutive addresses
 | 
			
		||||
  PMPADDR0 = 12'h3B0,
 | 
			
		||||
  PMPADDR1 = 12'h3B1,
 | 
			
		||||
  PMPADDR2 = 12'h3B2,
 | 
			
		||||
  PMPADDR3 = 12'h3B3,
 | 
			
		||||
  PMPADDR4 = 12'h3B4,
 | 
			
		||||
  PMPADDR5 = 12'h3B5,
 | 
			
		||||
  PMPADDR6 = 12'h3B6,
 | 
			
		||||
  PMPADDR7 = 12'h3B7,
 | 
			
		||||
  PMPADDR8 = 12'h3B8,
 | 
			
		||||
  PMPADDR9 = 12'h3B9,
 | 
			
		||||
  PMPADDR10 = 12'h3BA,
 | 
			
		||||
  PMPADDR11 = 12'h3BB,
 | 
			
		||||
  PMPADDR12 = 12'h3BC,
 | 
			
		||||
  PMPADDR13 = 12'h3BD,
 | 
			
		||||
  PMPADDR14 = 12'h3BE,
 | 
			
		||||
  PMPADDR15 = 12'h3BF,
 | 
			
		||||
  // ... up to 63 more at consecutive addresses
 | 
			
		||||
  TSELECT = 12'h7A0,
 | 
			
		||||
  TDATA1 = 12'h7A1,
 | 
			
		||||
  TDATA2 = 12'h7A2,
 | 
			
		||||
@ -90,7 +74,7 @@ module csrm #(parameter
 | 
			
		||||
    output logic [31:0]      MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, 
 | 
			
		||||
    output logic [`XLEN-1:0]      MEDELEG_REGW, MIDELEG_REGW,
 | 
			
		||||
    // 64-bit registers in RV64, or two 32-bit registers in RV32
 | 
			
		||||
    output logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW,
 | 
			
		||||
    output var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
    output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
 | 
			
		||||
    input  logic [11:0]      MIP_REGW, MIE_REGW,
 | 
			
		||||
    output logic             WriteMSTATUSM,
 | 
			
		||||
@ -103,8 +87,8 @@ module csrm #(parameter
 | 
			
		||||
  logic            WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
 | 
			
		||||
  logic            WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
 | 
			
		||||
  logic            WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
 | 
			
		||||
  logic            WritePMPCFG0M, WritePMPCFG2M;
 | 
			
		||||
  logic            WritePMPADDRM [15:0]; 
 | 
			
		||||
  logic [`PMP_ENTRIES/8-1:0] WritePMPCFGM, WritePMPCFGHM ;
 | 
			
		||||
  logic [`PMP_ENTRIES-1:0]   WritePMPADDRM ; 
 | 
			
		||||
 | 
			
		||||
  localparam MISA_26 = (`MISA) & 32'h03ffffff;
 | 
			
		||||
 | 
			
		||||
@ -120,7 +104,7 @@ module csrm #(parameter
 | 
			
		||||
  assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC)) && ~StallW;
 | 
			
		||||
  assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE)) && ~StallW;
 | 
			
		||||
  assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL)) && ~StallW;
 | 
			
		||||
  assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0)) && ~StallW;
 | 
			
		||||
/*  assign WritePMPCFG0M = (CSRMWriteM && (CSRAdrM == PMPCFG0)) && ~StallW;
 | 
			
		||||
  assign WritePMPCFG2M = (CSRMWriteM && (CSRAdrM == PMPCFG2)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[0] = (CSRMWriteM && (CSRAdrM == PMPADDR0)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[1] = (CSRMWriteM && (CSRAdrM == PMPADDR1)) && ~StallW;
 | 
			
		||||
@ -137,10 +121,13 @@ module csrm #(parameter
 | 
			
		||||
  assign WritePMPADDRM[12] = (CSRMWriteM && (CSRAdrM == PMPADDR12)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[13] = (CSRMWriteM && (CSRAdrM == PMPADDR13)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[14] = (CSRMWriteM && (CSRAdrM == PMPADDR14)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[15] = (CSRMWriteM && (CSRAdrM == PMPADDR15)) && ~StallW;
 | 
			
		||||
  assign WritePMPADDRM[15] = (CSRMWriteM && (CSRAdrM == PMPADDR15)) && ~StallW; */
 | 
			
		||||
  assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN) && ~StallW;
 | 
			
		||||
  assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT) && ~StallW;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  assign IllegalCSRMWriteReadonlyM = CSRMWriteM && (CSRAdrM == MVENDORID || CSRAdrM == MARCHID || CSRAdrM == MIMPID || CSRAdrM == MHARTID);
 | 
			
		||||
 | 
			
		||||
  // CSRs
 | 
			
		||||
@ -172,33 +159,39 @@ module csrm #(parameter
 | 
			
		||||
  flopenl #(32)   MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTINHIBIT_REGW);
 | 
			
		||||
 | 
			
		||||
  // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
 | 
			
		||||
 | 
			
		||||
  // *** need to add support for locked PMPCFG and PMPADR
 | 
			
		||||
  genvar i;
 | 
			
		||||
  generate
 | 
			
		||||
    genvar i;
 | 
			
		||||
    for (i = 0; i < `PMP_ENTRIES; i++) begin: pmp_flop
 | 
			
		||||
    for(i=0; i<`PMP_ENTRIES; i++) begin
 | 
			
		||||
      assign WritePMPADDRM[i] = (CSRMWriteM && (CSRAdrM == PMPADDR0+i)) && ~StallW;
 | 
			
		||||
      flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i]);
 | 
			
		||||
    end
 | 
			
		||||
    for (i=0; i<`PMP_ENTRIES/8; i++) begin
 | 
			
		||||
      if (`XLEN==64) begin
 | 
			
		||||
        assign WritePMPCFGM[i] = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i)) && ~StallW;
 | 
			
		||||
        flopenr #(`XLEN) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i]);
 | 
			
		||||
      end else begin
 | 
			
		||||
        assign WritePMPCFGM[i]  = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i)) && ~StallW;
 | 
			
		||||
        assign WritePMPCFGHM[i] = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i+1)) && ~StallW;
 | 
			
		||||
        flopenr #(`XLEN) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i][31:0]);
 | 
			
		||||
        flopenr #(`XLEN) PMPCFGHreg(clk, reset, WritePMPCFGHM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i][63:32]);
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  // PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32
 | 
			
		||||
  generate
 | 
			
		||||
    if (`XLEN==64) begin
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG01reg(clk, reset, WritePMPCFG0M, CSRWriteValM, PMPCFG01_REGW);
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG23reg(clk, reset, WritePMPCFG2M, CSRWriteValM, PMPCFG23_REGW);      
 | 
			
		||||
    end else begin
 | 
			
		||||
      logic WritePMPCFG1M, WritePMPCFG3M;
 | 
			
		||||
      assign WritePMPCFG1M = MTrapM | (CSRMWriteM && (CSRAdrM == PMPCFG1));
 | 
			
		||||
      assign WritePMPCFG3M = MTrapM | (CSRMWriteM && (CSRAdrM == PMPCFG3));
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG0reg(clk, reset, WritePMPCFG0M, CSRWriteValM, PMPCFG01_REGW[31:0]);
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG1reg(clk, reset, WritePMPCFG1M, CSRWriteValM, PMPCFG01_REGW[63:32]);            
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG2reg(clk, reset, WritePMPCFG2M, CSRWriteValM, PMPCFG23_REGW[31:0]);
 | 
			
		||||
      flopenr #(`XLEN) PMPCFG3reg(clk, reset, WritePMPCFG3M, CSRWriteValM, PMPCFG23_REGW[63:32]);            
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
  // Read machine mode CSRs
 | 
			
		||||
  // verilator lint_off WIDTH
 | 
			
		||||
  always_comb begin
 | 
			
		||||
    IllegalCSRMAccessM = !(`S_SUPPORTED | `U_SUPPORTED & `N_SUPPORTED) && 
 | 
			
		||||
                          (CSRAdrM == MEDELEG || CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
 | 
			
		||||
    case (CSRAdrM) 
 | 
			
		||||
    if (CSRAdrM >= PMPADDR0 && CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
 | 
			
		||||
      CSRMReadValM = PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0];
 | 
			
		||||
    else if (CSRAdrM >= PMPCFG0 && CSRAdrM < PMPCFG0 + `PMP_ENTRIES/8) begin
 | 
			
		||||
      if (~CSRAdrM[0]) CSRMReadValM = PMPCFG_ARRAY_REGW[CSRAdrM - PMPCFG0][`XLEN-1:0];
 | 
			
		||||
      else             CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG_ARRAY_REGW[CSRAdrM - PMPCFG0][63:32]};
 | 
			
		||||
    end
 | 
			
		||||
    else case (CSRAdrM) 
 | 
			
		||||
      MISA_ADR:  CSRMReadValM = MISA_REGW;
 | 
			
		||||
      MVENDORID: CSRMReadValM = 0;
 | 
			
		||||
      MARCHID:   CSRMReadValM = 0;
 | 
			
		||||
@ -219,7 +212,7 @@ module csrm #(parameter
 | 
			
		||||
      MTVAL:     CSRMReadValM = MTVAL_REGW;
 | 
			
		||||
      MCOUNTEREN:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTEREN_REGW};
 | 
			
		||||
      MCOUNTINHIBIT:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
 | 
			
		||||
      PMPCFG0:   CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0];
 | 
			
		||||
/*      PMPCFG0:   CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0];
 | 
			
		||||
      PMPCFG1:   CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:32]};
 | 
			
		||||
      PMPCFG2:   CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0];
 | 
			
		||||
      PMPCFG3:   CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:32]};
 | 
			
		||||
@ -238,11 +231,12 @@ module csrm #(parameter
 | 
			
		||||
      PMPADDR12: CSRMReadValM = PMPADDR_ARRAY_REGW[12];
 | 
			
		||||
      PMPADDR13: CSRMReadValM = PMPADDR_ARRAY_REGW[13];
 | 
			
		||||
      PMPADDR14: CSRMReadValM = PMPADDR_ARRAY_REGW[14];
 | 
			
		||||
      PMPADDR15: CSRMReadValM = PMPADDR_ARRAY_REGW[15];
 | 
			
		||||
      PMPADDR15: CSRMReadValM = PMPADDR_ARRAY_REGW[15]; */
 | 
			
		||||
      default: begin
 | 
			
		||||
                 CSRMReadValM = 0;
 | 
			
		||||
                 IllegalCSRMAccessM = 1;
 | 
			
		||||
      end
 | 
			
		||||
    endcase
 | 
			
		||||
  end
 | 
			
		||||
  // verilator lint_on WIDTH
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ module privileged (
 | 
			
		||||
  output logic [1:0]       PrivilegeModeW,
 | 
			
		||||
  output logic [`XLEN-1:0] SATP_REGW,
 | 
			
		||||
  output logic             STATUS_MXR, STATUS_SUM,
 | 
			
		||||
  output logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW,
 | 
			
		||||
  output var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | 
			
		||||
  output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], 
 | 
			
		||||
  output logic [2:0]       FRM_REGW
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -126,7 +126,7 @@ module wallypipelinedhart (
 | 
			
		||||
  logic             DSquashBusAccessM, ISquashBusAccessF;
 | 
			
		||||
  logic [5:0]            DHSELRegionsM, IHSELRegionsF;
 | 
			
		||||
  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
 | 
			
		||||
  logic [63:0]      PMPCFG01_REGW, PMPCFG23_REGW; // signals being sent from privileged unit to pmp/pma in dmem and ifu.
 | 
			
		||||
  var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0];
 | 
			
		||||
  assign            HSELRegions = ExecuteAccessF ? IHSELRegionsF : DHSELRegionsM; // *** this is a pure guess on how one of these should be selected. it passes tests, but is it the right way to do this?
 | 
			
		||||
 | 
			
		||||
  // IMem stalls
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user