mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Fixed Issue #752 of Verilator simulation by changing LRUMemory to be nonblocking now that Verilator handles this construct properly
This commit is contained in:
parent
4a4bbdfc43
commit
2fc9edff45
31
src/cache/cacheLRU.sv
vendored
31
src/cache/cacheLRU.sv
vendored
@ -48,12 +48,12 @@ module cacheLRU
|
|||||||
localparam LOGNUMWAYS = $clog2(NUMWAYS);
|
localparam LOGNUMWAYS = $clog2(NUMWAYS);
|
||||||
|
|
||||||
logic [NUMWAYS-2:0] LRUMemory [NUMSETS-1:0];
|
logic [NUMWAYS-2:0] LRUMemory [NUMSETS-1:0];
|
||||||
logic [NUMWAYS-2:0] CurrLRU;
|
logic [NUMWAYS-2:0] CurrLRU, NextLRU, ReadLRU, BypassedLRU;
|
||||||
logic [NUMWAYS-2:0] NextLRU;
|
|
||||||
logic [LOGNUMWAYS-1:0] HitWayEncoded, Way;
|
logic [LOGNUMWAYS-1:0] HitWayEncoded, Way;
|
||||||
logic [NUMWAYS-2:0] WayExpanded;
|
logic [NUMWAYS-2:0] WayExpanded;
|
||||||
logic AllValid;
|
logic AllValid;
|
||||||
|
logic ForwardLRU;
|
||||||
|
|
||||||
genvar row;
|
genvar row;
|
||||||
|
|
||||||
/* verilator lint_off UNOPTFLAT */
|
/* verilator lint_off UNOPTFLAT */
|
||||||
@ -131,29 +131,22 @@ module cacheLRU
|
|||||||
assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
|
assign Intermediate[node] = CurrLRU[node] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero);
|
priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero);
|
||||||
binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay);
|
binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay);
|
||||||
mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc);
|
mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc);
|
||||||
decoder #(LOGNUMWAYS) decoder (VictimWayEnc, VictimWay);
|
decoder #(LOGNUMWAYS) decoder (VictimWayEnc, VictimWay);
|
||||||
|
|
||||||
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
|
// LRU memory must be reset for Questa to run. The reset value does not matter but it is best to be deterministc.
|
||||||
// This is a two port memory.
|
always_ff @(posedge clk)
|
||||||
// Every cycle must read from CacheSetTag and each load/store must write the new LRU.
|
|
||||||
|
|
||||||
// note: Verilator lint doesn't like <= for array initialization (https://verilator.org/warn/BLKLOOPINIT?v=5.021)
|
|
||||||
// Move to = to keep Verilator happy and simulator running fast
|
|
||||||
always_ff @(posedge clk) begin
|
|
||||||
if (reset | (InvalidateCache & ~FlushStage))
|
if (reset | (InvalidateCache & ~FlushStage))
|
||||||
for (int set = 0; set < NUMSETS; set++) LRUMemory[set] = '0; // exclusion-tag: initialize
|
for (int set = 0; set < NUMSETS; set++) LRUMemory[set] <= '0; // exclusion-tag: initialize
|
||||||
else if(CacheEn) begin
|
else if (CacheEn & LRUWriteEn) LRUMemory[PAdr] <= NextLRU;
|
||||||
// Because we are using blocking assignments, change to LRUMemory must occur after LRUMemory is used so we get the proper value
|
|
||||||
if(LRUWriteEn & (PAdr == CacheSetTag)) CurrLRU = NextLRU;
|
|
||||||
else CurrLRU = LRUMemory[CacheSetTag];
|
|
||||||
if(LRUWriteEn) LRUMemory[PAdr] = NextLRU;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
// LRU read path with write forwarding
|
||||||
|
assign ReadLRU = LRUMemory[CacheSetTag];
|
||||||
|
assign ForwardLRU = LRUWriteEn & (PAdr == CacheSetTag);
|
||||||
|
mux2 #(NUMWAYS-1) ReadLRUmux(LRUMemory[CacheSetTag], NextLRU, ForwardLRU, BypassedLRU);
|
||||||
|
flop #(NUMWAYS-1) CurrLRUReg(clk, BypassedLRU, CurrLRU);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user