mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Finally the d$ spill works. At least until the next bug. Definitely needs a lot of cleanup.
This commit is contained in:
		
							parent
							
								
									5660eff57d
								
							
						
					
					
						commit
						13333d3e82
					
				@ -53,10 +53,13 @@ module align import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
  output logic [P.XLEN-1:0] IEUAdrSpillE,      // The next PCF for one of the two memory addresses of the spill
 | 
					  output logic [P.XLEN-1:0] IEUAdrSpillE,      // The next PCF for one of the two memory addresses of the spill
 | 
				
			||||||
  output logic [P.XLEN-1:0] IEUAdrSpillM,      // IEUAdrM for one of the two memory addresses of the spill
 | 
					  output logic [P.XLEN-1:0] IEUAdrSpillM,      // IEUAdrM for one of the two memory addresses of the spill
 | 
				
			||||||
  output logic              SelSpillE,     // During the transition between the two spill operations, the IFU should stall the pipeline
 | 
					  output logic              SelSpillE,     // During the transition between the two spill operations, the IFU should stall the pipeline
 | 
				
			||||||
  output logic [P.LLEN-1:0] DCacheReadDataWordSpillM);// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
 | 
					  output logic [1:0]        MemRWSpillM, 
 | 
				
			||||||
 | 
					  output logic              SelStoreDelay, //*** this is bad.  really don't like moving this outside
 | 
				
			||||||
 | 
					  output logic [P.LLEN-1:0] DCacheReadDataWordSpillM, // The final 32 bit instruction after merging the two spilled fetches into 1 instruction
 | 
				
			||||||
 | 
					  output logic SpillStallM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]).  Without a cache this is just PCF[1]
 | 
					  // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]).  Without a cache this is just PCF[1]
 | 
				
			||||||
  typedef enum logic [1:0]  {STATE_READY, STATE_SPILL} statetype;
 | 
					  typedef enum logic [1:0]  {STATE_READY, STATE_SPILL, STATE_STORE_DELAY} statetype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  statetype          CurrState, NextState;
 | 
					  statetype          CurrState, NextState;
 | 
				
			||||||
  logic              TakeSpillM;
 | 
					  logic              TakeSpillM;
 | 
				
			||||||
@ -74,6 +77,7 @@ module align import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  logic [(P.LLEN-1)*2/8:0] ByteMaskSaveM;
 | 
					  logic [(P.LLEN-1)*2/8:0] ByteMaskSaveM;
 | 
				
			||||||
  logic [(P.LLEN-1)*2/8:0] ByteMaskMuxM;
 | 
					  logic [(P.LLEN-1)*2/8:0] ByteMaskMuxM;
 | 
				
			||||||
 | 
					  logic                    SaveByteMask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  always_comb begin
 | 
					  always_comb begin
 | 
				
			||||||
    case(MemRWM)
 | 
					    case(MemRWM)
 | 
				
			||||||
@ -123,17 +127,23 @@ module align import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  always_comb begin
 | 
					  always_comb begin
 | 
				
			||||||
    case (CurrState)
 | 
					    case (CurrState)
 | 
				
			||||||
      STATE_READY: if (TakeSpillM)                NextState = STATE_SPILL;
 | 
					      STATE_READY: if (TakeSpillM & ~MemRWM[0])   NextState = STATE_SPILL;
 | 
				
			||||||
 | 
					                   else if(TakeSpillM & MemRWM[0])NextState = STATE_STORE_DELAY;
 | 
				
			||||||
                   else                           NextState = STATE_READY;
 | 
					                   else                           NextState = STATE_READY;
 | 
				
			||||||
      STATE_SPILL: if(StallM)                     NextState = STATE_SPILL;
 | 
					      STATE_SPILL: if(StallM)                     NextState = STATE_SPILL;
 | 
				
			||||||
                   else                           NextState = STATE_READY;
 | 
					                   else                           NextState = STATE_READY;
 | 
				
			||||||
 | 
					      STATE_STORE_DELAY: NextState = STATE_SPILL;
 | 
				
			||||||
      default:                                    NextState = STATE_READY;
 | 
					      default:                                    NextState = STATE_READY;
 | 
				
			||||||
    endcase
 | 
					    endcase
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign SelSpillM = (CurrState == STATE_SPILL);
 | 
					  assign SelSpillM = (CurrState == STATE_SPILL | CurrState == STATE_STORE_DELAY);
 | 
				
			||||||
  assign SelSpillE = (CurrState == STATE_READY & TakeSpillM) | (CurrState == STATE_SPILL & CacheBusHPWTStall);
 | 
					  assign SelSpillE = (CurrState == STATE_READY & TakeSpillM) | (CurrState == STATE_SPILL & CacheBusHPWTStall) | (CurrState == STATE_STORE_DELAY);
 | 
				
			||||||
 | 
					  assign SaveByteMask = (CurrState == STATE_READY & TakeSpillM);
 | 
				
			||||||
  assign SpillSaveM = (CurrState == STATE_READY) & TakeSpillM & ~FlushM;
 | 
					  assign SpillSaveM = (CurrState == STATE_READY) & TakeSpillM & ~FlushM;
 | 
				
			||||||
 | 
					  assign SelStoreDelay = (CurrState == STATE_STORE_DELAY);
 | 
				
			||||||
 | 
					  assign SpillStallM = SelSpillE | CurrState == STATE_STORE_DELAY;
 | 
				
			||||||
 | 
					  mux2 #(2) memrwmux(MemRWM, 2'b00, SelStoreDelay, MemRWSpillM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  // Merge spilled data
 | 
					  // Merge spilled data
 | 
				
			||||||
@ -178,6 +188,6 @@ module align import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
  mux3 #(2*P.LLEN/8) bytemaskspillmux(ByteMaskShiftedM, {{{P.LLEN/8}{1'b0}}, ByteMaskM}, 
 | 
					  mux3 #(2*P.LLEN/8) bytemaskspillmux(ByteMaskShiftedM, {{{P.LLEN/8}{1'b0}}, ByteMaskM}, 
 | 
				
			||||||
                                      {{{P.LLEN/8}{1'b0}}, ByteMaskMuxM[P.LLEN*2/8-1:P.LLEN/8]}, {SelSpillM, SelSpillE}, ByteMaskSpillM);
 | 
					                                      {{{P.LLEN/8}{1'b0}}, ByteMaskMuxM[P.LLEN*2/8-1:P.LLEN/8]}, {SelSpillM, SelSpillE}, ByteMaskSpillM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  flopenr #(P.LLEN*2/8) bytemaskreg(clk, reset, SelSpillE, {ByteMaskExtendedM, ByteMaskM}, ByteMaskSaveM);
 | 
					  flopenr #(P.LLEN*2/8) bytemaskreg(clk, reset, SaveByteMask, {ByteMaskExtendedM, ByteMaskM}, ByteMaskSaveM);
 | 
				
			||||||
  mux2 #(P.LLEN*2/8) bytemasksavemux({ByteMaskExtendedM, ByteMaskM}, ByteMaskSaveM, SelSpillM, ByteMaskMuxM);
 | 
					  mux2 #(P.LLEN*2/8) bytemasksavemux({ByteMaskExtendedM, ByteMaskM}, ByteMaskSaveM, SelSpillM, ByteMaskMuxM);
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
				
			|||||||
@ -135,6 +135,9 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
  logic [P.LLEN-1:0]     LSUWriteDataM;                          // Final write data
 | 
					  logic [P.LLEN-1:0]     LSUWriteDataM;                          // Final write data
 | 
				
			||||||
  logic [(P.LLEN-1)/8:0] ByteMaskM;                              // Selects which bytes within a word to write
 | 
					  logic [(P.LLEN-1)/8:0] ByteMaskM;                              // Selects which bytes within a word to write
 | 
				
			||||||
  logic [(P.LLEN-1)/8:0] ByteMaskExtendedM;                      // Selects which bytes within a word to write
 | 
					  logic [(P.LLEN-1)/8:0] ByteMaskExtendedM;                      // Selects which bytes within a word to write
 | 
				
			||||||
 | 
					  logic [1:0]            MemRWSpillM;
 | 
				
			||||||
 | 
					  logic                  SpillStallM;
 | 
				
			||||||
 | 
					  logic                  SelStoreDelay;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  logic                  DTLBMissM;                              // DTLB miss causes HPTW walk
 | 
					  logic                  DTLBMissM;                              // DTLB miss causes HPTW walk
 | 
				
			||||||
  logic                  DTLBWriteM;                             // Writes PTE and PageType to DTLB
 | 
					  logic                  DTLBWriteM;                             // Writes PTE and PageType to DTLB
 | 
				
			||||||
@ -157,7 +160,8 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
                     .MemRWM, .CacheableM,
 | 
					                     .MemRWM, .CacheableM,
 | 
				
			||||||
                     .DCacheReadDataWordM, .CacheBusHPWTStall, .DTLBMissM, .DataUpdateDAM,
 | 
					                     .DCacheReadDataWordM, .CacheBusHPWTStall, .DTLBMissM, .DataUpdateDAM,
 | 
				
			||||||
                     .ByteMaskM, .ByteMaskExtendedM, .LSUWriteDataM, .ByteMaskSpillM, .LSUWriteDataSpillM,
 | 
					                     .ByteMaskM, .ByteMaskExtendedM, .LSUWriteDataM, .ByteMaskSpillM, .LSUWriteDataSpillM,
 | 
				
			||||||
                     .IEUAdrSpillE, .IEUAdrSpillM, .SelSpillE, .DCacheReadDataWordSpillM);
 | 
					                     .IEUAdrSpillE, .IEUAdrSpillM, .SelSpillE, .MemRWSpillM, .DCacheReadDataWordSpillM, .SpillStallM,
 | 
				
			||||||
 | 
					                     .SelStoreDelay);
 | 
				
			||||||
    assign IEUAdrExtM = {2'b00, IEUAdrSpillM}; 
 | 
					    assign IEUAdrExtM = {2'b00, IEUAdrSpillM}; 
 | 
				
			||||||
    assign IEUAdrExtE = {2'b00, IEUAdrSpillE};
 | 
					    assign IEUAdrExtE = {2'b00, IEUAdrSpillE};
 | 
				
			||||||
  end else begin : no_ziccslm_align
 | 
					  end else begin : no_ziccslm_align
 | 
				
			||||||
@ -167,6 +171,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
    assign DCacheReadDataWordSpillM = DCacheReadDataWordM;
 | 
					    assign DCacheReadDataWordSpillM = DCacheReadDataWordM;
 | 
				
			||||||
    assign ByteMaskSpillM = ByteMaskM;
 | 
					    assign ByteMaskSpillM = ByteMaskM;
 | 
				
			||||||
    assign LSUWriteDataSpillM = LSUWriteDataM;
 | 
					    assign LSUWriteDataSpillM = LSUWriteDataM;
 | 
				
			||||||
 | 
					    assign MemRWSpillM = MemRWM;
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -205,7 +210,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
  assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
 | 
					  assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
 | 
				
			||||||
  assign GatedStallW = StallW & ~SelHPTW;
 | 
					  assign GatedStallW = StallW & ~SelHPTW;
 | 
				
			||||||
  assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall;
 | 
					  assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall;
 | 
				
			||||||
  assign LSUStallM = CacheBusHPWTStall | SelSpillE;
 | 
					  assign LSUStallM = CacheBusHPWTStall | SpillStallM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  // MMU and misalignment fault logic required if privileged unit exists
 | 
					  // MMU and misalignment fault logic required if privileged unit exists
 | 
				
			||||||
@ -297,7 +302,7 @@ module lsu import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
      
 | 
					      
 | 
				
			||||||
      cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN),
 | 
					      cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN),
 | 
				
			||||||
              .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(CACHEWORDLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache(
 | 
					              .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(CACHEWORDLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache(
 | 
				
			||||||
        .clk, .reset, .Stall(GatedStallW & ~SelSpillE), .SelBusBeat, .FlushStage(FlushW | IgnoreRequestTLB), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM),
 | 
					        .clk, .reset, .Stall(GatedStallW & ~SelSpillE), .SelBusBeat, .FlushStage(FlushW | IgnoreRequestTLB), .CacheRW(SelStoreDelay ? 2'b00 : CacheRWM), .CacheAtomic(CacheAtomicM),
 | 
				
			||||||
        .FlushCache(FlushDCache), .NextSet(IEUAdrExtE[11:0]), .PAdr(PAdrM), 
 | 
					        .FlushCache(FlushDCache), .NextSet(IEUAdrExtE[11:0]), .PAdr(PAdrM), 
 | 
				
			||||||
        .ByteMask(ByteMaskSpillM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
 | 
					        .ByteMask(ByteMaskSpillM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
 | 
				
			||||||
        .CacheWriteData(LSUWriteDataSpillM), .SelHPTW,
 | 
					        .CacheWriteData(LSUWriteDataSpillM), .SelHPTW,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user