mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Fixed a very complex interaction between interrupts, the icache, dcache, and hptw.
If an interrupt occurred at the start of an ITLB miss or DTLB miss the page table walk should be aborted before starting.
This commit is contained in:
		
							parent
							
								
									870549c01a
								
							
						
					
					
						commit
						2f85ac7f38
					
				@ -24,7 +24,7 @@ in the memory stage.  This is the core reason for the complexity.
 | 
			
		||||
The above table classifies the operations into 8 categories.
 | 
			
		||||
2 of the 8 are not possible because a DTLB miss implies a memory operation.
 | 
			
		||||
Each (I/D)TLB miss results in either a write to the corresponding TLB or a TLB fault.
 | 
			
		||||
To complicate things it is possilbe to have current ITLB and DTLB misses, which
 | 
			
		||||
To complicate things it is possilbe to have concurrent ITLB and DTLB misses, which
 | 
			
		||||
both can result in either a write or a fault. The table belows shows the possible
 | 
			
		||||
scenarios and the sequence of operations.
 | 
			
		||||
 | 
			
		||||
@ -72,3 +72,19 @@ to normal mode.
 | 
			
		||||
 | 
			
		||||
Type 5a is a Type 4a with a current memory operation.  The Dcache first switches to walker mode
 | 
			
		||||
 | 
			
		||||
Other traps.
 | 
			
		||||
A new problem has emerged.  What happens when an interrupt occurs during a page table walk?
 | 
			
		||||
The dcache has an output called CommittedM which tells the CPU if the memory operation is
 | 
			
		||||
committed into the memory system.  It would be wrong to pin the interrupt to a memory operation
 | 
			
		||||
when it is already or partially committed to the memory system.  Instead the next instruction
 | 
			
		||||
has to be pinned to the interrupt.  The complexity occurs with the ITLB miss; types 4, 5 and 7.
 | 
			
		||||
 | 
			
		||||
Type 4: The ITLB misses and starts using the dcache to fetch the page table.  There is no memory
 | 
			
		||||
operation. Depending on where in the walk the operations could be aborted.  If the tlb is not yet
 | 
			
		||||
updated then the walk could be aborted. However if the TLB is updated then the interrupt must be
 | 
			
		||||
delayed until the next instruction.
 | 
			
		||||
 | 
			
		||||
What is the meaning of CommittedM?
 | 
			
		||||
This signal informs the CPU if a memory operation is not started or if it is between started
 | 
			
		||||
and done. Once a memory op is started it should not be interrupted.  This is used to prevent the
 | 
			
		||||
CPU from generating an interrupt after the operation is partially or completely done.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								wally-pipelined/src/cache/dcachefsm.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								wally-pipelined/src/cache/dcachefsm.sv
									
									
									
									
										vendored
									
									
								
							@ -192,16 +192,9 @@ module dcachefsm
 | 
			
		||||
	LRUWriteEn = 1'b0;
 | 
			
		||||
	CommittedM = 1'b0;
 | 
			
		||||
 | 
			
		||||
	if(FlushDCacheM) begin
 | 
			
		||||
	  NextState = STATE_FLUSH;
 | 
			
		||||
	  DCacheStall = 1'b1;
 | 
			
		||||
	  SelAdrM = 2'b11;
 | 
			
		||||
	  FlushAdrCntRst = 1'b1;
 | 
			
		||||
	  FlushWayCntRst = 1'b1;	
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	// TLB Miss	
 | 
			
		||||
	else if((AnyCPUReqM & DTLBMissM) | ITLBMissF) begin
 | 
			
		||||
	if(((AnyCPUReqM & DTLBMissM) | ITLBMissF) & ~(ExceptionM | PendingInterruptM)) begin
 | 
			
		||||
	  // the LSU arbiter has not yet selected the PTW.
 | 
			
		||||
	  // The CPU needs to be stalled until that happens.
 | 
			
		||||
	  // If we set DCacheStall for 1 cycle before going to
 | 
			
		||||
@ -212,6 +205,16 @@ module dcachefsm
 | 
			
		||||
	  DCacheStall = 1'b1;
 | 
			
		||||
	  NextState = STATE_PTW_READY;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	// Flush dcache to next level of memory
 | 
			
		||||
	else if(FlushDCacheM  & ~(ExceptionM | PendingInterruptM)) begin
 | 
			
		||||
	  NextState = STATE_FLUSH;
 | 
			
		||||
	  DCacheStall = 1'b1;
 | 
			
		||||
	  SelAdrM = 2'b11;
 | 
			
		||||
	  FlushAdrCntRst = 1'b1;
 | 
			
		||||
	  FlushWayCntRst = 1'b1;	
 | 
			
		||||
	end
 | 
			
		||||
	
 | 
			
		||||
	// amo hit
 | 
			
		||||
	else if(AtomicM[1] & (&MemRWM) & CacheableM & ~(ExceptionM | PendingInterruptM) & CacheHit & ~DTLBMissM) begin
 | 
			
		||||
	  SelAdrM = 2'b10;
 | 
			
		||||
@ -623,7 +626,7 @@ module dcachefsm
 | 
			
		||||
	CntReset = 1'b0;
 | 
			
		||||
	AHBWrite = 1'b0;
 | 
			
		||||
	AHBRead = 1'b0;
 | 
			
		||||
	CommittedM = 1'b0;
 | 
			
		||||
	CommittedM = 1'b1;
 | 
			
		||||
	NextState = STATE_READY;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								wally-pipelined/src/cache/icache.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								wally-pipelined/src/cache/icache.sv
									
									
									
									
										vendored
									
									
								
							@ -31,7 +31,10 @@ module icache
 | 
			
		||||
   input logic 		       clk, reset,
 | 
			
		||||
   input logic 		       StallF, 
 | 
			
		||||
   input logic [`PA_BITS-1:0]  PCNextF,
 | 
			
		||||
   input logic [`PA_BITS-1:0]  PCPF, 
 | 
			
		||||
   input logic [`PA_BITS-1:0]  PCPF,
 | 
			
		||||
 | 
			
		||||
   input logic ExceptionM, PendingInterruptM,
 | 
			
		||||
   
 | 
			
		||||
   // Data read in from the ebu unit
 | 
			
		||||
   input logic [`XLEN-1:0]     InstrInF,
 | 
			
		||||
   input logic 		       InstrAckF,
 | 
			
		||||
@ -286,6 +289,8 @@ module icache
 | 
			
		||||
			.ITLBMissF,
 | 
			
		||||
			.ITLBWriteF,
 | 
			
		||||
			.WalkerInstrPageFaultF,
 | 
			
		||||
			.ExceptionM,
 | 
			
		||||
			.PendingInterruptM,
 | 
			
		||||
			.InstrAckF,
 | 
			
		||||
			.InstrReadF,
 | 
			
		||||
			.hit,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								wally-pipelined/src/cache/icachefsm.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								wally-pipelined/src/cache/icachefsm.sv
									
									
									
									
										vendored
									
									
								
							@ -36,6 +36,8 @@ module icachefsm
 | 
			
		||||
   input logic 	      ITLBWriteF,
 | 
			
		||||
   input logic 	      WalkerInstrPageFaultF,
 | 
			
		||||
 | 
			
		||||
   input logic ExceptionM, PendingInterruptM,
 | 
			
		||||
 | 
			
		||||
   // BUS interface
 | 
			
		||||
   input logic 	      InstrAckF,
 | 
			
		||||
 | 
			
		||||
@ -135,7 +137,7 @@ module icachefsm
 | 
			
		||||
      STATE_READY: begin
 | 
			
		||||
        SelAdr = 2'b00;
 | 
			
		||||
        ICacheReadEn = 1'b1;
 | 
			
		||||
        if (ITLBMissF) begin
 | 
			
		||||
        if (ITLBMissF & ~(ExceptionM | PendingInterruptM)) begin
 | 
			
		||||
          NextState = STATE_TLB_MISS;
 | 
			
		||||
        end else if (hit & ~spill) begin
 | 
			
		||||
          ICacheStallF = 1'b0;
 | 
			
		||||
 | 
			
		||||
@ -27,60 +27,62 @@
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module ifu (
 | 
			
		||||
  input logic                  clk, reset,
 | 
			
		||||
  input logic                  StallF, StallD, StallE, StallM, StallW,
 | 
			
		||||
  input logic                  FlushF, FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
  input logic 		      clk, reset,
 | 
			
		||||
  input logic 		      StallF, StallD, StallE, StallM, StallW,
 | 
			
		||||
  input logic 		      FlushF, FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
  // Fetch
 | 
			
		||||
  input logic [`XLEN-1:0]      InstrInF,
 | 
			
		||||
  input logic                  InstrAckF,
 | 
			
		||||
  output logic [`XLEN-1:0]     PCF, 
 | 
			
		||||
  output logic [`PA_BITS-1:0]  InstrPAdrF,
 | 
			
		||||
  output logic                 InstrReadF,
 | 
			
		||||
  output logic                 ICacheStallF,
 | 
			
		||||
  input logic [`XLEN-1:0]     InstrInF,
 | 
			
		||||
  input logic 		      InstrAckF,
 | 
			
		||||
  output logic [`XLEN-1:0]    PCF, 
 | 
			
		||||
  output logic [`PA_BITS-1:0] InstrPAdrF,
 | 
			
		||||
  output logic 		      InstrReadF,
 | 
			
		||||
  output logic 		      ICacheStallF,
 | 
			
		||||
  // Execute
 | 
			
		||||
  output logic [`XLEN-1:0]     PCLinkE,
 | 
			
		||||
  input logic                  PCSrcE, 
 | 
			
		||||
  input logic [`XLEN-1:0]      PCTargetE,
 | 
			
		||||
  output logic [`XLEN-1:0]     PCE,
 | 
			
		||||
  output logic                 BPPredWrongE, 
 | 
			
		||||
  output logic [`XLEN-1:0]    PCLinkE,
 | 
			
		||||
  input logic 		      PCSrcE, 
 | 
			
		||||
  input logic [`XLEN-1:0]     PCTargetE,
 | 
			
		||||
  output logic [`XLEN-1:0]    PCE,
 | 
			
		||||
  output logic 		      BPPredWrongE, 
 | 
			
		||||
  // Mem
 | 
			
		||||
  input logic                  RetM, TrapM, 
 | 
			
		||||
  input logic [`XLEN-1:0]      PrivilegedNextPCM, 
 | 
			
		||||
  input logic                  InvalidateICacheM,
 | 
			
		||||
  output logic [31:0]          InstrD, InstrM, 
 | 
			
		||||
  output logic [`XLEN-1:0]     PCM, 
 | 
			
		||||
  output logic [4:0]           InstrClassM,
 | 
			
		||||
  output logic                 BPPredDirWrongM,
 | 
			
		||||
  output logic                 BTBPredPCWrongM,
 | 
			
		||||
  output logic                 RASPredPCWrongM,
 | 
			
		||||
  output logic                 BPPredClassNonCFIWrongM,
 | 
			
		||||
  input logic 		      RetM, TrapM, 
 | 
			
		||||
  input logic [`XLEN-1:0]     PrivilegedNextPCM, 
 | 
			
		||||
  input logic 		      InvalidateICacheM,
 | 
			
		||||
  output logic [31:0] 	      InstrD, InstrM, 
 | 
			
		||||
  output logic [`XLEN-1:0]    PCM, 
 | 
			
		||||
  output logic [4:0] 	      InstrClassM,
 | 
			
		||||
  output logic 		      BPPredDirWrongM,
 | 
			
		||||
  output logic 		      BTBPredPCWrongM,
 | 
			
		||||
  output logic 		      RASPredPCWrongM,
 | 
			
		||||
  output logic 		      BPPredClassNonCFIWrongM,
 | 
			
		||||
  // Writeback
 | 
			
		||||
  // output logic [`XLEN-1:0] PCLinkW,
 | 
			
		||||
  // Faults
 | 
			
		||||
  input logic                  IllegalBaseInstrFaultD,
 | 
			
		||||
  output logic                 ITLBInstrPageFaultF,
 | 
			
		||||
  output logic                 IllegalIEUInstrFaultD,
 | 
			
		||||
  output logic                 InstrMisalignedFaultM,
 | 
			
		||||
  output logic [`XLEN-1:0]     InstrMisalignedAdrM,
 | 
			
		||||
  input logic 		      IllegalBaseInstrFaultD,
 | 
			
		||||
  output logic 		      ITLBInstrPageFaultF,
 | 
			
		||||
  output logic 		      IllegalIEUInstrFaultD,
 | 
			
		||||
  output logic 		      InstrMisalignedFaultM,
 | 
			
		||||
  output logic [`XLEN-1:0]    InstrMisalignedAdrM,
 | 
			
		||||
  input logic 		      ExceptionM, PendingInterruptM,
 | 
			
		||||
	    
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  // mmu management
 | 
			
		||||
  input logic [1:0]            PrivilegeModeW,
 | 
			
		||||
  input logic [`XLEN-1:0]      PTE,
 | 
			
		||||
  input logic [1:0]            PageType,
 | 
			
		||||
  input logic [`XLEN-1:0]      SATP_REGW,
 | 
			
		||||
  input logic                  STATUS_MXR, STATUS_SUM, STATUS_MPRV,
 | 
			
		||||
  input logic  [1:0]           STATUS_MPP,
 | 
			
		||||
  input logic                  ITLBWriteF, ITLBFlushF,
 | 
			
		||||
  input logic                  WalkerInstrPageFaultF,
 | 
			
		||||
  input logic [1:0] 	      PrivilegeModeW,
 | 
			
		||||
  input logic [`XLEN-1:0]     PTE,
 | 
			
		||||
  input logic [1:0] 	      PageType,
 | 
			
		||||
  input logic [`XLEN-1:0]     SATP_REGW,
 | 
			
		||||
  input logic 		      STATUS_MXR, STATUS_SUM, STATUS_MPRV,
 | 
			
		||||
  input logic [1:0] 	      STATUS_MPP,
 | 
			
		||||
  input logic 		      ITLBWriteF, ITLBFlushF,
 | 
			
		||||
  input logic 		      WalkerInstrPageFaultF,
 | 
			
		||||
 | 
			
		||||
  output logic                 ITLBMissF,
 | 
			
		||||
  output logic 		      ITLBMissF,
 | 
			
		||||
 | 
			
		||||
  // pmp/pma (inside mmu) signals.  *** temporarily from AHB bus but eventually replace with internal versions pre H
 | 
			
		||||
  input  var logic [7:0]       PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
 | 
			
		||||
  input  var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], 
 | 
			
		||||
  input 		      var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
 | 
			
		||||
  input 		      var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], 
 | 
			
		||||
 | 
			
		||||
  output logic                 InstrAccessFaultF
 | 
			
		||||
  output logic 		      InstrAccessFaultF
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0]            PCCorrectE, UnalignedPCNextF, PCNextF;
 | 
			
		||||
 | 
			
		||||
@ -134,8 +134,8 @@ module lsu
 | 
			
		||||
	    .SATP_REGW(SATP_REGW),
 | 
			
		||||
	    .PCF(PCF),
 | 
			
		||||
	    .MemAdrM(MemAdrM),
 | 
			
		||||
	    .ITLBMissF(ITLBMissF),
 | 
			
		||||
	    .DTLBMissM(DTLBMissM),
 | 
			
		||||
	    .ITLBMissF(ITLBMissF & ~PendingInterruptM),
 | 
			
		||||
	    .DTLBMissM(DTLBMissM & ~PendingInterruptM),
 | 
			
		||||
	    .MemRWM(MemRWM),
 | 
			
		||||
	    .PTE(PTE),
 | 
			
		||||
	    .PageType,
 | 
			
		||||
 | 
			
		||||
@ -159,6 +159,7 @@ module wallypipelinedhart (
 | 
			
		||||
    .StallF, .StallD, .StallE, .StallM, .StallW,
 | 
			
		||||
    .FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
 | 
			
		||||
 | 
			
		||||
    .ExceptionM, .PendingInterruptM,
 | 
			
		||||
    // Fetch
 | 
			
		||||
    .InstrInF(InstrRData), .InstrAckF, .PCF, .InstrPAdrF,
 | 
			
		||||
    .InstrReadF, .ICacheStallF,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user