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
						f411e63dc8
					
				| @ -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