diff --git a/pipelined/src/cache/cache.sv b/pipelined/src/cache/cache.sv index 4e34eb02..82050f0e 100644 --- a/pipelined/src/cache/cache.sv +++ b/pipelined/src/cache/cache.sv @@ -85,6 +85,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0]; logic [TAGLEN-1:0] Tag; logic [SETLEN-1:0] FlushAdr; + logic [SETLEN-1:0] OldFlushAdr, NextFlushAdr, RawFlushAdr; logic [SETLEN-1:0] FlushAdrP1; logic FlushAdrCntEn; logic FlushAdrCntRst; @@ -102,6 +103,8 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic SelFetchBuffer; logic CacheEn; + logic SelOldFlushAdr; + localparam LOGLLENBYTES = $clog2(WORDLEN/8); localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN; @@ -181,10 +184,15 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE ///////////////////////////////////////////////////////////////////////////////////////////// assign ResetOrFlushAdr = reset | FlushAdrCntRst; flopenr #(SETLEN) FlushAdrReg(.clk, .reset(ResetOrFlushAdr), .en(FlushAdrCntEn), - .d(FlushAdrP1), .q(FlushAdr)); - assign FlushAdrP1 = FlushAdr + 1'b1; - assign FlushAdrFlag = (FlushAdr == FlushAdrThreshold[SETLEN-1:0]); + .d(FlushAdrP1), .q(RawFlushAdr)); + assign NextFlushAdr = FlushAdrCntEn ? FlushAdrP1 : RawFlushAdr; + assign FlushAdrP1 = RawFlushAdr + 1'b1; + assign FlushAdrFlag = (RawFlushAdr == FlushAdrThreshold[SETLEN-1:0]); assign ResetOrFlushWay = reset | FlushWayCntRst; + flopenr #(SETLEN) OldFlushAdrReg(.clk, .reset(ResetOrFlushAdr), .en(FlushAdrCntEn), + .d(NextFlushAdr), .q(OldFlushAdr)); + mux2 #(SETLEN) FlushAdrMux(NextFlushAdr, OldFlushAdr, SelOldFlushAdr, FlushAdr); + flopenl #(NUMWAYS) FlushWayReg(.clk, .load(ResetOrFlushWay), .en(FlushWayCntEn), .val({{NUMWAYS-1{1'b0}}, 1'b1}), .d(NextFlushWay), .q(FlushWay)); assign FlushWayFlag = FlushWay[NUMWAYS-1]; @@ -200,7 +208,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE .CacheMiss, .CacheAccess, .SelAdr, .ClearValid, .ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush, - .FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst, + .FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst, .SelOldFlushAdr, .FlushWayCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .InvalidateCache, .CacheEn, diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv index 1396adf4..94618336 100644 --- a/pipelined/src/cache/cachefsm.sv +++ b/pipelined/src/cache/cachefsm.sv @@ -72,6 +72,7 @@ module cachefsm output logic FlushAdrCntRst, output logic FlushWayCntRst, output logic SelFetchBuffer, + output logic SelOldFlushAdr, output logic CacheEn); logic resetDelay; @@ -135,6 +136,14 @@ module cachefsm STATE_MISS_EVICT_DIRTY: if(CacheBusAck) NextState = STATE_MISS_FETCH_WDV; else NextState = STATE_MISS_EVICT_DIRTY; // 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_WRITE_BACK; + else if (FlushFlag & FlushWayFlag) NextState = STATE_READY; + else NextState = STATE_FLUSH; + STATE_FLUSH_WRITE_BACK: if(CacheBusAck & ~(FlushFlag & FlushWayFlag)) NextState = STATE_FLUSH; + else if(CacheBusAck) NextState = STATE_READY; + else NextState = STATE_FLUSH_WRITE_BACK; + +/* -----\/----- EXCLUDED -----\/----- STATE_FLUSH: NextState = STATE_FLUSH_CHECK; STATE_FLUSH_CHECK: if(LineDirty) NextState = STATE_FLUSH_WRITE_BACK; else if(FlushFlag) NextState = STATE_READY; @@ -146,6 +155,7 @@ module cachefsm else if(FlushWayFlag) NextState = STATE_FLUSH_INCR; else NextState = STATE_FLUSH_CHECK; end else NextState = STATE_FLUSH_WRITE_BACK; + -----/\----- EXCLUDED -----/\----- */ default: NextState = STATE_READY; endcase end @@ -156,10 +166,10 @@ module cachefsm (CurrState == STATE_MISS_FETCH_WDV) | (CurrState == STATE_MISS_EVICT_DIRTY) | (CurrState == STATE_MISS_WRITE_CACHE_LINE & ~(StoreAMO)) | // 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_CHECK & ~(FlushFlag)) | - (CurrState == STATE_FLUSH_INCR) | - (CurrState == STATE_FLUSH_WRITE_BACK & ~(FlushFlag) & CacheBusAck); + (CurrState == STATE_FLUSH & ~(FlushFlag & ~LineDirty)) | + //(CurrState == STATE_FLUSH_CHECK & ~(FlushFlag)) | + //(CurrState == STATE_FLUSH_INCR) | + (CurrState == STATE_FLUSH_WRITE_BACK & ~(FlushFlag & CacheBusAck)); // write enables internal to cache assign SetValid = CurrState == STATE_MISS_WRITE_CACHE_LINE; assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) | @@ -175,12 +185,17 @@ module cachefsm assign SelFlush = (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_CHECK) | (CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_WRITE_BACK); assign FlushWayAndNotAdrFlag = FlushWayFlag & ~FlushAdrFlag; - assign FlushAdrCntEn = (CurrState == STATE_FLUSH_CHECK & ~LineDirty & FlushWayAndNotAdrFlag) | - (CurrState == STATE_FLUSH_WRITE_BACK & FlushWayAndNotAdrFlag & CacheBusAck); - assign FlushWayCntEn = (CurrState == STATE_FLUSH_CHECK & ~LineDirty & ~(FlushFlag)) | - (CurrState == STATE_FLUSH_WRITE_BACK & ~FlushFlag & CacheBusAck); - assign FlushAdrCntRst = (CurrState == STATE_READY); - assign FlushWayCntRst = (CurrState == STATE_READY) | (CurrState == STATE_FLUSH_INCR); + //assign FlushAdrCntEn = (CurrState == STATE_FLUSH_CHECK & ~LineDirty & FlushWayAndNotAdrFlag) | + // (CurrState == STATE_FLUSH_WRITE_BACK & FlushWayAndNotAdrFlag & CacheBusAck); + assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITE_BACK & FlushWayFlag & CacheBusAck) | + (CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty); + assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) | + (CurrState == STATE_FLUSH_WRITE_BACK & CacheBusAck); + assign FlushAdrCntRst = (CurrState == STATE_FLUSH & FlushFlag & FlushWayFlag & ~LineDirty) | + (CurrState == STATE_FLUSH_WRITE_BACK & FlushFlag & FlushWayFlag & CacheBusAck); + assign FlushWayCntRst = FlushAdrCntRst; + assign SelOldFlushAdr = (CurrState == STATE_FLUSH & LineDirty) | + (CurrState == STATE_FLUSH_WRITE_BACK & ~CacheBusAck); // Bus interface controls assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | (CurrState == STATE_MISS_FETCH_WDV & ~CacheBusAck) | diff --git a/pipelined/src/ebu/buscachefsm.sv b/pipelined/src/ebu/buscachefsm.sv index b89be641..7d3d2bee 100644 --- a/pipelined/src/ebu/buscachefsm.sv +++ b/pipelined/src/ebu/buscachefsm.sv @@ -131,8 +131,8 @@ module buscachefsm #(parameter integer BeatCountThreshold, assign BusStall = (CurrState == ADR_PHASE & (|BusRW | |CacheBusRW)) | //(CurrState == DATA_PHASE & ~BusRW[0]) | // replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem. (CurrState == DATA_PHASE) | - (CurrState == CACHE_FETCH) | - (CurrState == CACHE_WRITEBACK); + (CurrState == CACHE_FETCH & ~HREADY) | + (CurrState == CACHE_WRITEBACK & ~HREADY); assign BusCommitted = CurrState != ADR_PHASE; // AHB bus interface