mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge pull request #115 from davidharrishmc/dev
Fixed SSTC being unusable in M-MODE without Status.TM. Disable STIME…
This commit is contained in:
		
						commit
						849cbcbf20
					
				@ -135,7 +135,7 @@
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 1
 | 
			
		||||
`define SVADU_SUPPORTED 1
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -144,7 +144,7 @@
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 1
 | 
			
		||||
`define SVADU_SUPPORTED 1
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -138,7 +138,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -137,7 +137,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -138,7 +138,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -137,7 +137,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -140,7 +140,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -140,7 +140,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -140,7 +140,7 @@
 | 
			
		||||
`define BPRED_SIZE 10
 | 
			
		||||
`define BTB_SIZE 10
 | 
			
		||||
 | 
			
		||||
`define HPTW_WRITES_SUPPORTED 0
 | 
			
		||||
`define SVADU_SUPPORTED 0
 | 
			
		||||
 | 
			
		||||
// FPU division architecture
 | 
			
		||||
`define RADIX 32'h4
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ module spill #(
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
 | 
			
		||||
  assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
 | 
			
		||||
  assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrDAPageFaultF));
 | 
			
		||||
  
 | 
			
		||||
  always_ff @(posedge clk)
 | 
			
		||||
    if (reset | FlushD)    CurrState <= #1 STATE_READY;
 | 
			
		||||
 | 
			
		||||
@ -87,7 +87,7 @@ module hptw (
 | 
			
		||||
  logic [`XLEN-1:0] 	   TranslationVAdr;
 | 
			
		||||
  logic [`XLEN-1:0] 	   NextPTE;
 | 
			
		||||
  logic 				   UpdatePTE;
 | 
			
		||||
  logic 				   DAPageFault;
 | 
			
		||||
  logic 				   HPTWDAPageFault;
 | 
			
		||||
  logic [`PA_BITS-1:0] 	   HPTWReadAdr;
 | 
			
		||||
  logic 				   SelHPTWAdr;
 | 
			
		||||
  logic [`XLEN+1:0] 	   HPTWAdrExt;
 | 
			
		||||
@ -125,7 +125,7 @@ module hptw (
 | 
			
		||||
	assign ValidLeafPTE = ValidPTE & LeafPTE;
 | 
			
		||||
	assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
 | 
			
		||||
 | 
			
		||||
  if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
 | 
			
		||||
  if(`SVADU_SUPPORTED) begin : hptwwrites
 | 
			
		||||
    logic                     ReadAccess, WriteAccess;
 | 
			
		||||
    logic                     InvalidRead, InvalidWrite;
 | 
			
		||||
    logic                     UpperBitsUnequalPageFault; 
 | 
			
		||||
@ -167,14 +167,14 @@ module hptw (
 | 
			
		||||
    // memory access.  If there is the PTE needs to be updated seting Access
 | 
			
		||||
    // and possibly also Dirty.  Dirty is set if the operation is a store/amo.
 | 
			
		||||
    // However any other fault should not cause the update.
 | 
			
		||||
    assign DAPageFault = ValidLeafPTE & (~Accessed | SetDirty) & ~OtherPageFault;
 | 
			
		||||
    assign HPTWDAPageFault = ValidLeafPTE & (~Accessed | SetDirty) & ~OtherPageFault;
 | 
			
		||||
 | 
			
		||||
    assign HPTWRW[0] = (WalkerState == UPDATE_PTE);
 | 
			
		||||
    assign UpdatePTE = (WalkerState == LEAF) & DAPageFault;
 | 
			
		||||
    assign UpdatePTE = (WalkerState == LEAF) & HPTWDAPageFault;
 | 
			
		||||
  end else begin // block: hptwwrites
 | 
			
		||||
    assign NextPTE = ReadDataM;
 | 
			
		||||
    assign HPTWAdr = HPTWReadAdr;
 | 
			
		||||
    assign DAPageFault = '0;
 | 
			
		||||
    assign HPTWDAPageFault = '0;
 | 
			
		||||
    assign UpdatePTE = '0;
 | 
			
		||||
    assign HPTWRW[0] = '0;
 | 
			
		||||
  end
 | 
			
		||||
@ -182,8 +182,8 @@ module hptw (
 | 
			
		||||
	// Enable and select signals based on states
 | 
			
		||||
	assign StartWalk = (WalkerState == IDLE) & TLBMiss;
 | 
			
		||||
	assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
 | 
			
		||||
	assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk;
 | 
			
		||||
	assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk;
 | 
			
		||||
	assign DTLBWriteM = (WalkerState == LEAF & ~HPTWDAPageFault) & DTLBWalk;
 | 
			
		||||
	assign ITLBWriteF = (WalkerState == LEAF & ~HPTWDAPageFault) & ~DTLBWalk;
 | 
			
		||||
  
 | 
			
		||||
	// FSM to track PageType based on the levels of the page table traversed
 | 
			
		||||
	flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
 | 
			
		||||
@ -262,7 +262,7 @@ module hptw (
 | 
			
		||||
					else                                 										NextWalkerState = LEAF;
 | 
			
		||||
			L0_RD: if (DCacheStallM)                     								NextWalkerState = L0_RD;
 | 
			
		||||
				   else                                     							NextWalkerState = LEAF;
 | 
			
		||||
			LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault)             NextWalkerState = UPDATE_PTE;
 | 
			
		||||
			LEAF: if (`SVADU_SUPPORTED & HPTWDAPageFault)             NextWalkerState = UPDATE_PTE;
 | 
			
		||||
				  else 																										NextWalkerState = IDLE;
 | 
			
		||||
			UPDATE_PTE: if(DCacheStallM) 		                        		NextWalkerState = UPDATE_PTE;
 | 
			
		||||
						else 																									NextWalkerState = LEAF;
 | 
			
		||||
@ -273,8 +273,8 @@ module hptw (
 | 
			
		||||
  assign SelHPTW = WalkerState != IDLE;
 | 
			
		||||
  assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss);
 | 
			
		||||
 | 
			
		||||
  assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
 | 
			
		||||
  assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);  
 | 
			
		||||
  assign ITLBMissOrDAFaultF = ITLBMissF | (`SVADU_SUPPORTED & InstrDAPageFaultF);
 | 
			
		||||
  assign DTLBMissOrDAFaultM = DTLBMissM | (`SVADU_SUPPORTED & DataDAPageFaultM);  
 | 
			
		||||
 | 
			
		||||
  // HTPW address/data/control muxing
 | 
			
		||||
 | 
			
		||||
@ -291,7 +291,7 @@ module hptw (
 | 
			
		||||
  mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);    
 | 
			
		||||
  mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);
 | 
			
		||||
  mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, IHAdrM);
 | 
			
		||||
  if(`HPTW_WRITES_SUPPORTED)
 | 
			
		||||
  if(`SVADU_SUPPORTED)
 | 
			
		||||
    mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, IHWriteDataM);
 | 
			
		||||
  else assign IHWriteDataM = WriteDataM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -120,9 +120,9 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) (
 | 
			
		||||
 | 
			
		||||
  // Access faults
 | 
			
		||||
  // If TLB miss and translating we want to not have faults from the PMA and PMP checkers.
 | 
			
		||||
  assign InstrAccessFaultF    = (PMAInstrAccessFaultF    | PMPInstrAccessFaultF)    & ~(Translate & ~TLBHit);
 | 
			
		||||
  assign LoadAccessFaultM     = (PMALoadAccessFaultM     | PMPLoadAccessFaultM)     & ~(Translate & ~TLBHit);
 | 
			
		||||
  assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM) & ~(Translate & ~TLBHit);
 | 
			
		||||
  assign InstrAccessFaultF    = (PMAInstrAccessFaultF    | PMPInstrAccessFaultF)    & ~TLBMiss;
 | 
			
		||||
  assign LoadAccessFaultM     = (PMALoadAccessFaultM     | PMPLoadAccessFaultM)     & ~TLBMiss;
 | 
			
		||||
  assign StoreAmoAccessFaultM = (PMAStoreAmoAccessFaultM | PMPStoreAmoAccessFaultM) & ~TLBMiss;
 | 
			
		||||
 | 
			
		||||
  // Misaligned faults
 | 
			
		||||
   always_comb
 | 
			
		||||
 | 
			
		||||
@ -85,5 +85,9 @@ module pmpadrdec (
 | 
			
		||||
  assign W = PMPCfg[1];
 | 
			
		||||
  assign R = PMPCfg[0];
 | 
			
		||||
  assign Active = |PMPCfg[4:3];
 | 
			
		||||
 | 
			
		||||
  // known bug: The size of the access is not yet checked.  For example, if an NA4 entry matches 0xC-0xF and the system
 | 
			
		||||
  // attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This
 | 
			
		||||
  // implementation will not detect the failure.
 | 
			
		||||
 endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ module tlbcontrol #(parameter ITLB = 0) (
 | 
			
		||||
    // only execute non-user mode pages.
 | 
			
		||||
    assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
 | 
			
		||||
      ((EffectivePrivilegeMode == `S_MODE) & PTE_U);
 | 
			
		||||
    if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
 | 
			
		||||
    if(`SVADU_SUPPORTED) begin : hptwwrites
 | 
			
		||||
      assign DAPageFault = Translate & TLBHit & ~PTE_A & ~TLBPageFault;
 | 
			
		||||
      assign TLBPageFault = (Translate  & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
 | 
			
		||||
    end else begin
 | 
			
		||||
@ -98,7 +98,7 @@ module tlbcontrol #(parameter ITLB = 0) (
 | 
			
		||||
    // Check for write error. Writes are invalid when the page's write bit is
 | 
			
		||||
    // low.
 | 
			
		||||
    assign InvalidWrite = WriteAccess & ~PTE_W;
 | 
			
		||||
    if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
 | 
			
		||||
    if(`SVADU_SUPPORTED) begin : hptwwrites
 | 
			
		||||
      assign DAPageFault = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D) & ~TLBPageFault; 
 | 
			
		||||
      assign TLBPageFault =  (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
 | 
			
		||||
    end else begin
 | 
			
		||||
 | 
			
		||||
@ -86,8 +86,8 @@ module csrs #(parameter
 | 
			
		||||
  assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & MCOUNTEREN_TM & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & MCOUNTEREN_TM & (`XLEN == 32) & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & InstrValidNotFlushedM;
 | 
			
		||||
  assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & (`XLEN == 32) & InstrValidNotFlushedM;
 | 
			
		||||
 | 
			
		||||
  // CSRs
 | 
			
		||||
  flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); 
 | 
			
		||||
@ -100,12 +100,14 @@ module csrs #(parameter
 | 
			
		||||
  else
 | 
			
		||||
    assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
 | 
			
		||||
  flopens #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
 | 
			
		||||
  if (`XLEN == 64)
 | 
			
		||||
    flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW);
 | 
			
		||||
  else begin
 | 
			
		||||
    flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]);
 | 
			
		||||
    flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]);
 | 
			
		||||
  end
 | 
			
		||||
  if (`SSTC_SUPPORTED) begin
 | 
			
		||||
    if (`XLEN == 64)
 | 
			
		||||
      flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW);
 | 
			
		||||
    else begin
 | 
			
		||||
      flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]);
 | 
			
		||||
      flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]);
 | 
			
		||||
    end
 | 
			
		||||
  end else assign STIMECMP_REGW = 0;
 | 
			
		||||
 | 
			
		||||
  // Supervisor timer interrupt logic
 | 
			
		||||
  // Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs
 | 
			
		||||
@ -132,12 +134,12 @@ module csrs #(parameter
 | 
			
		||||
                    if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
 | 
			
		||||
                  end
 | 
			
		||||
      SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
 | 
			
		||||
      STIMECMP:  if (MCOUNTEREN_TM) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; 
 | 
			
		||||
      STIMECMP:  if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; 
 | 
			
		||||
                 else begin 
 | 
			
		||||
                   CSRSReadValM = 0;
 | 
			
		||||
                   IllegalCSRSAccessM = 1;
 | 
			
		||||
                 end
 | 
			
		||||
      STIMECMPH: if (MCOUNTEREN_TM & (`XLEN == 32)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
 | 
			
		||||
      STIMECMPH: if (`SSTC_SUPPORTED & (`XLEN == 32) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
 | 
			
		||||
                 else begin // not supported for RV64
 | 
			
		||||
                   CSRSReadValM = 0;
 | 
			
		||||
                   IllegalCSRSAccessM = 1;
 | 
			
		||||
 | 
			
		||||
@ -101,7 +101,7 @@ package cvw;
 | 
			
		||||
  parameter BPRED_SUPPORTED = `BPRED_SUPPORTED;
 | 
			
		||||
  parameter BPRED_TYPE = `BPRED_TYPE;
 | 
			
		||||
  parameter BPRED_SIZE = `BPRED_SIZE;
 | 
			
		||||
  parameter HPTW_WRITES_SUPPORTED = `HPTW_WRITES_SUPPORTED;
 | 
			
		||||
  parameter SVADU_SUPPORTED = `SVADU_SUPPORTED;
 | 
			
		||||
//  parameter  = `;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user