From 667fe035c0b9b6936aac569946601ef324477084 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 Nov 2023 17:01:43 -0600 Subject: [PATCH 1/7] Simplified CMO.Zero fsm implementation slightly. --- src/cache/cachefsm.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index b057ceaa2..e6d6a68fa 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -136,7 +136,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, else NextState = STATE_READY; // exclusion-tag-start: icache case STATE_WRITEBACK: if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH; - else if(CacheBusAck) NextState = STATE_CMO_DONE; + else if(CacheBusAck) NextState = STATE_READ_HOLD; 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; @@ -146,7 +146,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, 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; + STATE_CMO_WRITEBACK: if(CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD; else NextState = STATE_CMO_WRITEBACK; STATE_CMO_DONE: if(Stall) NextState = STATE_CMO_DONE; else NextState = STATE_READY; From 5fb3c83efc055436c44b2f98ea69ba64ca070486 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 Nov 2023 20:52:11 -0600 Subject: [PATCH 2/7] Removed the CMO_WRITEBACK state from the cache. --- src/cache/cachefsm.sv | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index e6d6a68fa..c4011981e 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -91,8 +91,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, STATE_FLUSH, STATE_FLUSH_WRITEBACK, // CMO states - STATE_CMO_WRITEBACK, - STATE_CMO_DONE + STATE_CMO_WRITEBACK } statetype; statetype CurrState, NextState; @@ -125,8 +124,8 @@ 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 | CMOZeroEviction) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement - else if(CMOWritebackHit) NextState = STATE_CMO_WRITEBACK; + else if(AnyMiss | CMOZeroEviction | CMOWritebackHit) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement + //else if(CMOWritebackHit) NextState = STATE_CMO_WRITEBACK; else NextState = STATE_READY; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; else if(CacheBusAck) NextState = STATE_READY; @@ -135,7 +134,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P, STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; else NextState = STATE_READY; // exclusion-tag-start: icache case - STATE_WRITEBACK: if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH; + STATE_WRITEBACK: if (CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD; + else if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH; else if(CacheBusAck) NextState = STATE_READ_HOLD; 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. @@ -148,29 +148,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P, STATE_CMO_WRITEBACK: if(CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD; else NextState = STATE_CMO_WRITEBACK; - STATE_CMO_DONE: if(Stall) NextState = STATE_CMO_DONE; - else NextState = STATE_READY; // 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 | CurrState == STATE_CMO_DONE)); + assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWritebackHit | CMOZeroEviction)) | // 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_CMO_WRITEBACK); + (CurrState == STATE_FLUSH_WRITEBACK); // write enables internal to cache assign CMOZeroHit = CurrState == STATE_READY & CMOp[3] & CacheHit ; assign SetValid = CurrState == STATE_WRITE_LINE | (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)); + (CurrState == STATE_WRITEBACK & CMOp[2] & CacheBusAck)); // coverage off -item e 1 -fecexprrow 8 assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) | @@ -182,7 +179,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, 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_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck); + (P.ZICBOM_SUPPORTED & CurrState == STATE_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 @@ -190,9 +187,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (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) | + assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (CurrState == STATE_READY & AnyMiss & LineDirty); - assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK; + assign SelCMOWriteback = CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]); assign SelFlush = (CurrState == STATE_READY & FlushCache) | (CurrState == STATE_FLUSH) | @@ -209,17 +206,16 @@ module cachefsm import cvw::*; #(parameter cvw_t P, // Bus interface controls assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses (CurrState == STATE_FETCH & ~CacheBusAck) | - (CurrState == STATE_WRITEBACK & CacheBusAck & ~CMOp[3]); + (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOp)); assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW (CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | - (P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck); + (P.ZICBOM_SUPPORTED & CurrState == STATE_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 From 52ac07ce8dd04e0db61a6c08a8c11244662c8716 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 Nov 2023 20:52:11 -0600 Subject: [PATCH 3/7] Removed the CMO_WRITEBACK state from the cache and unused signals. --- src/cache/cache.sv | 5 ++--- src/cache/cachefsm.sv | 36 ++++++++++++------------------------ src/cache/cacheway.sv | 1 - 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 078f6fb28..26bb44a04 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -102,7 +102,6 @@ module cache import cvw::*; #(parameter cvw_t P, logic [LINELEN/8-1:0] LineByteMask; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic ZeroCacheLine; - logic CMOZeroHit; logic [LINELEN-1:0] PreLineWriteData; genvar index; @@ -121,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, .SelWay, - .SetValid, .ClearValid, .SetDirty, .ClearDirty, .CMOZeroHit, .SelWriteback, .SelCMOWriteback, .VictimWay, + .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .SelCMOWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); // Select victim way for associative caches @@ -233,7 +232,7 @@ module cache import cvw::*; #(parameter cvw_t P, .FlushStage, .CacheRW, .CacheAtomic, .Stall, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheMiss, .CacheAccess, .SelAdr, .SelWay, - .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .CMOZeroHit, .SelWriteback, .SelCMOWriteback, .SelFlush, + .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .SelFlush, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index e6d6a68fa..7a55658e7 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -60,7 +60,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P, output logic SetDirty, // Set the dirty bit in the selected way and set 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 CMOZeroHit, // CMOZ hit 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 @@ -89,10 +88,7 @@ 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, - // CMO states - STATE_CMO_WRITEBACK, - STATE_CMO_DONE + STATE_FLUSH_WRITEBACK } statetype; statetype CurrState, NextState; @@ -125,8 +121,7 @@ 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 | CMOZeroEviction) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement - else if(CMOWritebackHit) NextState = STATE_CMO_WRITEBACK; + else if(AnyMiss | CMOZeroEviction | CMOWritebackHit) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement else NextState = STATE_READY; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; else if(CacheBusAck) NextState = STATE_READY; @@ -135,7 +130,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P, STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; else NextState = STATE_READY; // exclusion-tag-start: icache case - STATE_WRITEBACK: if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH; + STATE_WRITEBACK: if (CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD; + else if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH; else if(CacheBusAck) NextState = STATE_READ_HOLD; 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. @@ -145,32 +141,25 @@ 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_READ_HOLD; - else NextState = STATE_CMO_WRITEBACK; - STATE_CMO_DONE: if(Stall) NextState = STATE_CMO_DONE; - else NextState = STATE_READY; // 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 | CurrState == STATE_CMO_DONE)); + assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWritebackHit | CMOZeroEviction)) | // 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_CMO_WRITEBACK); + (CurrState == STATE_FLUSH_WRITEBACK); // write enables internal to cache - assign CMOZeroHit = CurrState == STATE_READY & CMOp[3] & CacheHit ; assign SetValid = CurrState == STATE_WRITE_LINE | (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)); + (CurrState == STATE_WRITEBACK & CMOp[2] & CacheBusAck)); // coverage off -item e 1 -fecexprrow 8 assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) | @@ -182,7 +171,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, 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_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck); + (P.ZICBOM_SUPPORTED & CurrState == STATE_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 @@ -190,9 +179,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (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) | + assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (CurrState == STATE_READY & AnyMiss & LineDirty); - assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK; + assign SelCMOWriteback = CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]); assign SelFlush = (CurrState == STATE_READY & FlushCache) | (CurrState == STATE_FLUSH) | @@ -209,17 +198,16 @@ module cachefsm import cvw::*; #(parameter cvw_t P, // Bus interface controls assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses (CurrState == STATE_FETCH & ~CacheBusAck) | - (CurrState == STATE_WRITEBACK & CacheBusAck & ~CMOp[3]); + (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOp)); assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW (CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | - (P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck); + (P.ZICBOM_SUPPORTED & CurrState == STATE_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 diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index ef53beab5..991915637 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -42,7 +42,6 @@ module cacheway import cvw::*; #(parameter cvw_t P, 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 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 From 70eb110a9ce094e532c39c019f6e9050b0ef7f91 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 Nov 2023 22:13:31 -0600 Subject: [PATCH 4/7] More optimizations to simplify cmo logic. --- src/cache/cache.sv | 5 ++--- src/cache/cachefsm.sv | 10 +++++----- src/cache/cacheway.sv | 2 -- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 26bb44a04..152b8d7f4 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -120,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, .SelWay, - .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .SelCMOWriteback, .VictimWay, + .SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); // Select victim way for associative caches @@ -156,11 +156,10 @@ 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, SelBothWriteback}), .y(CacheBusAdr)); + .s({SelFlush, SelWriteback}), .y(CacheBusAdr)); ///////////////////////////////////////////////////////////////////////////////////////////// // Write Path diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 7a55658e7..28cdb5d93 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -172,17 +172,17 @@ 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_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck); - assign SelWay = SelWriteback | (CurrState == STATE_WRITE_LINE) | + assign SelWay = (CurrState == STATE_WRITEBACK & ~CacheBusAck & ~(CMOp[1] | CMOp[2])) | + (CurrState == STATE_READY & AnyMiss & LineDirty) | + (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 & ~(CMOp[1] | CMOp[2])) | - (CurrState == STATE_READY & AnyMiss & LineDirty); - assign SelCMOWriteback = CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]); - + assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) | + (CurrState == STATE_READY & AnyMiss & LineDirty); assign SelFlush = (CurrState == STATE_READY & FlushCache) | (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_WRITEBACK); diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 991915637..efd338b65 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -43,8 +43,6 @@ module cacheway import cvw::*; #(parameter cvw_t P, input logic SetDirty, // Set the dirty bit in the selected way and set input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway 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 From d2a747bf3d2d03be730c07ab71a233f9e489a99a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 20 Nov 2023 23:59:40 -0600 Subject: [PATCH 5/7] cleanup. --- src/cache/cache.sv | 4 +--- src/cache/cachefsm.sv | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 152b8d7f4..72fdf9a0b 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -90,8 +90,6 @@ 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; @@ -231,7 +229,7 @@ module cache import cvw::*; #(parameter cvw_t P, .FlushStage, .CacheRW, .CacheAtomic, .Stall, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheMiss, .CacheAccess, .SelAdr, .SelWay, - .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .SelFlush, + .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 28cdb5d93..edb87f29a 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -61,7 +61,6 @@ 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 SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway From 1d811b085c8c03194e8d6b04ed5e1df051ef8093 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 Nov 2023 00:14:59 -0600 Subject: [PATCH 6/7] More cleanup. --- src/cache/cachefsm.sv | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index edb87f29a..e507f1daa 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -171,13 +171,9 @@ 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_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck); - assign SelWay = (CurrState == STATE_WRITEBACK & ~CacheBusAck & ~(CMOp[1] | CMOp[2])) | - (CurrState == STATE_READY & AnyMiss & LineDirty) | - (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 SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (P.ZICBOZ_SUPPORTED & CacheBusAck & CMOp[3]))) | + (CurrState == STATE_READY & ((AnyMiss & LineDirty) | (P.ZICBOZ_SUPPORTED & CMOZeroNoEviction & ~CacheHit))) | + (CurrState == STATE_WRITE_LINE); assign ZeroCacheLine = P.ZICBOZ_SUPPORTED & ((CurrState == STATE_READY & CMOZeroNoEviction) | (CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck))); assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) | From 1acc3951c8916f84a06959d1398ccc8f443752c2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 Nov 2023 00:19:24 -0600 Subject: [PATCH 7/7] More simplifications. --- src/cache/cachefsm.sv | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index e507f1daa..564ac12df 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -76,6 +76,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, logic AnyMiss; logic FlushFlag; logic CMOWritebackHit; + logic CMOWriteback; logic CMOZeroNoEviction; logic CMOZeroEviction; @@ -98,6 +99,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit; assign CMOZeroNoEviction = CMOp[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now assign CMOZeroEviction = CMOp[3] & LineDirty; // (hit or miss) with writeback dirty line + assign CMOWriteback = CMOWritebackHit | CMOZeroEviction; assign FlushFlag = FlushAdrFlag & FlushWayFlag; @@ -120,7 +122,7 @@ 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 | CMOZeroEviction | CMOWritebackHit) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement + else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement else NextState = STATE_READY; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; else if(CacheBusAck) NextState = STATE_READY; @@ -147,7 +149,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, // com back to CPU assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); - assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWritebackHit | CMOZeroEviction)) | // exclusion-tag: icache StallStates + assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWriteback)) | // 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.