mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Might have working cbo clean and flush instructions.
This commit is contained in:
		
							parent
							
								
									8c7eafffad
								
							
						
					
					
						commit
						b842fdb863
					
				
							
								
								
									
										11
									
								
								src/cache/cache.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								src/cache/cache.sv
									
									
									
									
										vendored
									
									
								
							| @ -90,6 +90,8 @@ module cache import cvw::*; #(parameter cvw_t P, | ||||
|   logic [NUMWAYS-1:0]            FlushWay, NextFlushWay; | ||||
|   logic                          FlushWayCntEn; | ||||
|   logic                          SelWriteback; | ||||
|   logic                          SelCMOWriteback; | ||||
|   logic                          SelBothWriteback; | ||||
|   logic                          LRUWriteEn; | ||||
|   logic                          SelFlush; | ||||
|   logic                          ResetOrFlushCntRst; | ||||
| @ -116,8 +118,8 @@ module cache import cvw::*; #(parameter cvw_t P, | ||||
| 
 | ||||
|   // Array of cache ways, along with victim, hit, dirty, and read merging logic
 | ||||
|   cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( | ||||
|     .clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, | ||||
|     .SetValid, .ClearValid, .SetDirty, .ClearDirty, .ZeroCacheLine, .SelWriteback, .VictimWay, | ||||
|     .clk, .reset, .CacheEn, .CMOp, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, | ||||
|     .SetValid, .ClearValid, .SetDirty, .ClearDirty, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .VictimWay, | ||||
|     .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); | ||||
| 
 | ||||
|   // Select victim way for associative caches
 | ||||
| @ -153,10 +155,11 @@ module cache import cvw::*; #(parameter cvw_t P, | ||||
|     .PAdr(WordOffsetAddr), .ReadDataLine, .ReadDataWord); | ||||
|    | ||||
|   // Bus address for fetch, writeback, or flush writeback
 | ||||
|   assign SelBothWriteback = SelWriteback | SelCMOWriteback; | ||||
|   mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), | ||||
|     .d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), | ||||
|     .d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}), | ||||
|     .s({SelFlush, SelWriteback}), .y(CacheBusAdr)); | ||||
|     .s({SelFlush, SelBothWriteback}), .y(CacheBusAdr)); | ||||
|    | ||||
|   /////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|   // Write Path
 | ||||
| @ -222,7 +225,7 @@ module cache import cvw::*; #(parameter cvw_t P, | ||||
|     .FlushStage, .CacheRW, .CacheAtomic, .Stall, | ||||
|     .CacheHit, .LineDirty, .CacheStall, .CacheCommitted,  | ||||
|     .CacheMiss, .CacheAccess, .SelAdr,  | ||||
|     .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush, | ||||
|     .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .SelFlush, | ||||
|     .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, | ||||
|     .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, | ||||
|     .InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); | ||||
|  | ||||
							
								
								
									
										43
									
								
								src/cache/cachefsm.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								src/cache/cachefsm.sv
									
									
									
									
										vendored
									
									
								
							| @ -61,6 +61,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, | ||||
|   output logic       ClearDirty,        // Clear the dirty bit in the selected way and set
 | ||||
|   output logic       ZeroCacheLine,     // Write zeros to all bytes of cacheline
 | ||||
|   output logic       SelWriteback,      // Overrides cached tag check to select a specific way and set for writeback
 | ||||
|   output logic       SelCMOWriteback,   // Overrides cached tag check to select a specific way and set for writeback for both data and tag
 | ||||
|   output logic       LRUWriteEn,        // Update the LRU state
 | ||||
|   output logic       SelFlush,          // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
 | ||||
|   output logic       FlushAdrCntEn,     // Enable the counter for Flush Adr
 | ||||
| @ -83,7 +84,11 @@ module cachefsm import cvw::*; #(parameter cvw_t P, | ||||
|                            STATE_READ_HOLD,  // required for back to back reads. structural hazard on writting SRAM
 | ||||
|                            // flush cache 
 | ||||
|                            STATE_FLUSH, | ||||
|                            STATE_FLUSH_WRITEBACK} statetype; | ||||
|                            STATE_FLUSH_WRITEBACK, | ||||
|                            // CMO states
 | ||||
|                            STATE_CMO_WRITEBACK, | ||||
|                            STATE_CMO_DONE | ||||
|                            } statetype; | ||||
| 
 | ||||
|   statetype CurrState, NextState; | ||||
| 
 | ||||
| @ -112,17 +117,17 @@ module cachefsm import cvw::*; #(parameter cvw_t P, | ||||
|       STATE_READY:           if(InvalidateCache)                               NextState = STATE_READY;     // exclusion-tag: dcache InvalidateCheck
 | ||||
|                              else if(FlushCache & ~READ_ONLY_CACHE)            NextState = STATE_FLUSH; | ||||
|                              else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH;     // exclusion-tag: icache FETCHStatement
 | ||||
|                              else if(AnyMiss | CMOp[1] | CMOp[2]) /* & LineDirty */NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
 | ||||
|                              else if(AnyMiss) /* & LineDirty */                NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
 | ||||
|                              else if((CMOp[1] | CMOp[2]) & CacheHit)           NextState = STATE_CMO_WRITEBACK;  | ||||
|                              else                                              NextState = STATE_READY; | ||||
|       STATE_FETCH:           if(CacheBusAck & ~(CMOp[1] | CMOp[2]))            NextState = STATE_WRITE_LINE; | ||||
|                              else if(CacheBusAck) /* CMOp[1] | CMOp[2] */      NextState = STATE_READY; | ||||
|       STATE_FETCH:           if(CacheBusAck)                                   NextState = STATE_WRITE_LINE; | ||||
|                              else if(CacheBusAck)                              NextState = STATE_READY; | ||||
|                              else                                              NextState = STATE_FETCH; | ||||
|       STATE_WRITE_LINE:                                                        NextState = STATE_READ_HOLD; | ||||
|       STATE_READ_HOLD:       if(Stall)                                         NextState = STATE_READ_HOLD; | ||||
|                              else                                              NextState = STATE_READY; | ||||
|       // exclusion-tag-start: icache case
 | ||||
|       STATE_WRITEBACK:       if(CacheBusAck & (CMOp[1] | CMOp[2]))             NextState = STATE_READ_HOLD; | ||||
|                              else if(CacheBusAck)                              NextState = STATE_FETCH; | ||||
|       STATE_WRITEBACK:       if(CacheBusAck)                                   NextState = STATE_FETCH; | ||||
|                              else                                              NextState = STATE_WRITEBACK; | ||||
|       // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
 | ||||
|       STATE_FLUSH:           if(LineDirty)                                     NextState = STATE_FLUSH_WRITEBACK; | ||||
| @ -131,36 +136,42 @@ module cachefsm import cvw::*; #(parameter cvw_t P, | ||||
|       STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag)                      NextState = STATE_FLUSH; | ||||
|                              else if(CacheBusAck)                              NextState = STATE_READ_HOLD; | ||||
|                              else                                              NextState = STATE_FLUSH_WRITEBACK; | ||||
| 
 | ||||
|       STATE_CMO_WRITEBACK:   if(CacheBusAck & (CMOp[1] | CMOp[2]))             NextState = STATE_CMO_DONE; | ||||
|                              else                                              NextState = STATE_CMO_WRITEBACK; | ||||
|       // exclusion-tag-end: icache case
 | ||||
|       default:                                                                 NextState = STATE_READY; | ||||
|     endcase | ||||
|   end | ||||
| 
 | ||||
|   // com back to CPU
 | ||||
|   assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & CurrState == STATE_READ_HOLD); | ||||
|   assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD | CurrState == STATE_CMO_DONE)); | ||||
|   assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOp[1] | CMOp[2])) | // exclusion-tag: icache StallStates
 | ||||
|                       (CurrState == STATE_FETCH) | | ||||
|                       (CurrState == STATE_WRITEBACK) | | ||||
|                       (CurrState == STATE_WRITE_LINE) |  // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write.
 | ||||
|                       (CurrState == STATE_FLUSH) | | ||||
|                       (CurrState == STATE_FLUSH_WRITEBACK); | ||||
|                       (CurrState == STATE_FLUSH_WRITEBACK) | | ||||
|                       (CurrState == STATE_CMO_WRITEBACK); | ||||
|   // write enables internal to cache
 | ||||
|   assign SetValid = CurrState == STATE_WRITE_LINE | (CurrState == STATE_READY & CMOp[3]); | ||||
|   assign SetValid = CurrState == STATE_WRITE_LINE |  | ||||
|                     (CurrState == STATE_READY & CMOp[3]); // *** RT: NOT completely right has to be a hit
 | ||||
|   assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0]) | | ||||
|                       (CurrState == STATE_WRITEBACK & CMOp[1])); | ||||
|                       (CurrState == STATE_CMO_DONE & CMOp[2])); | ||||
|   // coverage off -item e 1 -fecexprrow 8
 | ||||
|   assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) | | ||||
|                       (CurrState == STATE_WRITE_LINE) & ~FlushStage; | ||||
|   // exclusion-tag-start: icache flushdirtycontrols
 | ||||
|   assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOp[3])) |         // exclusion-tag: icache SetDirty
 | ||||
|   assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOp[3])) |         // exclusion-tag: icache SetDirty   *** NOT completely right has to be a hit for CMOp[3]
 | ||||
|                     (CurrState == STATE_WRITE_LINE & (CacheRW[0])); | ||||
|   assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) |   // exclusion-tag: icache ClearDirty
 | ||||
|                       (CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal.  Dirty must be cleared concurrently and atomically with writeback.  For single core cannot clear after writeback on bus ack and change flushadr.  Clears the wrong set.
 | ||||
|   // Flush and eviction controls
 | ||||
|                       (P.ZICBOM_SUPPORTED & CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | CMOp[3])); | ||||
|   assign ZeroCacheLine = CurrState == STATE_READY & CMOp[3]; | ||||
|                       (P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_DONE & (CMOp[1] | CMOp[2])); | ||||
|   assign ZeroCacheLine = CurrState == STATE_READY & CMOp[3];  // *** RT: NOT completely right
 | ||||
|   assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) | | ||||
|                     (CurrState == STATE_READY & AnyMiss & LineDirty); | ||||
|   assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK; | ||||
| 
 | ||||
|   assign SelFlush = (CurrState == STATE_READY & FlushCache) | | ||||
|           (CurrState == STATE_FLUSH) |  | ||||
| @ -179,13 +190,15 @@ module cachefsm import cvw::*; #(parameter cvw_t P, | ||||
|                          (CurrState == STATE_FETCH & ~CacheBusAck) |  | ||||
|                          (CurrState == STATE_WRITEBACK & CacheBusAck); | ||||
|   assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW
 | ||||
|                           (CurrState == STATE_WRITEBACK & ~CacheBusAck) | | ||||
|                      (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck); | ||||
|                          (CurrState == STATE_WRITEBACK & ~CacheBusAck) | | ||||
|                          (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | | ||||
|                          (P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck); | ||||
| 
 | ||||
|   assign SelAdr = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
 | ||||
|                   (CurrState == STATE_FETCH) | | ||||
|                   (CurrState == STATE_WRITEBACK) | | ||||
|                   (CurrState == STATE_WRITE_LINE) | | ||||
|                   (CurrState == STATE_CMO_WRITEBACK) | | ||||
|                   resetDelay; | ||||
|   assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD; | ||||
|   assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								src/cache/cacheway.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								src/cache/cacheway.sv
									
									
									
									
										vendored
									
									
								
							| @ -33,6 +33,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, | ||||
|   input  logic                        clk, | ||||
|   input  logic                        reset, | ||||
|   input  logic                        FlushStage,     // Pipeline flush of second stage (prevent writes and bus operations)
 | ||||
|   input  logic [3:0]                  CMOp,           // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
 | ||||
|   input  logic                        CacheEn,        // Enable the cache memory arrays.  Disable hold read data constant
 | ||||
|   input  logic [$clog2(NUMLINES)-1:0] CacheSet,       // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
 | ||||
|   input  logic [PA_BITS-1:0]          PAdr,           // Physical address 
 | ||||
| @ -43,6 +44,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, | ||||
|   input  logic                        ZeroCacheLine,  // Write zeros to all bytes of a cache line
 | ||||
|   input  logic                        ClearDirty,     // Clear the dirty bit in the selected way and set
 | ||||
|   input  logic                        SelWriteback,   // Overrides cached tag check to select a specific way and set for writeback
 | ||||
|   input  logic                        SelCMOWriteback,   // Overrides cached tag check to select a specific way and set for writeback for both data and tag
 | ||||
|   input  logic                        SelFlush,       // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
 | ||||
|   input  logic                        VictimWay,      // LRU selected this way as victim to evict
 | ||||
|   input  logic                        FlushWay,       // This way is selected for flush and possible writeback if dirty
 | ||||
| @ -78,7 +80,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, | ||||
|   logic                               SelData; | ||||
|   logic                               SelNotHit2; | ||||
|    | ||||
|   if (P.ZICBOM_SUPPORTED) begin : cbologic | ||||
|   if (P.ZICBOZ_SUPPORTED) begin : cbologic | ||||
|     assign SelNotHit2 = SetValid & ~(ZeroCacheLine & HitWay); | ||||
|   end else begin : cbologic | ||||
|     assign SelNotHit2 = SetValid; | ||||
| @ -93,7 +95,9 @@ module cacheway import cvw::*; #(parameter cvw_t P, | ||||
|     // coverage off -item e 1 -fecexprrow 3
 | ||||
|     // nonzero ways will never see SelFlush=0 while FlushWay=1 since FlushWay only advances on a subset of SelFlush assertion cases.
 | ||||
|     assign FlushWayEn = FlushWay & SelFlush; | ||||
|     // *** RT: This is slopy. I should refactor to have the fsm issue two types of writeback commands
 | ||||
|     assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback; | ||||
|     //assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback;
 | ||||
|   end else begin:flushlogic // no flush operation for read-only caches.
 | ||||
|     assign SelTag = VictimWay; | ||||
|     assign SelNonHit = SelNotHit2; | ||||
| @ -124,7 +128,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, | ||||
|     .din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); | ||||
| 
 | ||||
|   // AND portion of distributed tag multiplexer
 | ||||
|   assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
 | ||||
|   assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux
 | ||||
|   assign DirtyWay = SelTag & Dirty & ValidWay; | ||||
|   assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user