forked from Github_Repos/cvw
		
	WFI terminates when an interrupt is pending even if interrupts are globally disabled
This commit is contained in:
		
							parent
							
								
									412d4656ed
								
							
						
					
					
						commit
						a516f89f22
					
				| @ -38,7 +38,7 @@ module hazard( | ||||
| (* mark_debug = "true" *)              input logic  FPUStallD, FStallD, | ||||
| (* mark_debug = "true" *)	      input logic  DivBusyE,FDivBusyE, | ||||
| (* mark_debug = "true" *)	      input logic  EcallFaultM, BreakpointFaultM, | ||||
| (* mark_debug = "true" *)        input logic  InvalidateICacheM, wfiM, | ||||
| (* mark_debug = "true" *)        input logic  InvalidateICacheM, wfiM, IntPendingM, | ||||
|   // Stall & flush outputs
 | ||||
| (* mark_debug = "true" *)	      output logic StallF, StallD, StallE, StallM, StallW, | ||||
| (* mark_debug = "true" *)	      output logic FlushF, FlushD, FlushE, FlushM, FlushW | ||||
| @ -61,9 +61,11 @@ module hazard( | ||||
|   // If any stages are stalled, the first stage that isn't stalled must flush.
 | ||||
| 
 | ||||
|   assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE); | ||||
|   assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);    // stall in decode if instruction is a load/mul/csr dependent on previous
 | ||||
|   // stall in decode if instruction is a load/mul/csr dependent on previous
 | ||||
|   assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);     | ||||
|   assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); | ||||
|   assign StallMCause = wfiM & ~TrapM;  | ||||
|   // WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled.  It could also terminate with TW trap
 | ||||
|   assign StallMCause = wfiM & (~TrapM & ~IntPendingM);   | ||||
|   assign StallWCause = LSUStallM | IFUStallF; | ||||
| 
 | ||||
|   assign StallF = StallFCause | StallD; | ||||
|  | ||||
| @ -78,7 +78,7 @@ module privileged ( | ||||
|   output var logic [7:0]   PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], | ||||
|   output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],  | ||||
|   output logic [2:0]       FRM_REGW, | ||||
|   output logic             BreakpointFaultM, EcallFaultM, wfiM | ||||
|   output logic             BreakpointFaultM, EcallFaultM, wfiM, IntPendingM | ||||
| ); | ||||
| 
 | ||||
|   logic [1:0] NextPrivilegeModeM; | ||||
| @ -226,7 +226,7 @@ module privileged ( | ||||
|             .InstrM, | ||||
|             .InstrValidM, .CommittedM, .DivE,  | ||||
|             .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM, | ||||
|             .InterruptM, | ||||
|             .InterruptM, .IntPendingM, | ||||
|             .ExceptionM, | ||||
|             .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM); | ||||
| endmodule | ||||
|  | ||||
| @ -48,7 +48,7 @@ module trap ( | ||||
|   input logic [31:0] 	   InstrM, | ||||
|   input logic 		   InstrValidM, CommittedM, DivE,  | ||||
|   output logic 		   TrapM, MTrapM, STrapM, UTrapM, RetM, | ||||
|   output logic 		   InterruptM, | ||||
|   output logic 		   InterruptM, IntPendingM, | ||||
|   output logic 		   ExceptionM, | ||||
|   output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM | ||||
| //  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | ||||
| @ -56,7 +56,7 @@ module trap ( | ||||
| ); | ||||
| 
 | ||||
|   logic MIntGlobalEnM, SIntGlobalEnM; | ||||
|   (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;  | ||||
|   (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM, MValidIntsM, SValidIntsM;  | ||||
|   //logic InterruptM;
 | ||||
|   logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; | ||||
|   logic Exception1M; | ||||
| @ -65,13 +65,16 @@ module trap ( | ||||
|   // interrupt if any sources are pending
 | ||||
|   // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage)
 | ||||
|   // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice
 | ||||
|   // MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
 | ||||
|   // MValidIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
 | ||||
|   // Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i]
 | ||||
|   assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9
 | ||||
|   assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9
 | ||||
|   assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW; | ||||
|   assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW; | ||||
|   assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM);  // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
 | ||||
|   assign MPendingIntsM = MIP_REGW & MIE_REGW; | ||||
|   assign SPendingIntsM = SIP_REGW & SIE_REGW; | ||||
|   assign IntPendingM = |MPendingIntsM; | ||||
|   assign MValidIntsM = {12{MIntGlobalEnM}} & MPendingIntsM & ~MIDELEG_REGW; | ||||
|   assign SValidIntsM = {12{SIntGlobalEnM}} & SPendingIntsM; | ||||
|   assign InterruptM = (|MValidIntsM || |SValidIntsM) && InstrValidM && ~(CommittedM);  // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
 | ||||
| 
 | ||||
|   // Trigger Traps and RET
 | ||||
|   // According to RISC-V Spec Section 1.6, exceptions are caused by instructions.  Interrupts are external asynchronous.
 | ||||
| @ -119,15 +122,15 @@ module trap ( | ||||
|   // Exceptions are of lower priority than all interrupts (3.1.9)
 | ||||
|   always_comb | ||||
|     if      (reset)                 CauseM = 0; // hard reset 3.3
 | ||||
|     else if (MPendingIntsM[11])     CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
 | ||||
|     else if (MPendingIntsM[3])      CauseM = (1 << (`XLEN-1)) + 3;  // Machine Sw Int
 | ||||
|     else if (MPendingIntsM[7])      CauseM = (1 << (`XLEN-1)) + 7;  // Machine Timer Int
 | ||||
|     else if (MPendingIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by M-mode
 | ||||
|     else if (MPendingIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by M-mode
 | ||||
|     else if (MPendingIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by M-mode
 | ||||
|     else if (SPendingIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by S-mode
 | ||||
|     else if (SPendingIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by S-mode
 | ||||
|     else if (SPendingIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by S-mode
 | ||||
|     else if (MValidIntsM[11])     CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
 | ||||
|     else if (MValidIntsM[3])      CauseM = (1 << (`XLEN-1)) + 3;  // Machine Sw Int
 | ||||
|     else if (MValidIntsM[7])      CauseM = (1 << (`XLEN-1)) + 7;  // Machine Timer Int
 | ||||
|     else if (MValidIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by M-mode
 | ||||
|     else if (MValidIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by M-mode
 | ||||
|     else if (MValidIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by M-mode
 | ||||
|     else if (SValidIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by S-mode
 | ||||
|     else if (SValidIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by S-mode
 | ||||
|     else if (SValidIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by S-mode
 | ||||
|     else if (InstrPageFaultM)       CauseM = 12; | ||||
|     else if (InstrAccessFaultM)     CauseM = 1; | ||||
|     else if (IllegalInstrFaultM)    CauseM = 2; | ||||
|  | ||||
| @ -112,7 +112,7 @@ module wallypipelinedcore ( | ||||
|   logic [1:0]             PrivilegeModeW; | ||||
|   logic [`XLEN-1:0]     PTE; | ||||
|   logic [1:0]             PageType; | ||||
|   logic              wfiM; | ||||
|   logic              wfiM, IntPendingM; | ||||
| 
 | ||||
|   // PMA checker signals
 | ||||
|   var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0]; | ||||
| @ -306,7 +306,7 @@ module wallypipelinedcore ( | ||||
|      .FPUStallD, .FStallD, | ||||
|     .DivBusyE, .FDivBusyE, | ||||
|     .EcallFaultM, .BreakpointFaultM, | ||||
|      .InvalidateICacheM, .wfiM, | ||||
|      .InvalidateICacheM, .wfiM, .IntPendingM, | ||||
|      // Stall & flush outputs
 | ||||
|     .StallF, .StallD, .StallE, .StallM, .StallW, | ||||
|     .FlushF, .FlushD, .FlushE, .FlushM, .FlushW | ||||
| @ -341,7 +341,7 @@ module wallypipelinedcore ( | ||||
|          .PrivilegeModeW, .SATP_REGW, | ||||
|          .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, | ||||
|          .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,  | ||||
|          .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM | ||||
|          .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM | ||||
|       ); | ||||
|    end else begin | ||||
|       assign CSRReadValW = 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user