mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
commit
7f62905a71
6
src/cache/cache.sv
vendored
6
src/cache/cache.sv
vendored
@ -88,7 +88,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
|||||||
logic FlushAdrFlag, FlushWayFlag;
|
logic FlushAdrFlag, FlushWayFlag;
|
||||||
logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
|
logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
|
||||||
logic FlushWayCntEn;
|
logic FlushWayCntEn;
|
||||||
logic SelBothWriteback;
|
logic SelWriteback;
|
||||||
logic LRUWriteEn;
|
logic LRUWriteEn;
|
||||||
logic SelFlush;
|
logic SelFlush;
|
||||||
logic ResetOrFlushCntRst;
|
logic ResetOrFlushCntRst;
|
||||||
@ -156,7 +156,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
|||||||
mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
||||||
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
||||||
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
|
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
|
||||||
.s({SelFlush, SelBothWriteback}), .y(CacheBusAdr));
|
.s({SelFlush, SelWriteback}), .y(CacheBusAdr));
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Write Path
|
// Write Path
|
||||||
@ -227,7 +227,7 @@ module cache import cvw::*; #(parameter cvw_t P,
|
|||||||
.FlushStage, .CacheRW, .Stall,
|
.FlushStage, .CacheRW, .Stall,
|
||||||
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
||||||
.CacheMiss, .CacheAccess, .SelAdr, .SelWay,
|
.CacheMiss, .CacheAccess, .SelAdr, .SelWay,
|
||||||
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .ZeroCacheLine, .SelBothWriteback, .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);
|
||||||
|
55
src/cache/cachefsm.sv
vendored
55
src/cache/cachefsm.sv
vendored
@ -59,7 +59,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
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 ZeroCacheLine, // Write zeros to all bytes of cacheline
|
||||||
output logic SelBothWriteback, // 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
|
||||||
output logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
|
output logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
|
||||||
@ -75,10 +75,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
logic AnyMiss;
|
logic AnyMiss;
|
||||||
logic FlushFlag;
|
logic FlushFlag;
|
||||||
logic CMOWritebackHit;
|
logic CMOWritebackHit;
|
||||||
|
logic CMOWriteback;
|
||||||
logic CMOZeroNoEviction;
|
logic CMOZeroNoEviction;
|
||||||
logic CMOZeroEviction;
|
logic CMOZeroEviction;
|
||||||
logic SelWriteback; // Overrides cached tag check to select a specific way and set for writeback
|
|
||||||
logic SelCMOWriteback; // Overrides cached tag check to select a specific way and set for writeback for both data and tag
|
|
||||||
|
|
||||||
typedef enum logic [3:0]{STATE_READY, // hit states
|
typedef enum logic [3:0]{STATE_READY, // hit states
|
||||||
// miss states
|
// miss states
|
||||||
@ -88,10 +87,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM
|
STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM
|
||||||
// flush cache
|
// flush cache
|
||||||
STATE_FLUSH,
|
STATE_FLUSH,
|
||||||
STATE_FLUSH_WRITEBACK,
|
STATE_FLUSH_WRITEBACK
|
||||||
// CMO states
|
|
||||||
STATE_CMO_WRITEBACK,
|
|
||||||
STATE_CMO_DONE
|
|
||||||
} statetype;
|
} statetype;
|
||||||
|
|
||||||
statetype CurrState, NextState;
|
statetype CurrState, NextState;
|
||||||
@ -102,6 +98,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit;
|
assign CMOWritebackHit = (CMOp[1] | CMOp[2]) & CacheHit;
|
||||||
assign CMOZeroNoEviction = CMOp[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now
|
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 CMOZeroEviction = CMOp[3] & LineDirty; // (hit or miss) with writeback dirty line
|
||||||
|
assign CMOWriteback = CMOWritebackHit | CMOZeroEviction;
|
||||||
|
|
||||||
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
|
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
|
||||||
|
|
||||||
@ -124,8 +121,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
||||||
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
|
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 & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
|
||||||
else if(AnyMiss | CMOZeroEviction) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||||
else if(CMOWritebackHit) NextState = STATE_CMO_WRITEBACK;
|
|
||||||
else NextState = STATE_READY;
|
else NextState = STATE_READY;
|
||||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||||
else if(CacheBusAck) NextState = STATE_READY;
|
else if(CacheBusAck) NextState = STATE_READY;
|
||||||
@ -134,8 +130,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
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[3]) NextState = STATE_FETCH;
|
STATE_WRITEBACK: if (CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_READ_HOLD;
|
||||||
else if(CacheBusAck) NextState = STATE_CMO_DONE;
|
else if(CacheBusAck & ~CMOp[3]) NextState = STATE_FETCH;
|
||||||
|
else if(CacheBusAck) NextState = STATE_READ_HOLD;
|
||||||
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.
|
||||||
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
|
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
|
||||||
@ -144,31 +141,25 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
|
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
|
||||||
else if(CacheBusAck) NextState = STATE_READ_HOLD;
|
else if(CacheBusAck) NextState = STATE_READ_HOLD;
|
||||||
else NextState = STATE_FLUSH_WRITEBACK;
|
else NextState = STATE_FLUSH_WRITEBACK;
|
||||||
|
|
||||||
STATE_CMO_WRITEBACK: if(CacheBusAck & (CMOp[1] | CMOp[2])) NextState = STATE_CMO_DONE;
|
|
||||||
else NextState = STATE_CMO_WRITEBACK;
|
|
||||||
STATE_CMO_DONE: if(Stall) NextState = STATE_CMO_DONE;
|
|
||||||
else NextState = STATE_READY;
|
|
||||||
// exclusion-tag-end: icache case
|
// exclusion-tag-end: icache case
|
||||||
default: NextState = STATE_READY;
|
default: NextState = STATE_READY;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// com back to CPU
|
// com back to CPU
|
||||||
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD | CurrState == STATE_CMO_DONE));
|
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD));
|
||||||
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWritebackHit | CMOZeroEviction)) | // exclusion-tag: icache StallStates
|
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss | CMOWriteback)) | // exclusion-tag: icache StallStates
|
||||||
(CurrState == STATE_FETCH) |
|
(CurrState == STATE_FETCH) |
|
||||||
(CurrState == STATE_WRITEBACK) |
|
(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_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) |
|
||||||
(CurrState == STATE_FLUSH_WRITEBACK) |
|
(CurrState == STATE_FLUSH_WRITEBACK);
|
||||||
(CurrState == STATE_CMO_WRITEBACK);
|
|
||||||
// write enables internal to cache
|
// write enables internal to cache
|
||||||
assign SetValid = CurrState == STATE_WRITE_LINE |
|
assign SetValid = CurrState == STATE_WRITE_LINE |
|
||||||
(P.ZICBOZ_SUPPORTED & CurrState == STATE_READY & CMOZeroNoEviction) |
|
(P.ZICBOZ_SUPPORTED & CurrState == STATE_READY & CMOZeroNoEviction) |
|
||||||
(P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]);
|
(P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]);
|
||||||
assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0] & CacheHit) |
|
assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0] & CacheHit) |
|
||||||
(CurrState == STATE_CMO_WRITEBACK & CMOp[2] & CacheBusAck));
|
(CurrState == STATE_WRITEBACK & CMOp[2] & CacheBusAck));
|
||||||
// coverage off -item e 1 -fecexprrow 8
|
// coverage off -item e 1 -fecexprrow 8
|
||||||
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
||||||
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
||||||
@ -180,19 +171,14 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
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_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck);
|
(P.ZICBOM_SUPPORTED & CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck);
|
||||||
assign SelWay = SelWriteback | (CurrState == STATE_WRITE_LINE) |
|
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (P.ZICBOZ_SUPPORTED & CacheBusAck & CMOp[3]))) |
|
||||||
// This is almost the same as setvalid, but on cachehit we don't want to select
|
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (P.ZICBOZ_SUPPORTED & CMOZeroNoEviction & ~CacheHit))) |
|
||||||
// the nonhit way, but instead want to force this to zero
|
(CurrState == STATE_WRITE_LINE);
|
||||||
(P.ZICBOZ_SUPPORTED & CurrState == STATE_READY & CMOZeroNoEviction & ~CacheHit) |
|
|
||||||
(P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]);
|
|
||||||
assign ZeroCacheLine = P.ZICBOZ_SUPPORTED & ((CurrState == STATE_READY & CMOZeroNoEviction) |
|
assign ZeroCacheLine = P.ZICBOZ_SUPPORTED & ((CurrState == STATE_READY & CMOZeroNoEviction) |
|
||||||
(CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck)));
|
(CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck)));
|
||||||
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) |
|
||||||
(CurrState == STATE_READY & AnyMiss & LineDirty);
|
(CurrState == STATE_READY & AnyMiss & LineDirty);
|
||||||
assign SelCMOWriteback = CurrState == STATE_CMO_WRITEBACK;
|
|
||||||
assign SelBothWriteback = SelWriteback | SelCMOWriteback;
|
|
||||||
|
|
||||||
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
|
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
|
||||||
(CurrState == STATE_FLUSH) |
|
(CurrState == STATE_FLUSH) |
|
||||||
(CurrState == STATE_FLUSH_WRITEBACK);
|
(CurrState == STATE_FLUSH_WRITEBACK);
|
||||||
@ -208,17 +194,16 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
// Bus interface controls
|
// Bus interface controls
|
||||||
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
|
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
|
||||||
(CurrState == STATE_FETCH & ~CacheBusAck) |
|
(CurrState == STATE_FETCH & ~CacheBusAck) |
|
||||||
(CurrState == STATE_WRITEBACK & CacheBusAck & ~CMOp[3]);
|
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOp));
|
||||||
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW
|
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | // exclusion-tag: icache CacheBusW
|
||||||
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
||||||
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
|
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
|
||||||
(P.ZICBOM_SUPPORTED & CurrState == STATE_CMO_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck);
|
(P.ZICBOM_SUPPORTED & CurrState == STATE_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
|
assign SelAdr = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
|
||||||
(CurrState == STATE_FETCH) |
|
(CurrState == STATE_FETCH) |
|
||||||
(CurrState == STATE_WRITEBACK) |
|
(CurrState == STATE_WRITEBACK) |
|
||||||
(CurrState == STATE_WRITE_LINE) |
|
(CurrState == STATE_WRITE_LINE) |
|
||||||
(CurrState == STATE_CMO_WRITEBACK) |
|
|
||||||
resetDelay;
|
resetDelay;
|
||||||
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
|
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
|
||||||
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
|
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
|
||||||
|
Loading…
Reference in New Issue
Block a user