mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Might have working cbo clean and flush instructions.
This commit is contained in:
parent
8c7eafffad
commit
b842fdb863
11
src/cache/cache.sv
vendored
11
src/cache/cache.sv
vendored
@ -90,6 +90,8 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
|
||||
logic FlushWayCntEn;
|
||||
logic SelWriteback;
|
||||
logic SelCMOWriteback;
|
||||
logic SelBothWriteback;
|
||||
logic LRUWriteEn;
|
||||
logic SelFlush;
|
||||
logic ResetOrFlushCntRst;
|
||||
@ -116,8 +118,8 @@ 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, .ZeroCacheLine, .SelWriteback, .VictimWay,
|
||||
.clk, .reset, .CacheEn, .CMOp, .CacheSet, .PAdr, .LineWriteData, .LineByteMask,
|
||||
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .VictimWay,
|
||||
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
||||
|
||||
// Select victim way for associative caches
|
||||
@ -153,10 +155,11 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
.PAdr(WordOffsetAddr), .ReadDataLine, .ReadDataWord);
|
||||
|
||||
// Bus address for fetch, writeback, or flush writeback
|
||||
assign SelBothWriteback = SelWriteback | SelCMOWriteback;
|
||||
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, SelWriteback}), .y(CacheBusAdr));
|
||||
.s({SelFlush, SelBothWriteback}), .y(CacheBusAdr));
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Write Path
|
||||
@ -222,7 +225,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
||||
.FlushStage, .CacheRW, .CacheAtomic, .Stall,
|
||||
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
||||
.CacheMiss, .CacheAccess, .SelAdr,
|
||||
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelFlush,
|
||||
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelWriteback, .SelCMOWriteback, .SelFlush,
|
||||
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
|
||||
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
||||
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn);
|
||||
|
43
src/cache/cachefsm.sv
vendored
43
src/cache/cachefsm.sv
vendored
@ -61,6 +61,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
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 SelCMOWriteback, // Overrides cached tag check to select a specific way and set for writeback for both data and tag
|
||||
output logic LRUWriteEn, // Update the LRU state
|
||||
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
output logic FlushAdrCntEn, // Enable the counter for Flush Adr
|
||||
@ -83,7 +84,11 @@ 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} statetype;
|
||||
STATE_FLUSH_WRITEBACK,
|
||||
// CMO states
|
||||
STATE_CMO_WRITEBACK,
|
||||
STATE_CMO_DONE
|
||||
} statetype;
|
||||
|
||||
statetype CurrState, NextState;
|
||||
|
||||
@ -112,17 +117,17 @@ 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 | CMOp[1] | CMOp[2]) /* & LineDirty */NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else if(AnyMiss) /* & LineDirty */ NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else if((CMOp[1] | CMOp[2]) & CacheHit) NextState = STATE_CMO_WRITEBACK;
|
||||
else NextState = STATE_READY;
|
||||
STATE_FETCH: if(CacheBusAck & ~(CMOp[1] | CMOp[2])) NextState = STATE_WRITE_LINE;
|
||||
else if(CacheBusAck) /* CMOp[1] | CMOp[2] */ NextState = STATE_READY;
|
||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||
else if(CacheBusAck) 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[1] | CMOp[2])) NextState = STATE_READ_HOLD;
|
||||
else if(CacheBusAck) NextState = STATE_FETCH;
|
||||
STATE_WRITEBACK: 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.
|
||||
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
|
||||
@ -131,36 +136,42 @@ 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;
|
||||
// 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);
|
||||
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD | CurrState == STATE_CMO_DONE));
|
||||
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOp[1] | CMOp[2])) | // 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_FLUSH_WRITEBACK) |
|
||||
(CurrState == STATE_CMO_WRITEBACK);
|
||||
// write enables internal to cache
|
||||
assign SetValid = CurrState == STATE_WRITE_LINE | (CurrState == STATE_READY & CMOp[3]);
|
||||
assign SetValid = CurrState == STATE_WRITE_LINE |
|
||||
(CurrState == STATE_READY & CMOp[3]); // *** RT: NOT completely right has to be a hit
|
||||
assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0]) |
|
||||
(CurrState == STATE_WRITEBACK & CMOp[1]));
|
||||
(CurrState == STATE_CMO_DONE & CMOp[2]));
|
||||
// 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 | CMOp[3])) | // exclusion-tag: icache SetDirty
|
||||
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOp[3])) | // exclusion-tag: icache SetDirty *** NOT completely right has to be a hit for CMOp[3]
|
||||
(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]));
|
||||
assign ZeroCacheLine = CurrState == STATE_READY & CMOp[3];
|
||||
(P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_DONE & (CMOp[1] | CMOp[2]));
|
||||
assign ZeroCacheLine = CurrState == STATE_READY & CMOp[3]; // *** RT: NOT completely right
|
||||
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
||||
(CurrState == STATE_READY & AnyMiss & LineDirty);
|
||||
assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK;
|
||||
|
||||
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
|
||||
(CurrState == STATE_FLUSH) |
|
||||
@ -179,13 +190,15 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
(CurrState == STATE_FETCH & ~CacheBusAck) |
|
||||
(CurrState == STATE_WRITEBACK & CacheBusAck);
|
||||
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW
|
||||
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
||||
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck);
|
||||
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
||||
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
|
||||
(P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_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
|
||||
|
8
src/cache/cacheway.sv
vendored
8
src/cache/cacheway.sv
vendored
@ -33,6 +33,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
||||
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
|
||||
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
||||
input logic [$clog2(NUMLINES)-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
|
||||
input logic [PA_BITS-1:0] PAdr, // Physical address
|
||||
@ -43,6 +44,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
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 SelCMOWriteback, // Overrides cached tag check to select a specific way and set for writeback for both data and tag
|
||||
input logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
input logic VictimWay, // LRU selected this way as victim to evict
|
||||
input logic FlushWay, // This way is selected for flush and possible writeback if dirty
|
||||
@ -78,7 +80,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
logic SelData;
|
||||
logic SelNotHit2;
|
||||
|
||||
if (P.ZICBOM_SUPPORTED) begin : cbologic
|
||||
if (P.ZICBOZ_SUPPORTED) begin : cbologic
|
||||
assign SelNotHit2 = SetValid & ~(ZeroCacheLine & HitWay);
|
||||
end else begin : cbologic
|
||||
assign SelNotHit2 = SetValid;
|
||||
@ -93,7 +95,9 @@ 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;
|
||||
// *** RT: This is slopy. I should refactor to have the fsm issue two types of writeback commands
|
||||
assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback;
|
||||
//assign SelNonHit = FlushWayEn | SelNotHit2 | SelWriteback;
|
||||
end else begin:flushlogic // no flush operation for read-only caches.
|
||||
assign SelTag = VictimWay;
|
||||
assign SelNonHit = SelNotHit2;
|
||||
@ -124,7 +128,7 @@ 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 = SelTag ? ReadTag : '0; // AND part of AOMux
|
||||
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux
|
||||
assign DirtyWay = SelTag & Dirty & ValidWay;
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user