cachefsm exclude icache logic without code reuse

This commit is contained in:
Alec Vercruysse 2023-04-12 15:57:45 -07:00
parent 800f0245f3
commit a3d9e11b0f
2 changed files with 105 additions and 127 deletions

View File

@ -27,17 +27,41 @@
# This file should be a last resort. It's preferable to put # This file should be a last resort. It's preferable to put
# // coverage off # // coverage off
# statements inline with the code whenever possible. # statements inline with the code whenever possible.
# a hack to describe coverage exclusions without hardcoding linenumbers:
do GetLineNum.do
# LZA (i<64) statement confuses coverage tool # LZA (i<64) statement confuses coverage tool
# This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working # This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working
coverage exclude -srcfile lzc.sv coverage exclude -srcfile lzc.sv
# Exclude D$ states from coverage in the I$ instance of cachefsm. ### Exclude D$ states and logic for the I$ instance
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv # This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
# Also exclude the write line to ready transition for the I$ since we can't get a flush # Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation.
# during this operation. coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY
# exclude unused transitions from case statement. Unfortunately the whole branch needs to be excluded I think. Expression coverage should still work.
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1
# exclude branch/condition coverage: LineDirty if statement
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1
# exclude the unreachable logic
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache WRITEBACKStatement"]
# exclude Atomic Operation logic
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO"] -item e 1 -fecexprrow 6
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO1"] -item e 1 -fecexprrow 2-4
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache AnyUpdateHit"] -item e 1 -fecexprrow 2
# cache write logic
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheW"] -item e 1 -fecexprrow 4
# output signal logic
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache StallStates"] -item e 1 -fecexprrow 8 12 14
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache flushdirtycontrols"]
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache flushdirtycontrols"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12
###################### ######################
# Toggle exclusions # Toggle exclusions

110
src/cache/cachefsm.sv vendored
View File

@ -86,25 +86,18 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
statetype CurrState, NextState; statetype CurrState, NextState;
// no atomic operations on i$
if (!READ_ONLY_CACHE) begin
assign AMO = CacheAtomic[1] & (&CacheRW); assign AMO = CacheAtomic[1] & (&CacheRW);
assign StoreAMO = AMO | CacheRW[0]; assign StoreAMO = AMO | CacheRW[0];
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache;
assign AnyUpdateHit = StoreAMO & CacheHit;
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit);
assign CacheAccess = (AMO | CacheRW[1] | CacheRW[0]) & CurrState == STATE_READY; // for performance counter
end
else begin
assign AnyMiss = CacheRW[1] & ~CacheHit & ~InvalidateCache;
assign AnyUpdateHit = 0; // todo clear all RO cache of usage of this logic
assign AnyHit = CacheRW[1] & CacheHit;
assign CacheAccess = CacheRW[1] & CurrState == STATE_READY; // for performance counter
end
assign CacheMiss = CacheAccess & ~CacheHit; // for performance counter assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: icache storeAMO
assign AnyUpdateHit = (StoreAMO) & CacheHit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
assign FlushFlag = FlushAdrFlag & FlushWayFlag; assign FlushFlag = FlushAdrFlag & FlushWayFlag;
// outputs for the performance counters.
assign CacheAccess = (AMO | CacheRW[1] | CacheRW[0]) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit;
// special case on reset. When the fsm first exists reset the // special case on reset. When the fsm first exists reset the
// PCNextF will no longer be pointing to the correct address. // PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector. // But PCF will be the reset vector.
@ -114,69 +107,52 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
if (reset | FlushStage) CurrState <= #1 STATE_READY; if (reset | FlushStage) CurrState <= #1 STATE_READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
// seperating NextState logic by ro vs rw cache results in code duplication but this is needed to hit coverage.
if (!READ_ONLY_CACHE)
always_comb begin always_comb begin
NextState = STATE_READY; NextState = STATE_READY;
case (CurrState) case (CurrState) // exclusion-tag: icache state-case
STATE_READY: if(InvalidateCache) NextState = STATE_READY; STATE_READY: if(InvalidateCache) NextState = STATE_READY;
else if(FlushCache) NextState = STATE_FLUSH; else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & ~LineDirty) NextState = STATE_FETCH; else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
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 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
STATE_WRITEBACK: if(CacheBusAck) NextState = STATE_FETCH; STATE_WRITEBACK: 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 // 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.
// time as getting back the bus ack.
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK; STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
else if (FlushFlag) NextState = STATE_READ_HOLD; else if (FlushFlag) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH; else NextState = STATE_FLUSH;
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;
// exclusion-tag-end: icache case
default: NextState = STATE_READY; default: NextState = STATE_READY;
endcase endcase
end // always_comb end
else // READ_ONLY_CACHE
always_comb begin
NextState = STATE_READY;
case (CurrState)
STATE_READY: if(InvalidateCache) NextState = STATE_READY;
else if(AnyMiss) NextState = STATE_FETCH;
else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY;
default: NextState = STATE_READY;
endcase // case (CurrState)
end // always_comb
// com back to CPU // com back to CPU
if (!READ_ONLY_CACHE) begin assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & CurrState == STATE_READ_HOLD);
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | // 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);
assign CacheCommitted = CurrState != STATE_READY; // write enables internal to cache
assign SelAdr = (CurrState == STATE_READY & (StoreAMO | AnyMiss)) | // changes if store delay hazard removed assign SetValid = CurrState == STATE_WRITE_LINE;
(CurrState == STATE_FETCH) | // coverage off -item e 1 -fecexprrow 8
(CurrState == STATE_WRITEBACK) | assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) & ~FlushStage;
resetDelay; // exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) | assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (StoreAMO)); (CurrState == STATE_WRITE_LINE & (StoreAMO));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) | assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) | // 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
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) | assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_READY & AnyMiss & LineDirty);
@ -190,43 +166,21 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_FLUSH_WRITEBACK & CacheBusAck); (CurrState == STATE_FLUSH_WRITEBACK & CacheBusAck);
assign FlushCntRst = (CurrState == STATE_FLUSH & FlushFlag & ~LineDirty) | assign FlushCntRst = (CurrState == STATE_FLUSH & FlushFlag & ~LineDirty) |
(CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck); (CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck);
// exclusion-tag-end: icache flushdirtycontrols
// Bus interface controls // Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck); (CurrState == STATE_WRITEBACK & CacheBusAck);
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) | 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);
// write enable internal to cache
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; assign SelAdr = (CurrState == STATE_READY & (StoreAMO | AnyMiss)) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
end
else begin
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) |
(CurrState == STATE_FETCH) |
(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.
assign CacheCommitted = (CurrState != STATE_READY) & ~(CurrState == STATE_READ_HOLD);
assign SelAdr = (CurrState == STATE_READY & AnyMiss) | // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |
resetDelay; resetDelay;
assign SetDirty = 0;
assign ClearDirty = 0;
assign SelWriteback = 0;
assign SelFlush = 0;
assign FlushAdrCntEn = 0;
assign FlushWayCntEn = 0;
assign FlushCntRst = 0;
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss) |
(CurrState == STATE_FETCH & ~CacheBusAck);
assign CacheBusRW[0] = 0;
assign CacheEn = (~Stall | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache;
end // else: (READ_ONLY_CACHE)
// write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE;
// coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
(CurrState == STATE_WRITE_LINE) & ~FlushStage;
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;
endmodule // cachefsm endmodule // cachefsm