diff --git a/pipelined/src/cache/cache.sv b/pipelined/src/cache/cache.sv index adaee8877..b86821217 100644 --- a/pipelined/src/cache/cache.sv +++ b/pipelined/src/cache/cache.sv @@ -81,6 +81,8 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE logic SetValid; logic [NUMWAYS-1:0] VictimWay; logic [NUMWAYS-1:0] VictimDirtyWay; + logic CacheHitDirty; + logic [NUMWAYS-1:0] HitDirtyWay; logic VictimDirty; logic [TAGLEN-1:0] VictimTagWay [NUMWAYS-1:0]; logic [TAGLEN-1:0] VictimTag; @@ -128,14 +130,14 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE) CacheWays[NUMWAYS-1:0](.clk, .reset, .ce, .CAdr, .PAdr, .LineWriteData, .LineByteMask, .SetValidWay, .ClearValidWay, .SetDirtyWay, .ClearDirtyWay, .SelEvict, .VictimWay, - .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .VictimDirtyWay, .VictimTagWay, .FlushStage, - .InvalidateCache); + .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .VictimDirtyWay, .VictimTagWay, .FlushStage, .InvalidateCache, .HitDirtyWay); if(NUMWAYS > 1) begin:vict cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( .clk, .reset, .ce, .HitWay, .ValidWay, .VictimWay, .CAdr, .LRUWriteEn(LRUWriteEn & ~FlushStage), .SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache); end else assign VictimWay = 1'b1; // one hot. assign CacheHit = | HitWay; + assign CacheHitDirty = | HitDirtyWay; assign VictimDirty = | VictimDirtyWay; // ReadDataLineWay is a 2d array of cache line len by number of ways. // Need to OR together each way in a bitwise manner. @@ -211,7 +213,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE ///////////////////////////////////////////////////////////////////////////////////////////// cachefsm cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, .FlushStage, .CacheRW, .CacheAtomic, .CPUBusy, - .CacheHit, .VictimDirty, .CacheStall, .CacheCommitted, + .CacheHit, .CacheHitDirty, .VictimDirty, .CacheStall, .CacheCommitted, .CacheMiss, .CacheAccess, .SelAdr, .ClearValid, .ClearDirty, .SetDirty, .SetValid, .SelEvict, .SelFlush, diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv index 4f057fe47..9406dfdf3 100644 --- a/pipelined/src/cache/cachefsm.sv +++ b/pipelined/src/cache/cachefsm.sv @@ -45,6 +45,7 @@ module cachefsm input logic CacheBusAck, // dcache internals input logic CacheHit, + input logic CacheHitDirty, input logic VictimDirty, input logic FlushAdrFlag, input logic FlushWayFlag, diff --git a/pipelined/src/cache/cacheway.sv b/pipelined/src/cache/cacheway.sv index 0326a1c87..84f2efee9 100644 --- a/pipelined/src/cache/cacheway.sv +++ b/pipelined/src/cache/cacheway.sv @@ -35,7 +35,6 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, input logic clk, input logic ce, input logic reset, - input logic [$clog2(NUMLINES)-1:0] CAdr, input logic [`PA_BITS-1:0] PAdr, input logic [LINELEN-1:0] LineWriteData, @@ -55,7 +54,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, output logic [LINELEN-1:0] ReadDataLineWay, output logic HitWay, output logic ValidWay, - output logic VictimDirtyWay, + output logic VictimDirtyWay, HitDirtyWay, output logic [TAGLEN-1:0] VictimTagWay); localparam integer WORDSPERLINE = LINELEN/`XLEN; @@ -65,7 +64,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, localparam integer BYTESPERWORD = `XLEN/8; logic [NUMLINES-1:0] ValidBits; -// logic [NUMLINES-1:0] DirtyBits; + logic [NUMLINES-1:0] DirtyBits; logic [LINELEN-1:0] ReadDataLine; logic [TAGLEN-1:0] ReadTag; logic Dirty; @@ -86,63 +85,18 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, ///////////////////////////////////////////////////////////////////////////////////////////// // Tag Array ///////////////////////////////////////////////////////////////////////////////////////////// -/* -----\/----- EXCLUDED -----\/----- - localparam BYTEENLEN = DIRTY_BITS+((TAGLEN-1)/8); - logic [BYTEENLEN:0] TagByteEn; - logic [DIRTY_BITS+TAGLEN-1:0] TagDin, TagDout; - - if(DIRTY_BITS) begin - assign TagByteEn = {(SetDirtyWay | ClearDirtyWay) & ~FlushStage, {{BYTEENLEN}{SetValidEN}}}; - assign TagDin = {SetDirtyWay, PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN] }; - assign Dirty = TagDout[TAGLEN]; - end else begin - assign TagByteEn = {{BYTEENLEN}{SetValidEN}}; - assign TagDin = PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]; - assign Dirty = '0; - end - assign ReadTag = TagDout[TAGLEN-1:0]; - - sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(DIRTY_BITS+TAGLEN)) CacheTagMem(.clk, .ce, - .addr(CAdr), .dout(TagDout), .bwe(TagByteEn), - .din(TagDin), .we(1'b1)); - -----/\----- EXCLUDED -----/\----- */ - sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce, .addr(CAdr), .dout(ReadTag), .bwe({{(TAGLEN+7)/8}{SetValidEN}}), .din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(1'b1)); - if (DIRTY_BITS) begin : dirty - sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(1)) DirtyMem(.clk, .ce, - .addr(CAdr), .dout(Dirty), .bwe((SetDirtyWay | ClearDirtyWay) & ~FlushStage), - .din(SetDirtyWay), .we(1'b1)); - end else assign Dirty = 1'b0; - - - ///////////////////////////////////////////////////////////////////////////////////////////// - // Dirty Bits - ///////////////////////////////////////////////////////////////////////////////////////////// - - // Dirty bits -/* -----\/----- EXCLUDED -----\/----- - if (DIRTY_BITS) begin:dirty - always_ff @(posedge clk) begin - //if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; - if(ce) begin - Dirty <= #1 DirtyBits[CAdr]; - if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay; - //if (SetDirtyWay & ~FlushStage) DirtyBits[CAdr] <= #1 1'b1; - //else if (ClearDirtyWay & ~FlushStage) DirtyBits[CAdr] <= #1 1'b0; - end - end - end else assign Dirty = 1'b0; - -----/\----- EXCLUDED -----/\----- */ // AND portion of distributed tag multiplexer mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag); assign VictimTagWay = SelTag ? ReadTag : '0; // AND part of AOMux assign VictimDirtyWay = SelTag & Dirty & ValidWay; + assign HitDirtyWay = Dirty & HitWay; assign HitWay = ValidWay & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]); ///////////////////////////////////////////////////////////////////////////////////////////// @@ -182,6 +136,21 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, end end + ///////////////////////////////////////////////////////////////////////////////////////////// + // Dirty Bits + ///////////////////////////////////////////////////////////////////////////////////////////// + + // Dirty bits + if (DIRTY_BITS) begin:dirty + always_ff @(posedge clk) begin + if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; // reset is optional. Consider merging with TAG array in the future. + if(ce) begin + Dirty <= #1 DirtyBits[CAdr]; + if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay; + end + end + end else assign Dirty = 1'b0; + endmodule diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index 0d21e84a7..e2edcd8b6 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -515,8 +515,9 @@ module DCacheFlushFSM .start, .tag(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS-1-tagstart:0]), .valid(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].ValidBits[index]), - //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]), - .dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]), + .dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]), + // these dirty bit selections would be needed if dirty is moved inside the tag array. + //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]), //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS+tagstart]), .data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].CacheDataMem.RAM[index]), .index(index),