Updated the cache for book clarity.

This commit is contained in:
Rose Thompson 2024-02-28 17:07:32 -06:00
parent 252ca5b925
commit 90ad5e7dab
3 changed files with 49 additions and 52 deletions

6
src/cache/cache.sv vendored
View File

@ -98,7 +98,7 @@ module cache import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic SelFetchBuffer;
logic CacheEn;
logic SelWay;
logic SelVictim;
logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
genvar index;
@ -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, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelWay,
.clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelVictim,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay,
.FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache);
@ -227,7 +227,7 @@ module cache import cvw::*; #(parameter cvw_t P,
cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay,
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelVictim,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,

62
src/cache/cachefsm.sv vendored
View File

@ -63,7 +63,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic ClearDirty, // Clear the dirty bit in the selected way and set
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 SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
output logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
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
@ -79,12 +79,12 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
logic CMOZeroNoEviction;
logic StallConditions;
typedef enum logic [3:0]{STATE_READY, // hit states
typedef enum logic [3:0]{STATE_HIT, // hit states
// miss states
STATE_FETCH,
STATE_WRITEBACK,
STATE_WRITE_LINE,
STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM
STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writting SRAM
// flush cache
STATE_FLUSH,
STATE_FLUSH_WRITEBACK
@ -101,51 +101,51 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
// outputs for the performance counters.
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_HIT & ~Stall & ~FlushStage) | (CurrState == STATE_ADDRESS_SETUP & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit;
// special case on reset. When the fsm first exists reset the
// special case on reset. When the fsm first exists reset twayhe
// PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector.
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
always_ff @(posedge clk)
if (reset | FlushStage) CurrState <= #1 STATE_READY;
if (reset | FlushStage) CurrState <= #1 STATE_HIT;
else CurrState <= #1 NextState;
always_comb begin
NextState = STATE_READY;
NextState = STATE_HIT;
case (CurrState) // exclusion-tag: icache state-case
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
STATE_HIT: if(InvalidateCache) NextState = STATE_HIT; // exclusion-tag: dcache InvalidateCheck
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; // exclusion-tag: icache FLUSHStatement
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if((AnyMiss | CMOWriteback) & ~READ_ONLY_CACHE) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else NextState = STATE_READY;
else NextState = STATE_HIT;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY;
STATE_WRITE_LINE: NextState = STATE_ADDRESS_SETUP;
STATE_ADDRESS_SETUP: if(Stall) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_HIT;
// exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall
else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP; // Read_hold lowers CacheStall
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;
else if (FlushFlag) NextState = STATE_READ_HOLD;
else if (FlushFlag) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_FLUSH;
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
else if(CacheBusAck) NextState = STATE_READ_HOLD;
else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP;
else NextState = STATE_FLUSH_WRITEBACK;
// exclusion-tag-end: icache case
default: NextState = STATE_READY;
default: NextState = STATE_HIT;
endcase
end
// com back to CPU
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD));
assign CacheCommitted = (CurrState != STATE_HIT) & ~(READ_ONLY_CACHE & (CurrState == STATE_ADDRESS_SETUP));
assign StallConditions = FlushCache | AnyMiss | CMOWriteback; // exclusion-tag: icache FlushCache
assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates
assign CacheStall = (CurrState == STATE_HIT & StallConditions) | // 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.
@ -153,26 +153,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
(CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE |
(CurrState == STATE_READY & CMOZeroNoEviction) |
(CurrState == STATE_HIT & CMOZeroNoEviction) |
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
assign ClearValid = (CurrState == STATE_HIT & CMOpM[0]) |
(CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
assign LRUWriteEn = (((CurrState == STATE_HIT & (AnyHit | CMOZeroNoEviction)) |
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
// exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty
assign SetDirty = (CurrState == STATE_HIT & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
(CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
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
CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) |
assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
(CurrState == STATE_HIT & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) |
(CurrState == STATE_WRITE_LINE);
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty);
(CurrState == STATE_HIT & AnyMiss & LineDirty);
// coverage off -item e 1 -fecexprrow 1
// (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck)
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
@ -183,29 +183,29 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
(CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck);
// exclusion-tag-end: icache flushdirtycontrols
// Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
assign CacheBusRW[1] = (CurrState == STATE_HIT & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
logic LoadMiss;
assign LoadMiss = (CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
assign CacheBusRW[0] = (CurrState == STATE_HIT & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck);
assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
assign SelAdrData = (CurrState == STATE_HIT & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) |
resetDelay;
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed
assign SelAdrTag = (CurrState == STATE_HIT & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed
(CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) |
resetDelay;
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_ADDRESS_SETUP;
assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_HIT) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
endmodule // cachefsm

33
src/cache/cacheway.sv vendored
View File

@ -42,7 +42,7 @@ 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 SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
input logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit
input logic ClearDirty, // Clear the dirty bit in the selected way and set
input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
input logic VictimWay, // LRU selected this way as victim to evict
@ -68,7 +68,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLine;
logic [TAGLEN-1:0] ReadTag;
logic Dirty;
logic SelDirty;
logic SelecteDirty;
logic SelectedWriteWordEn;
logic [LINELEN/8-1:0] FinalByteMask;
logic SetValidEN, ClearValidEN;
@ -77,33 +77,30 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic SetDirtyWay;
logic ClearDirtyWay;
logic SelNonHit;
logic SelData;
logic SelectedWay;
logic InvalidateCacheDelay;
if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn;
mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelDirty);
mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelecteDirty);
mux3 #(1) selectedmux(HitWay, FlushWay, VictimWay, {SelVictim, FlushCache}, SelectedWay);
// 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 FlushCache=0 while FlushWay=1 since FlushWay only advances on a subset of FlushCache assertion cases.
assign FlushWayEn = FlushWay & FlushCache;
assign SelNonHit = FlushWayEn | SelWay;
end else begin:flushlogic // no flush operation for read-only caches.
assign SelDirty = VictimWay;
assign SelNonHit = SelWay;
assign SelecteDirty = VictimWay;
mux2 #(1) selectedwaymux(HitWay, SelecteDirty, SelVictim , SelectedWay);
end
mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData);
/////////////////////////////////////////////////////////////////////////////////////////////
// Write Enable demux
/////////////////////////////////////////////////////////////////////////////////////////////
assign SetValidWay = SetValid & SelData;
assign ClearValidWay = ClearValid & SelData; // exclusion-tag: icache ClearValidWay
assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay
assign ClearDirtyWay = ClearDirty & SelData;
assign SetValidWay = SetValid & SelectedWay;
assign ClearValidWay = ClearValid & SelectedWay; // exclusion-tag: icache ClearValidWay
assign SetDirtyWay = SetDirty & SelectedWay; // exclusion-tag: icache SetDirtyWay
assign ClearDirtyWay = ClearDirty & SelectedWay;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN
assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache ClearValidEN
@ -120,9 +117,9 @@ 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 = SelData ? ReadTag : '0; // AND part of AOMux
assign TagWay = SelectedWay ? ReadTag : '0; // AND part of AOMux
assign HitDirtyWay = Dirty & ValidWay;
assign DirtyWay = SelDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay
assign DirtyWay = SelecteDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay
flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay);
@ -152,7 +149,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
end
// AND portion of distributed read multiplexers
assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux.
assign ReadDataLineWay = SelectedWay ? ReadDataLine : '0; // AND part of AO mux.
/////////////////////////////////////////////////////////////////////////////////////////////
// Valid Bits