Merge pull request #494 from ross144/main

CBO simplifications
This commit is contained in:
David Harris 2023-11-21 10:00:34 -08:00 committed by GitHub
commit 7f62905a71
2 changed files with 23 additions and 38 deletions

6
src/cache/cache.sv vendored
View File

@ -88,7 +88,7 @@ module cache import cvw::*; #(parameter cvw_t P,
logic FlushAdrFlag, FlushWayFlag;
logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
logic FlushWayCntEn;
logic SelBothWriteback;
logic SelWriteback;
logic LRUWriteEn;
logic SelFlush;
logic ResetOrFlushCntRst;
@ -156,7 +156,7 @@ module cache import cvw::*; #(parameter cvw_t P,
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
@ -227,7 +227,7 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .SelWay,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelBothWriteback, .SelFlush,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn);

55
src/cache/cachefsm.sv vendored
View File

@ -59,7 +59,7 @@ 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 SelBothWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
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
@ -75,10 +75,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
logic AnyMiss;
logic FlushFlag;
logic CMOWritebackHit;
logic CMOWriteback;
logic CMOZeroNoEviction;
logic CMOZeroEviction;
logic SelWriteback; // Overrides cached tag check to select a specific way and set for writeback
logic SelCMOWriteback; // Overrides cached tag check to select a specific way and set for writeback for both data and tag
typedef enum logic [3:0]{STATE_READY, // hit states
// miss states
@ -88,10 +87,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;
@ -102,6 +98,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;
@ -124,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 | 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;
@ -134,8 +130,9 @@ 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;
else if(CacheBusAck) NextState = STATE_CMO_DONE;
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.
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
@ -144,31 +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_CMO_DONE;
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 CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWritebackHit | CMOZeroEviction)) | // exclusion-tag: icache StallStates
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD));
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.
(CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_WRITEBACK) |
(CurrState == STATE_CMO_WRITEBACK);
(CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache
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) |
@ -180,19 +171,14 @@ 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);
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]);
(P.ZICBOM_SUPPORTED & CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck);
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 & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty);
assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK;
assign SelBothWriteback = SelWriteback | SelCMOWriteback;
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);
@ -208,17 +194,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