LineDirty is either the Victim Way or the Flush way dirty, but never the hitway dirty. CBO instructions require hitway dirty. However we cannot mux hitway dirty into LineDirty wihtout creating a combinational loop so we need a separate port.

This commit is contained in:
Rose Thompson 2023-11-29 17:35:26 -06:00
parent f11f88ac2b
commit ab68a76e77
3 changed files with 13 additions and 8 deletions

9
src/cache/cache.sv vendored
View File

@ -79,8 +79,8 @@ module cache import cvw::*; #(parameter cvw_t P,
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] HitWay, ValidWay;
logic CacheHit;
logic [NUMWAYS-1:0] VictimWay, DirtyWay;
logic LineDirty;
logic [NUMWAYS-1:0] VictimWay, DirtyWay, HitWayDirtyWay;
logic LineDirty, HitWayLineDirty;
logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0];
logic [TAGLEN-1:0] Tag;
logic [SETLEN-1:0] FlushAdr, NextFlushAdr, FlushAdrP1;
@ -116,7 +116,7 @@ module cache import cvw::*; #(parameter cvw_t P,
cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .SelWay,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay,
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitWayDirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches
if(NUMWAYS > 1) begin:vict
@ -128,6 +128,7 @@ module cache import cvw::*; #(parameter cvw_t P,
assign CacheHit = |HitWay;
assign LineDirty = |DirtyWay;
assign HitWayLineDirty = |HitWayDirtyWay;
// ReadDataLineWay is a 2d array of cache line len by number of ways.
// Need to OR together each way in a bitwise manner.
@ -218,7 +219,7 @@ module cache import cvw::*; #(parameter cvw_t P,
cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheHit, .LineDirty, .HitWayLineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .SelWay,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,

View File

@ -51,6 +51,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// cache internals
input logic CacheHit, // Exactly 1 way hits
input logic LineDirty, // The selected line and way is dirty
input logic HitWayLineDirty, // The cache hit way is dirty
input logic FlushAdrFlag, // On last set of a cache flush
input logic FlushWayFlag, // On the last way for any set of a cache flush
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
@ -94,7 +95,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit; // *** why does this not include dirty?
assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit & HitWayLineDirty;
//assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit; // *** why does this not include dirty? FIXME
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;
@ -130,7 +132,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
else NextState = STATE_READY;
// exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck & ~(|CMOp[3:1])) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; // *** why not Ready?
else if(CacheBusAck) NextState = STATE_READ_HOLD; // 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;

View File

@ -51,7 +51,8 @@ module cacheway import cvw::*; #(parameter cvw_t P,
output logic [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid
output logic HitWay, // This way hits
output logic ValidWay, // This way is valid
output logic DirtyWay, // This way is dirty
output logic HitWayDirtyWay, // The hit way is dirty
output logic DirtyWay , // The selected way is dirty
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
localparam WORDSPERLINE = LINELEN/XLEN;
@ -117,7 +118,8 @@ module cacheway import cvw::*; #(parameter cvw_t P,
// AND portion of distributed tag multiplexer
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux
assign DirtyWay = SelDirty & Dirty & ValidWay;
assign HitWayDirtyWay = Dirty & ValidWay;
assign DirtyWay = SelDirty & HitWayDirtyWay;
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]);
/////////////////////////////////////////////////////////////////////////////////////////////