diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 145921ef0..b70f4d5e9 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -116,14 +116,14 @@ 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, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, - .SetValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, + .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); // Select victim way for associative caches if(NUMWAYS > 1) begin:vict cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( - .clk, .reset, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn, - .SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache); + .clk, .reset, .FlushStage, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn, + .SetValid, .ClearValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache); end else assign VictimWay = 1'b1; // one hot. diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index 5fb00dc90..34ea59612 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -31,6 +31,7 @@ module cacheLRU #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) ( input logic clk, input logic reset, + input logic FlushStage, input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag @@ -38,6 +39,7 @@ module cacheLRU input logic [SETLEN-1:0] PAdr, // Physical address input logic LRUWriteEn, // Update the LRU state input logic SetValid, // Set the dirty bit in the selected way and set + input logic ClearValid, // Clear the dirty bit in the selected way and set input logic InvalidateCache, // Clear all valid bits input logic FlushCache, // Flush all dirty lines back to memory output logic [NUMWAYS-1:0] VictimWay // LRU selects a victim to evict @@ -138,9 +140,11 @@ module cacheLRU // This is a two port memory. // Every cycle must read from CacheSet and each load/store must write the new LRU. always_ff @(posedge clk) begin - if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; + if (reset | (InvalidateCache & ~FlushStage)) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if(CacheEn) begin - if(LRUWriteEn) + if(ClearValid & ~FlushStage) + LRUMemory[PAdr] <= '0; + else if(LRUWriteEn) LRUMemory[PAdr] <= NextLRU; if(LRUWriteEn & (PAdr == CacheSet)) CurrLRU <= #1 NextLRU; diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 4438ea2c7..240e66859 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -38,6 +38,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, input logic [PA_BITS-1:0] PAdr, // Physical address input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only) 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 ClearDirty, // Clear the dirty bit in the selected way and set input logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback @@ -69,6 +70,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, logic [LINELEN/8-1:0] FinalByteMask; logic SetValidEN; logic SetValidWay; + logic ClearValidWay; logic SetDirtyWay; logic ClearDirtyWay; logic SelNonHit; @@ -97,6 +99,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, ///////////////////////////////////////////////////////////////////////////////////////////// assign SetValidWay = SetValid & SelData; + assign ClearValidWay = ClearValid & SelData; assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay assign ClearDirtyWay = ClearDirty & SelData; assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn @@ -155,7 +158,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, if(CacheEn) begin ValidWay <= #1 ValidBits[CacheSet]; if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway - else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay; + else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay; end end