diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 23fd6163e..078f6fb28 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -98,6 +98,7 @@ module cache import cvw::*; #(parameter cvw_t P, logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic SelFetchBuffer; logic CacheEn; + logic SelWay; logic [LINELEN/8-1:0] LineByteMask; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic ZeroCacheLine; @@ -119,7 +120,7 @@ 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, .CMOp, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, + .clk, .reset, .CacheEn, .CMOp, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .SelWay, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .CMOZeroHit, .SelWriteback, .SelCMOWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); @@ -231,7 +232,7 @@ module cache import cvw::*; #(parameter cvw_t P, cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, .FlushStage, .CacheRW, .CacheAtomic, .Stall, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted, - .CacheMiss, .CacheAccess, .SelAdr, + .CacheMiss, .CacheAccess, .SelAdr, .SelWay, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .CMOZeroHit, .SelWriteback, .SelCMOWriteback, .SelFlush, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index cd35697fd..b057ceaa2 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -65,6 +65,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, 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 SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway output logic FlushAdrCntEn, // Enable the counter for Flush Adr output logic FlushWayCntEn, // Enable the way counter during a flush output logic FlushCntRst, // Reset both flush counters @@ -166,7 +167,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, // write enables internal to cache assign CMOZeroHit = CurrState == STATE_READY & CMOp[3] & CacheHit ; assign SetValid = CurrState == STATE_WRITE_LINE | - (CurrState == STATE_READY & CMOZeroNoEviction) | + (P.ZICBOZ_SUPPORTED & CurrState == STATE_READY & CMOZeroNoEviction) | (P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]); assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0] & CacheHit) | (CurrState == STATE_CMO_WRITEBACK & CMOp[2] & CacheBusAck)); @@ -182,6 +183,11 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (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_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck); + assign SelWay = SelWriteback | (CurrState == STATE_WRITE_LINE) | + // This is almost the same as setvalid, but on cachehit we don't want to select + // the nonhit way, but instead want to force this to zero + (P.ZICBOZ_SUPPORTED & CurrState == STATE_READY & CMOZeroNoEviction & ~CacheHit) | + (P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]); assign ZeroCacheLine = P.ZICBOZ_SUPPORTED & ((CurrState == STATE_READY & CMOZeroNoEviction) | (CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck))); assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) | diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index f64397070..ef53beab5 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -41,7 +41,8 @@ module cacheway import cvw::*; #(parameter cvw_t P, input logic SetValid, // Set the valid bit in the selected way and set input logic ClearValid, // Clear the valid bit in the selected way and set input logic SetDirty, // Set the dirty bit in the selected way and set - input logic CMOZeroHit, // Write zeros to all bytes of a cache line + input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway + input logic CMOZeroHit, // 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 @@ -80,30 +81,18 @@ module cacheway import cvw::*; #(parameter cvw_t P, logic SelData; logic SelNotHit2; - if (P.ZICBOZ_SUPPORTED) begin : cbologic - assign SelNotHit2 = SetValid & ~CMOZeroHit; - //assign SelNotHit2 = SetValid; - - end else begin : cbologic - assign SelNotHit2 = SetValid; - end - if (!READ_ONLY_CACHE) begin:flushlogic logic FlushWayEn; - mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag); // FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected. // 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; // *** this is not correct - - //assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback; + assign SelNonHit = FlushWayEn | SelWay; end else begin:flushlogic // no flush operation for read-only caches. assign SelTag = VictimWay; - assign SelNonHit = SelNotHit2; + assign SelNonHit = SelWay; end mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);