Initial CMO implementation. Just adds control signals into the L1 caches.

This commit is contained in:
Ross Thompson 2023-08-14 15:43:12 -05:00
parent fcf9adae8c
commit 0eac74ac7b
4 changed files with 19 additions and 7 deletions

7
src/cache/cache.sv vendored
View File

@ -38,6 +38,7 @@ module cache import cvw::*; #(parameter cvw_t P,
input logic [1:0] CacheAtomic, // Atomic operation
input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits.
input logic [PA_BITS-1:0] PAdr, // Physical address
input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
@ -75,7 +76,7 @@ module cache import cvw::*; #(parameter cvw_t P,
logic [1:0] AdrSelMuxSel;
logic [SETLEN-1:0] CacheSet;
logic [LINELEN-1:0] LineWriteData;
logic ClearDirty, SetDirty, SetValid;
logic ClearDirty, SetDirty, SetValid, ClearValid;
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] HitWay, ValidWay;
logic CacheHit;
@ -215,8 +216,8 @@ module cache import cvw::*; #(parameter cvw_t P,
.FlushStage, .CacheRW, .CacheAtomic, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr,
.ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CacheEn, .LRUWriteEn);
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn);
endmodule

14
src/cache/cachefsm.sv vendored
View File

@ -40,6 +40,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
input logic [1:0] CacheAtomic, // Atomic operation
input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
// Bus controls
input logic CacheBusAck, // Bus operation completed
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
@ -54,8 +55,9 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
input logic FlushWayFlag, // On the last way for any set of a cache flush
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
output logic SetValid, // Set the valid bit in the selected way and set
output logic ClearDirty, // Clear the dirty bit in the selected way and set
output logic ClearValid, // Clear the valid 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 SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
@ -140,6 +142,13 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_FLUSH_WRITEBACK);
// write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE;
// *** fix param later
//if (P.ZICBOM_SUPPORTED)
assign ClearValid = (CurrState == STATE_READY & CMOp[0]) |
(CurrState == STATE_WRITEBACK & CMOp[1]);
// *** end of fix me
// coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
(CurrState == STATE_WRITE_LINE) & ~FlushStage;
@ -147,8 +156,9 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) | // exclusion-tag: icache SetDirty
(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.
(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 & (CMOp[1] | CMOp[2] | CMOp[3])); // *** fix me param
assign SelWriteback = (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_READY & AnyMiss & LineDirty);

View File

@ -233,6 +233,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
// *** RT: Fix CMOp. Should be CMOpM. Also PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE.
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS),
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
.NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
@ -249,7 +250,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.CacheAtomic('0), .FlushCache('0),
.NextSet(PCSpillNextF[11:0]),
.PAdr(PCPF),
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM), .CMOp('0));
ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),

View File

@ -276,7 +276,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
.FetchBuffer, .CacheBusRW(CacheBusRWTemp),
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0), .CMOp(CMOpM));
assign DCacheStallM = CacheStall & ~IgnoreRequestTLB;
assign CacheBusRW = CacheBusRWTemp;