The L1 D cache now supports cache line (block) invalidation and partial support for clean and flush.

This commit is contained in:
Ross Thompson 2023-08-14 16:39:18 -05:00
parent f678133d19
commit 6284773733
3 changed files with 13 additions and 6 deletions

6
src/cache/cache.sv vendored
View File

@ -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 // 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]( cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .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); .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches // Select victim way for associative caches
if(NUMWAYS > 1) begin:vict if(NUMWAYS > 1) begin:vict
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU(
.clk, .reset, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn, .clk, .reset, .FlushStage, .CacheEn, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn,
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache); .SetValid, .ClearValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache);
end else end else
assign VictimWay = 1'b1; // one hot. assign VictimWay = 1'b1; // one hot.

View File

@ -31,6 +31,7 @@ module cacheLRU
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) ( #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic FlushStage,
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant 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] 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 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 [SETLEN-1:0] PAdr, // Physical address
input logic LRUWriteEn, // Update the LRU state input logic LRUWriteEn, // Update the LRU state
input logic SetValid, // Set the dirty bit in the selected way and set 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 InvalidateCache, // Clear all valid bits
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
output logic [NUMWAYS-1:0] VictimWay // LRU selects a victim to evict output logic [NUMWAYS-1:0] VictimWay // LRU selects a victim to evict
@ -138,9 +140,11 @@ module cacheLRU
// This is a two port memory. // This is a two port memory.
// Every cycle must read from CacheSet and each load/store must write the new LRU. // Every cycle must read from CacheSet and each load/store must write the new LRU.
always_ff @(posedge clk) begin 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(CacheEn) begin
if(LRUWriteEn) if(ClearValid & ~FlushStage)
LRUMemory[PAdr] <= '0;
else if(LRUWriteEn)
LRUMemory[PAdr] <= NextLRU; LRUMemory[PAdr] <= NextLRU;
if(LRUWriteEn & (PAdr == CacheSet)) if(LRUWriteEn & (PAdr == CacheSet))
CurrLRU <= #1 NextLRU; CurrLRU <= #1 NextLRU;

View File

@ -38,6 +38,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
input logic [PA_BITS-1:0] PAdr, // Physical address input logic [PA_BITS-1:0] PAdr, // Physical address
input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only) 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 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 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 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 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 [LINELEN/8-1:0] FinalByteMask;
logic SetValidEN; logic SetValidEN;
logic SetValidWay; logic SetValidWay;
logic ClearValidWay;
logic SetDirtyWay; logic SetDirtyWay;
logic ClearDirtyWay; logic ClearDirtyWay;
logic SelNonHit; logic SelNonHit;
@ -97,6 +99,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
assign SetValidWay = SetValid & SelData; assign SetValidWay = SetValid & SelData;
assign ClearValidWay = ClearValid & SelData;
assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay
assign ClearDirtyWay = ClearDirty & SelData; assign ClearDirtyWay = ClearDirty & SelData;
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn
@ -155,7 +158,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
if(CacheEn) begin if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet]; ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway 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
end end