mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Moved TLB Flush logic into privdec
This commit is contained in:
		
							parent
							
								
									1e5d94bbab
								
							
						
					
					
						commit
						2ceed15bd5
					
				@ -60,6 +60,8 @@ module hazard(
 | 
				
			|||||||
  // A stage must stall if the next stage is stalled
 | 
					  // A stage must stall if the next stage is stalled
 | 
				
			||||||
  // If any stages are stalled, the first stage that isn't stalled must flush.
 | 
					  // If any stages are stalled, the first stage that isn't stalled must flush.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
 | 
					  assign StallFCause = CSRWritePendingDEM & ~(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 StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);    
 | 
				
			||||||
 | 
				
			|||||||
@ -33,16 +33,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module privdec (
 | 
					module privdec (
 | 
				
			||||||
  input  logic         clk, reset,
 | 
					  input  logic         clk, reset,
 | 
				
			||||||
 | 
					  input  logic         StallM,
 | 
				
			||||||
  input  logic [31:20] InstrM,
 | 
					  input  logic [31:20] InstrM,
 | 
				
			||||||
  input  logic         PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM, 
 | 
					  input  logic         PrivilegedM, IllegalIEUInstrFaultM, IllegalCSRAccessM, IllegalFPUInstrM, 
 | 
				
			||||||
  input  logic [1:0]   PrivilegeModeW, 
 | 
					  input  logic [1:0]   PrivilegeModeW, 
 | 
				
			||||||
  input  logic         STATUS_TSR, STATUS_TVM, STATUS_TW,
 | 
					  input  logic         STATUS_TSR, STATUS_TVM, STATUS_TW,
 | 
				
			||||||
  input  logic [1:0]   STATUS_FS,
 | 
					  input  logic [1:0]   STATUS_FS,
 | 
				
			||||||
  output logic         IllegalInstrFaultM,
 | 
					  output logic         IllegalInstrFaultM, ITLBFlushF, DTLBFlushM,
 | 
				
			||||||
  output logic         sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
 | 
					  output logic         sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
 | 
					  logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
 | 
				
			||||||
  logic WFITimeoutM;
 | 
					  logic WFITimeoutM;
 | 
				
			||||||
 | 
					  logic       StallMQ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
  // Decode privileged instructions
 | 
					  // Decode privileged instructions
 | 
				
			||||||
@ -66,6 +68,18 @@ module privdec (
 | 
				
			|||||||
    assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT]; 
 | 
					    assign WFITimeoutM = ((STATUS_TW & PrivilegeModeW != `M_MODE) | (`S_SUPPORTED & PrivilegeModeW == `U_MODE)) & WFICount[`WFI_TIMEOUT_BIT]; 
 | 
				
			||||||
  end else assign WFITimeoutM = 0;
 | 
					  end else assign WFITimeoutM = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
 | 
					  // sfence.vma causes TLB flushes
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
 | 
					  // sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
 | 
				
			||||||
 | 
					  // In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
 | 
				
			||||||
 | 
					  // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and 
 | 
				
			||||||
 | 
					  // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush 
 | 
				
			||||||
 | 
					  // after a cycle AND pulse it for another cycle on any further back-to-back sfences. 
 | 
				
			||||||
 | 
					  flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
 | 
				
			||||||
 | 
					  assign ITLBFlushF = sfencevmaM & ~StallMQ;
 | 
				
			||||||
 | 
					  assign DTLBFlushM = sfencevmaM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
  // Fault on illegal instructions
 | 
					  // Fault on illegal instructions
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
 | 
				
			|||||||
@ -100,11 +100,8 @@ module privileged (
 | 
				
			|||||||
  logic       STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM;
 | 
					  logic       STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM;
 | 
				
			||||||
  logic       STATUS_MIE, STATUS_SIE;
 | 
					  logic       STATUS_MIE, STATUS_SIE;
 | 
				
			||||||
  logic [11:0] MIP_REGW, MIE_REGW;
 | 
					  logic [11:0] MIP_REGW, MIE_REGW;
 | 
				
			||||||
  logic       StallMQ;
 | 
					 | 
				
			||||||
  logic WFITimeoutM; 
 | 
					 | 
				
			||||||
  logic [1:0] NextPrivilegeModeM;
 | 
					  logic [1:0] NextPrivilegeModeM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
  // track the current privilege level
 | 
					  // track the current privilege level
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
@ -116,9 +113,10 @@ module privileged (
 | 
				
			|||||||
  // decode privileged instructions
 | 
					  // decode privileged instructions
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   privdec pmd(.clk, .reset, .InstrM(InstrM[31:20]), 
 | 
					   privdec pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:20]), 
 | 
				
			||||||
              .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, 
 | 
					              .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, 
 | 
				
			||||||
              .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM, 
 | 
					              .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .STATUS_FS, .IllegalInstrFaultM, 
 | 
				
			||||||
 | 
					              .ITLBFlushF, .DTLBFlushM,
 | 
				
			||||||
              .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
 | 
					              .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////
 | 
					  ///////////////////////////////////////////
 | 
				
			||||||
@ -158,15 +156,6 @@ module privileged (
 | 
				
			|||||||
  assign BreakpointFaultM = ebreakM; // could have other causes too
 | 
					  assign BreakpointFaultM = ebreakM; // could have other causes too
 | 
				
			||||||
  assign EcallFaultM = ecallM;
 | 
					  assign EcallFaultM = ecallM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
 | 
					 | 
				
			||||||
  assign ITLBFlushF = sfencevmaM & ~StallMQ;
 | 
					 | 
				
			||||||
  assign DTLBFlushM = sfencevmaM;
 | 
					 | 
				
			||||||
  // sets ITLBFlush to pulse for one cycle of the sfence.vma instruction
 | 
					 | 
				
			||||||
  // In this instr we want to flush the tlb and then do a pagetable walk to update the itlb and continue the program.
 | 
					 | 
				
			||||||
  // But we're still in the stalled sfence instruction, so if itlbflushf == sfencevmaM, tlbflush would never drop and 
 | 
					 | 
				
			||||||
  // the tlbwrite would never take place after the pagetable walk. by adding in ~StallMQ, we are able to drop itlbflush 
 | 
					 | 
				
			||||||
  // after a cycle AND pulse it for another cycle on any further back-to-back sfences. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // A page fault might occur because of insufficient privilege during a TLB
 | 
					  // A page fault might occur because of insufficient privilege during a TLB
 | 
				
			||||||
  // lookup or a improperly formatted page table during walking
 | 
					  // lookup or a improperly formatted page table during walking
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user