2021-07-21 04:17:42 +00:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// dcache (data cache)
|
|
|
|
//
|
|
|
|
// Written: ross1728@gmail.com July 20, 2021
|
|
|
|
// Implements Pseudo LRU
|
2022-11-17 22:50:03 +00:00
|
|
|
// Tested for Powers of 2.
|
2021-07-21 04:17:42 +00:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// A component of the Wally configurable RISC-V project.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
|
|
//
|
2022-01-07 12:58:40 +00:00
|
|
|
// MIT LICENSE
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
|
|
// software and associated documentation files (the "Software"), to deal in the Software
|
|
|
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
|
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
|
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
2021-07-21 04:17:42 +00:00
|
|
|
//
|
2022-01-07 12:58:40 +00:00
|
|
|
// The above copyright notice and this permission notice shall be included in all copies or
|
|
|
|
// substantial portions of the Software.
|
2021-07-21 04:17:42 +00:00
|
|
|
//
|
2022-01-07 12:58:40 +00:00
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
|
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
|
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-07-21 04:17:42 +00:00
|
|
|
|
|
|
|
`include "wally-config.vh"
|
|
|
|
|
2022-11-21 04:35:02 +00:00
|
|
|
module cacheLRU
|
2022-02-10 17:42:40 +00:00
|
|
|
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)(
|
2022-12-01 23:32:58 +00:00
|
|
|
input logic clk, reset, ce, FlushStage,
|
2022-02-13 21:47:27 +00:00
|
|
|
input logic [NUMWAYS-1:0] HitWay,
|
2022-11-29 20:09:48 +00:00
|
|
|
input logic [NUMWAYS-1:0] ValidWay,
|
2022-02-10 17:40:10 +00:00
|
|
|
output logic [NUMWAYS-1:0] VictimWay,
|
2022-11-29 16:52:40 +00:00
|
|
|
input logic [SETLEN-1:0] CAdr,
|
2022-11-29 20:51:09 +00:00
|
|
|
input logic [SETLEN-1:0] PAdr,
|
|
|
|
input logic LRUWriteEn, SetValid, InvalidateCache);
|
2021-07-21 04:17:42 +00:00
|
|
|
|
2022-11-21 04:31:36 +00:00
|
|
|
logic [NUMWAYS-2:0] LRUMemory [NUMLINES-1:0];
|
|
|
|
logic [NUMWAYS-2:0] CurrLRU;
|
2022-11-29 20:09:48 +00:00
|
|
|
logic [NUMWAYS-2:0] NextLRU;
|
2022-11-17 22:50:03 +00:00
|
|
|
logic [NUMWAYS-1:0] Way;
|
2022-11-16 17:15:34 +00:00
|
|
|
|
|
|
|
localparam LOGNUMWAYS = $clog2(NUMWAYS);
|
|
|
|
|
2022-11-17 22:50:03 +00:00
|
|
|
logic [LOGNUMWAYS-1:0] WayEncoded;
|
|
|
|
logic [NUMWAYS-2:0] WayExpanded;
|
2022-11-29 20:09:48 +00:00
|
|
|
logic AllValid;
|
|
|
|
|
2022-11-16 17:15:34 +00:00
|
|
|
genvar row;
|
|
|
|
|
2022-11-17 22:50:03 +00:00
|
|
|
/* verilator lint_off UNOPTFLAT */
|
|
|
|
// Ross: For some reason verilator does not like this. I checked and it is not a circular path.
|
2022-11-29 20:09:48 +00:00
|
|
|
logic [NUMWAYS-2:0] LRUUpdate;
|
2022-11-17 22:50:03 +00:00
|
|
|
logic [LOGNUMWAYS-1:0] Intermediate [NUMWAYS-2:0];
|
|
|
|
/* verilator lint_on UNOPTFLAT */
|
|
|
|
|
2022-11-29 20:09:48 +00:00
|
|
|
assign AllValid = &ValidWay;
|
|
|
|
|
2022-11-22 20:59:01 +00:00
|
|
|
///// Update replacement bits.
|
2022-11-17 22:50:03 +00:00
|
|
|
function integer log2 (integer value);
|
|
|
|
for (log2=0; value>0; log2=log2+1)
|
|
|
|
value = value>>1;
|
|
|
|
return log2;
|
|
|
|
endfunction // log2
|
|
|
|
|
2022-11-21 04:35:02 +00:00
|
|
|
// On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay.
|
2022-11-17 22:50:03 +00:00
|
|
|
mux2 #(NUMWAYS) WayMux(HitWay, VictimWay, SetValid, Way);
|
|
|
|
binencoder #(NUMWAYS) encoder(Way, WayEncoded);
|
2022-11-16 17:15:34 +00:00
|
|
|
|
|
|
|
// bit duplication
|
|
|
|
// expand HitWay as HitWay[3], {{2}{HitWay[2]}}, {{4}{HitWay[1]}, {{8{HitWay[0]}}, ...
|
|
|
|
for(row = 0; row < LOGNUMWAYS; row++) begin
|
|
|
|
localparam integer DuplicationFactor = 2**(LOGNUMWAYS-row-1);
|
|
|
|
localparam integer StartIndex = NUMWAYS-2 - DuplicationFactor + 1;
|
|
|
|
localparam integer EndIndex = NUMWAYS-2 - 2 * DuplicationFactor + 2;
|
2022-11-17 22:50:03 +00:00
|
|
|
assign WayExpanded[StartIndex : EndIndex] = {{DuplicationFactor}{WayEncoded[row]}};
|
2022-11-16 17:15:34 +00:00
|
|
|
end
|
|
|
|
|
2022-11-17 22:50:03 +00:00
|
|
|
genvar r, a, s;
|
2022-11-29 20:09:48 +00:00
|
|
|
assign LRUUpdate[NUMWAYS-2] = '1;
|
2022-11-16 17:15:34 +00:00
|
|
|
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin : enables
|
2022-11-17 22:50:03 +00:00
|
|
|
localparam p = NUMWAYS - s - 1;
|
|
|
|
localparam g = log2(p);
|
|
|
|
localparam t0 = s - p;
|
2022-11-16 17:15:34 +00:00
|
|
|
localparam t1 = t0 - 1;
|
|
|
|
localparam r = LOGNUMWAYS - g;
|
2022-11-29 20:09:48 +00:00
|
|
|
assign LRUUpdate[t0] = LRUUpdate[s] & ~WayEncoded[r];
|
|
|
|
assign LRUUpdate[t1] = LRUUpdate[s] & WayEncoded[r];
|
2022-11-16 17:15:34 +00:00
|
|
|
end
|
|
|
|
|
2022-11-29 20:09:48 +00:00
|
|
|
mux2 #(1) LRUMuxes[NUMWAYS-2:0](CurrLRU, ~WayExpanded, LRUUpdate, NextLRU);
|
2022-11-16 21:35:34 +00:00
|
|
|
|
2022-11-22 20:59:01 +00:00
|
|
|
// Compute next victim way.
|
|
|
|
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin
|
|
|
|
localparam t0 = 2*s - NUMWAYS;
|
|
|
|
localparam t1 = t0 + 1;
|
|
|
|
assign Intermediate[s] = CurrLRU[s] ? Intermediate[t1] : Intermediate[t0];
|
|
|
|
end
|
|
|
|
for(s = NUMWAYS/2-1; s >= 0; s--) begin
|
|
|
|
localparam int0 = (NUMWAYS/2-1-s)*2;
|
|
|
|
localparam int1 = int0 + 1;
|
|
|
|
assign Intermediate[s] = CurrLRU[s] ? int1[LOGNUMWAYS-1:0] : int0[LOGNUMWAYS-1:0];
|
|
|
|
end
|
|
|
|
|
2022-11-29 20:09:48 +00:00
|
|
|
logic [NUMWAYS-1:0] FirstZero;
|
|
|
|
logic [LOGNUMWAYS-1:0] FirstZeroWay;
|
|
|
|
logic [LOGNUMWAYS-1:0] VictimWayEnc;
|
|
|
|
|
|
|
|
priorityonehot #(NUMWAYS) FirstZeroEncoder(~ValidWay, FirstZero);
|
|
|
|
binencoder #(NUMWAYS) FirstZeroWayEncoder(FirstZero, FirstZeroWay);
|
|
|
|
mux2 #(LOGNUMWAYS) VictimMux(FirstZeroWay, Intermediate[NUMWAYS-2], AllValid, VictimWayEnc);
|
|
|
|
//decoder #(LOGNUMWAYS) decoder (Intermediate[NUMWAYS-2], VictimWay);
|
|
|
|
decoder #(LOGNUMWAYS) decoder (VictimWayEnc, VictimWay);
|
2022-11-22 20:59:01 +00:00
|
|
|
|
|
|
|
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
|
2022-11-16 21:35:34 +00:00
|
|
|
always_ff @(posedge clk) begin
|
2022-11-21 04:31:36 +00:00
|
|
|
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
2022-11-16 21:35:34 +00:00
|
|
|
if(ce) begin
|
2022-12-01 23:32:58 +00:00
|
|
|
if(InvalidateCache & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
|
|
|
else if (LRUWriteEn & ~FlushStage) begin
|
2022-11-29 20:51:09 +00:00
|
|
|
LRUMemory[PAdr] <= NextLRU;
|
2022-11-29 20:09:48 +00:00
|
|
|
CurrLRU <= #1 NextLRU;
|
2022-11-16 21:35:34 +00:00
|
|
|
end else begin
|
2022-11-29 16:52:40 +00:00
|
|
|
CurrLRU <= #1 LRUMemory[CAdr];
|
2022-11-16 21:35:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-01-05 16:25:08 +00:00
|
|
|
|
2021-07-21 04:17:42 +00:00
|
|
|
endmodule
|
|
|
|
|
2021-08-26 02:09:42 +00:00
|
|
|
|