diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 4a97a29d4..6882110bd 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -98,7 +98,7 @@ module cache import cvw::*; #(parameter cvw_t P, logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic SelFetchBuffer; logic CacheEn; - logic SelWay; + logic SelVictim; logic [LINELEN/8-1:0] LineByteMask; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; genvar index; @@ -120,7 +120,7 @@ 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, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelWay, + .clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelVictim, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay, .FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache); @@ -227,7 +227,7 @@ module cache import cvw::*; #(parameter cvw_t P, cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, .FlushStage, .CacheRW, .Stall, .CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted, - .CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay, + .CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelVictim, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 4af89b08e..869789df5 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -63,7 +63,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, output logic ClearDirty, // Clear the dirty bit in the selected way and set 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 SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway + output logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit output logic FlushAdrCntEn, // Enable the counter for Flush Adr output logic FlushWayCntEn, // Enable the way counter during a flush output logic FlushCntRst, // Reset both flush counters @@ -79,12 +79,12 @@ module cachefsm import cvw::*; #(parameter cvw_t P, logic CMOZeroNoEviction; logic StallConditions; - typedef enum logic [3:0]{STATE_READY, // hit states + typedef enum logic [3:0]{STATE_HIT, // hit states // miss states STATE_FETCH, STATE_WRITEBACK, STATE_WRITE_LINE, - STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM + STATE_ADDRESS_SETUP, // required for back to back reads. structural hazard on writting SRAM // flush cache STATE_FLUSH, STATE_FLUSH_WRITEBACK @@ -101,51 +101,51 @@ module cachefsm import cvw::*; #(parameter cvw_t P, assign FlushFlag = FlushAdrFlag & FlushWayFlag; // outputs for the performance counters. - assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW + assign CacheAccess = (|CacheRW) & ((CurrState == STATE_HIT & ~Stall & ~FlushStage) | (CurrState == STATE_ADDRESS_SETUP & ~Stall & ~FlushStage)); // 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 twayhe // PCNextF will no longer be pointing to the correct address. // But PCF will be the reset vector. flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay)); always_ff @(posedge clk) - if (reset | FlushStage) CurrState <= #1 STATE_READY; + if (reset | FlushStage) CurrState <= #1 STATE_HIT; else CurrState <= #1 NextState; always_comb begin - NextState = STATE_READY; + NextState = STATE_HIT; case (CurrState) // exclusion-tag: icache state-case - STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck + STATE_HIT: if(InvalidateCache) NextState = STATE_HIT; // exclusion-tag: dcache InvalidateCheck else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; // exclusion-tag: icache FLUSHStatement else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement else if((AnyMiss | CMOWriteback) & ~READ_ONLY_CACHE) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement - else NextState = STATE_READY; + else NextState = STATE_HIT; 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; + STATE_WRITE_LINE: NextState = STATE_ADDRESS_SETUP; + STATE_ADDRESS_SETUP: if(Stall) NextState = STATE_ADDRESS_SETUP; + else NextState = STATE_HIT; // exclusion-tag-start: icache case STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH; - else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall + else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP; // 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; - else if (FlushFlag) NextState = STATE_READ_HOLD; + else if (FlushFlag) NextState = STATE_ADDRESS_SETUP; else NextState = STATE_FLUSH; STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; - else if(CacheBusAck) NextState = STATE_READ_HOLD; + else if(CacheBusAck) NextState = STATE_ADDRESS_SETUP; else NextState = STATE_FLUSH_WRITEBACK; // exclusion-tag-end: icache case - default: NextState = STATE_READY; + default: NextState = STATE_HIT; endcase end // com back to CPU - assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); + assign CacheCommitted = (CurrState != STATE_HIT) & ~(READ_ONLY_CACHE & (CurrState == STATE_ADDRESS_SETUP)); assign StallConditions = FlushCache | AnyMiss | CMOWriteback; // exclusion-tag: icache FlushCache - assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates + assign CacheStall = (CurrState == STATE_HIT & StallConditions) | // 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. @@ -153,26 +153,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (CurrState == STATE_FLUSH_WRITEBACK); // write enables internal to cache assign SetValid = CurrState == STATE_WRITE_LINE | - (CurrState == STATE_READY & CMOZeroNoEviction) | + (CurrState == STATE_HIT & CMOZeroNoEviction) | (CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]); - assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) | + assign ClearValid = (CurrState == STATE_HIT & CMOpM[0]) | (CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck); - assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | + assign LRUWriteEn = (((CurrState == STATE_HIT & (AnyHit | CMOZeroNoEviction)) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) | (CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck); // exclusion-tag-start: icache flushdirtycontrols - assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty + assign SetDirty = (CurrState == STATE_HIT & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty (CurrState == STATE_WRITE_LINE & (CacheRW[0])) | (CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck)); 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 CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck; - assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) | - (CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) | + assign SelVictim = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) | + (CurrState == STATE_HIT & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) | (CurrState == STATE_WRITE_LINE); assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) | - (CurrState == STATE_READY & AnyMiss & LineDirty); + (CurrState == STATE_HIT & AnyMiss & LineDirty); // coverage off -item e 1 -fecexprrow 1 // (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck) assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) | @@ -183,29 +183,29 @@ module cachefsm import cvw::*; #(parameter cvw_t P, (CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck); // exclusion-tag-end: icache flushdirtycontrols // Bus interface controls - assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses + assign CacheBusRW[1] = (CurrState == STATE_HIT & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses (CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM)); logic LoadMiss; assign LoadMiss = (CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss - assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW + assign CacheBusRW[0] = (CurrState == STATE_HIT & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW (CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck); - assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed + assign SelAdrData = (CurrState == STATE_HIT & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITE_LINE) | resetDelay; - assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed + assign SelAdrTag = (CurrState == STATE_HIT & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITE_LINE) | resetDelay; - assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD; - assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn + assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_ADDRESS_SETUP; + assign CacheEn = (~Stall | StallConditions) | (CurrState != STATE_HIT) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn endmodule // cachefsm diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 678f7acac..3c0f5df31 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -42,7 +42,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, 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 SetDirty, // Set the dirty bit in the selected way and set - input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway + input logic SelVictim, // Overides HitWay Tag matching. Selects selects the victim tag/data regardless of hit input logic ClearDirty, // Clear the dirty bit in the selected way and set input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr input logic VictimWay, // LRU selected this way as victim to evict @@ -68,7 +68,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, logic [LINELEN-1:0] ReadDataLine; logic [TAGLEN-1:0] ReadTag; logic Dirty; - logic SelDirty; + logic SelecteDirty; logic SelectedWriteWordEn; logic [LINELEN/8-1:0] FinalByteMask; logic SetValidEN, ClearValidEN; @@ -77,33 +77,30 @@ module cacheway import cvw::*; #(parameter cvw_t P, logic SetDirtyWay; logic ClearDirtyWay; logic SelNonHit; - logic SelData; + logic SelectedWay; logic InvalidateCacheDelay; if (!READ_ONLY_CACHE) begin:flushlogic - logic FlushWayEn; - mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelDirty); - + mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelecteDirty); + mux3 #(1) selectedmux(HitWay, FlushWay, VictimWay, {SelVictim, FlushCache}, SelectedWay); // FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected. // coverage off -item e 1 -fecexprrow 3 // nonzero ways will never see FlushCache=0 while FlushWay=1 since FlushWay only advances on a subset of FlushCache assertion cases. - assign FlushWayEn = FlushWay & FlushCache; - assign SelNonHit = FlushWayEn | SelWay; end else begin:flushlogic // no flush operation for read-only caches. - assign SelDirty = VictimWay; - assign SelNonHit = SelWay; + assign SelecteDirty = VictimWay; + mux2 #(1) selectedwaymux(HitWay, SelecteDirty, SelVictim , SelectedWay); end - mux2 #(1) selectedwaymux(HitWay, SelDirty, SelNonHit , SelData); + ///////////////////////////////////////////////////////////////////////////////////////////// // Write Enable demux ///////////////////////////////////////////////////////////////////////////////////////////// - assign SetValidWay = SetValid & SelData; - assign ClearValidWay = ClearValid & SelData; // exclusion-tag: icache ClearValidWay - assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay - assign ClearDirtyWay = ClearDirty & SelData; + assign SetValidWay = SetValid & SelectedWay; + assign ClearValidWay = ClearValid & SelectedWay; // exclusion-tag: icache ClearValidWay + assign SetDirtyWay = SetDirty & SelectedWay; // exclusion-tag: icache SetDirtyWay + assign ClearDirtyWay = ClearDirty & SelectedWay; assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn assign SetValidEN = SetValidWay & ~FlushStage; // exclusion-tag: cache SetValidEN assign ClearValidEN = ClearValidWay & ~FlushStage; // exclusion-tag: cache ClearValidEN @@ -120,9 +117,9 @@ 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 = SelData ? ReadTag : '0; // AND part of AOMux + assign TagWay = SelectedWay ? ReadTag : '0; // AND part of AOMux assign HitDirtyWay = Dirty & ValidWay; - assign DirtyWay = SelDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay + assign DirtyWay = SelecteDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay); @@ -152,7 +149,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, end // AND portion of distributed read multiplexers - assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux. + assign ReadDataLineWay = SelectedWay ? ReadDataLine : '0; // AND part of AO mux. ///////////////////////////////////////////////////////////////////////////////////////////// // Valid Bits