CMOZ now implemented in the D cache.

This commit is contained in:
Ross Thompson 2023-08-17 12:46:40 -05:00
parent e74e4f3a60
commit 6a8a82d9e8
3 changed files with 29 additions and 14 deletions

16
src/cache/cache.sv vendored
View File

@ -98,7 +98,8 @@ module cache import cvw::*; #(parameter cvw_t P,
logic CacheEn;
logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
logic ZeroCacheLine;
logic [LINELEN-1:0] PreLineWriteData;
genvar index;
/////////////////////////////////////////////////////////////////////////////////////////////
@ -116,7 +117,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, .CacheSet, .PAdr, .LineWriteData, .LineByteMask,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .ZeroCacheLine, .SelWriteback, .VictimWay,
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches
@ -160,6 +161,11 @@ module cache import cvw::*; #(parameter cvw_t P,
/////////////////////////////////////////////////////////////////////////////////////////////
// Write Path
/////////////////////////////////////////////////////////////////////////////////////////////
if(P.ZICBOZ_SUPPORTED) begin : cboz_supported
mux2 #(LINELEN) WriteDataMux(FetchBuffer, '0, ZeroCacheLine, PreLineWriteData);
end else begin
assign PreLineWriteData = FetchBuffer;
end
if(!READ_ONLY_CACHE) begin:WriteSelLogic
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel;
@ -174,14 +180,14 @@ module cache import cvw::*; #(parameter cvw_t P,
// Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index]), .y(LineWriteData[8*index+7:8*index]));
.d1(PreLineWriteData[8*index+7:8*index]), .s(FetchBufferByteSel[index] | ZeroCacheLine), .y(LineWriteData[8*index+7:8*index]));
end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end
else
begin:WriteSelLogic
// No need for this mux if the cache does not handle writes.
assign LineWriteData = FetchBuffer;
assign LineWriteData = PreLineWriteData;
assign LineByteMask = '1;
end
@ -216,7 +222,7 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .CacheAtomic, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn);

14
src/cache/cachefsm.sv vendored
View File

@ -59,6 +59,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic ClearValid, // Clear the valid bit in the selected way and set
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 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
@ -113,14 +114,14 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if(AnyMiss | CMOp[2] | CMOp[3]) /* & LineDirty */NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck & ~(CMOp[2] | CMOp[3]))) NextState = STATE_WRITE_LINE;
else (CacheBusAck) /* CMOp[2] | CMOp[3] */ NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck & ~(CMOp[2] | CMOp[3])) NextState = STATE_WRITE_LINE;
else if(CacheBusAck) /* CMOp[2] | CMOp[3] */ 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[2] | CMOp[3])) NextState = STATE_READY;
STATE_WRITEBACK: if(CacheBusAck & (CMOp[2] | CMOp[3])) NextState = STATE_READY;
else 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.
@ -144,19 +145,20 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
(CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE;
assign SetValid = CurrState == STATE_WRITE_LINE | (CurrState == STATE_READY & CMOp[3]);
assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0]) |
(CurrState == STATE_WRITEBACK & CMOp[1]));
// 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) | // exclusion-tag: icache SetDirty
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOp[3])) | // exclusion-tag: icache SetDirty
(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]));
(P.ZICBOM_SUPPORTED & CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | CMOp[3]));
assign ZeroCacheLine = CurrState == STATE_READY & CMOp[3];
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty);

13
src/cache/cacheway.sv vendored
View File

@ -40,6 +40,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 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 SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
@ -75,7 +76,13 @@ module cacheway import cvw::*; #(parameter cvw_t P,
logic ClearDirtyWay;
logic SelNonHit;
logic SelData;
logic SelNotHit2;
if (P.ZICBOM_SUPPORTED) begin : cbologic
assign SelNotHit2 = SetValid & ~(ZeroCacheLine & HitWay);
end else begin : cbologic
assign SelNotHit2 = SetValid;
end
if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn;
@ -86,10 +93,10 @@ 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;
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback;
end else begin:flushlogic // no flush operation for read-only caches.
assign SelTag = VictimWay;
assign SelNonHit = SetValid;
assign SelNonHit = SelNotHit2;
end
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);