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 CacheEn;
logic [LINELEN/8-1:0] LineByteMask; logic [LINELEN/8-1:0] LineByteMask;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
logic ZeroCacheLine;
logic [LINELEN-1:0] PreLineWriteData;
genvar index; 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 // 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]( cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .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); .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches // Select victim way for associative caches
@ -160,6 +161,11 @@ module cache import cvw::*; #(parameter cvw_t P,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path // 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 if(!READ_ONLY_CACHE) begin:WriteSelLogic
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded; logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel; 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 // Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), 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 end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end end
else else
begin:WriteSelLogic begin:WriteSelLogic
// No need for this mux if the cache does not handle writes. // No need for this mux if the cache does not handle writes.
assign LineWriteData = FetchBuffer; assign LineWriteData = PreLineWriteData;
assign LineByteMask = '1; assign LineByteMask = '1;
end end
@ -216,7 +222,7 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .CacheAtomic, .Stall, .FlushStage, .CacheRW, .CacheAtomic, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .CacheMiss, .CacheAccess, .SelAdr,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); .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 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 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 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 SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state output logic LRUWriteEn, // Update the LRU state
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr 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 & (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 if(AnyMiss | CMOp[2] | CMOp[3]) /* & LineDirty */NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck & ~(CMOp[2] | CMOp[3]))) NextState = STATE_WRITE_LINE; STATE_FETCH: if(CacheBusAck & ~(CMOp[2] | CMOp[3])) NextState = STATE_WRITE_LINE;
else (CacheBusAck) /* CMOp[2] | CMOp[3] */ NextState = STATE_READY; else if(CacheBusAck) /* CMOp[2] | CMOp[3] */ NextState = STATE_READY;
else NextState = STATE_FETCH; else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD; STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
// exclusion-tag-start: icache case // 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 if(CacheBusAck) NextState = STATE_FETCH;
else NextState = STATE_WRITEBACK; 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. // 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) |
(CurrState == STATE_FLUSH_WRITEBACK); (CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache // 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]) | assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0]) |
(CurrState == STATE_WRITEBACK & CMOp[1])); (CurrState == STATE_WRITEBACK & CMOp[1]));
// coverage off -item e 1 -fecexprrow 8 // coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) | assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
(CurrState == STATE_WRITE_LINE) & ~FlushStage; (CurrState == STATE_WRITE_LINE) & ~FlushStage;
// exclusion-tag-start: icache flushdirtycontrols // 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])); (CurrState == STATE_WRITE_LINE & (CacheRW[0]));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty 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. (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 // 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) | assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (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 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 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 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 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 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 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 ClearDirtyWay;
logic SelNonHit; logic SelNonHit;
logic SelData; 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 if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn; logic FlushWayEn;
@ -86,10 +93,10 @@ module cacheway import cvw::*; #(parameter cvw_t P,
// coverage off -item e 1 -fecexprrow 3 // 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. // 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 FlushWayEn = FlushWay & SelFlush;
assign SelNonHit = FlushWayEn | SetValid | SelWriteback; assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback;
end else begin:flushlogic // no flush operation for read-only caches. end else begin:flushlogic // no flush operation for read-only caches.
assign SelTag = VictimWay; assign SelTag = VictimWay;
assign SelNonHit = SetValid; assign SelNonHit = SelNotHit2;
end end
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData); mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);