2021-07-21 04:17:42 +00:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// dcache (data cache)
|
|
|
|
//
|
|
|
|
// Written: ross1728@gmail.com July 20, 2021
|
|
|
|
// Implements Pseudo LRU
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 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"
|
|
|
|
|
2021-08-26 03:30:05 +00:00
|
|
|
module cachereplacementpolicy
|
2022-02-10 17:42:40 +00:00
|
|
|
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)(
|
2022-10-04 20:14:58 +00:00
|
|
|
input logic clk, reset, ce,
|
2022-02-13 21:47:27 +00:00
|
|
|
input logic [NUMWAYS-1:0] HitWay,
|
2022-02-10 17:40:10 +00:00
|
|
|
output logic [NUMWAYS-1:0] VictimWay,
|
2022-02-10 17:42:40 +00:00
|
|
|
input logic [SETLEN-1:0] RAdr,
|
2022-02-10 17:40:10 +00:00
|
|
|
input logic LRUWriteEn);
|
2021-07-21 04:17:42 +00:00
|
|
|
|
2022-02-10 17:42:40 +00:00
|
|
|
logic [NUMWAYS-2:0] LRUEn, LRUMask;
|
|
|
|
logic [NUMWAYS-2:0] ReplacementBits [NUMLINES-1:0];
|
|
|
|
logic [NUMWAYS-2:0] LineReplacementBits;
|
|
|
|
logic [NUMWAYS-2:0] NewReplacement;
|
|
|
|
logic [NUMWAYS-2:0] NewReplacementD;
|
|
|
|
logic [SETLEN+OFFSETLEN-1:OFFSETLEN] PAdrD;
|
|
|
|
logic [SETLEN-1:0] RAdrD;
|
|
|
|
logic LRUWriteEnD;
|
2021-08-26 02:09:42 +00:00
|
|
|
|
2022-11-16 17:15:34 +00:00
|
|
|
|
|
|
|
localparam LOGNUMWAYS = $clog2(NUMWAYS);
|
|
|
|
localparam LEN = NUMWAYS-1;
|
|
|
|
|
|
|
|
logic [LOGNUMWAYS-1:0] HitWayEnc;
|
|
|
|
logic [LEN-1:0] HitWayExpand;
|
|
|
|
genvar row;
|
|
|
|
|
|
|
|
logic [NUMWAYS-2:0] cEn;
|
|
|
|
|
|
|
|
// proposed generic solution
|
2022-11-16 21:35:34 +00:00
|
|
|
/* -----\/----- EXCLUDED -----\/-----
|
2022-11-16 17:15:34 +00:00
|
|
|
binencoder #(NUMWAYS) encoder(HitWay, HitWayEnc);
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
assign HitWayExpand[StartIndex : EndIndex] = {{DuplicationFactor}{HitWayEnc[row]}};
|
|
|
|
end
|
|
|
|
|
|
|
|
genvar r, a,s;
|
|
|
|
assign cEn[NUMWAYS-2] = '1;
|
|
|
|
for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin : enables
|
|
|
|
localparam p = NUMWAYS - s;
|
|
|
|
localparam g = $clog2(p);
|
|
|
|
localparam t0 = s - g;
|
|
|
|
localparam t1 = t0 - 1;
|
|
|
|
localparam r = LOGNUMWAYS - g;
|
|
|
|
assign cEn[t0] = cEn[s] & ~HitWayEnc[r];
|
|
|
|
assign cEn[t1] = cEn[s] & HitWayEnc[r];
|
|
|
|
end
|
|
|
|
|
2022-11-16 21:35:34 +00:00
|
|
|
mux2 #(1) LRUMuxes[NUMWAYS-2:0](LineReplacementBits, ~HitWayExpand, cEn, NewReplacement);
|
|
|
|
|
|
|
|
always_ff @(posedge clk) begin
|
|
|
|
if (reset) for (int set = 0; set < NUMLINES; set++) ReplacementBits[set] <= '0;
|
|
|
|
if(ce) begin
|
|
|
|
if (LRUWriteEn) begin
|
|
|
|
ReplacementBits[RAdr] <= NewReplacement;
|
|
|
|
LineReplacementBits <= #1 NewReplacement;
|
|
|
|
end else begin
|
|
|
|
LineReplacementBits <= #1 ReplacementBits[RAdr];
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
localparam HalfPoint = (2**$clog2(NUMWAYS)) / 2;
|
|
|
|
logic [NUMWAYS-2:0] ivec;
|
|
|
|
|
|
|
|
|
|
|
|
assign ivec[HalfPoint-1:0] = LineReplacementBits[HalfPoint-1:0];
|
|
|
|
for(r = NUMWAYS-2; r >= HalfPoint; r--) begin
|
|
|
|
|
|
|
|
end
|
2022-11-16 17:15:34 +00:00
|
|
|
|
|
|
|
assign VictimWay[0] = ~LineReplacementBits[2] & ~LineReplacementBits[0];
|
|
|
|
assign VictimWay[1] = ~LineReplacementBits[2] & LineReplacementBits[0];
|
|
|
|
assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1];
|
|
|
|
assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1];
|
|
|
|
|
|
|
|
-----/\----- EXCLUDED -----/\----- */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-04 00:07:31 +00:00
|
|
|
// *** high priority to clean up
|
2022-02-03 17:18:48 +00:00
|
|
|
initial begin
|
|
|
|
assert (NUMWAYS == 2 || NUMWAYS == 4) else $error("Only 2 or 4 ways supported");
|
|
|
|
end
|
|
|
|
|
|
|
|
// Replacement Bits: Register file
|
|
|
|
// Needs to be resettable for simulation, but could omit reset for synthesis ***
|
2022-10-04 20:14:58 +00:00
|
|
|
always_ff @(posedge clk) begin
|
2022-07-06 23:34:30 +00:00
|
|
|
if (reset) for (int set = 0; set < NUMLINES; set++) ReplacementBits[set] <= '0;
|
2022-10-04 20:14:58 +00:00
|
|
|
if(ce) begin
|
2022-10-04 20:29:32 +00:00
|
|
|
if (LRUWriteEn) begin
|
|
|
|
ReplacementBits[RAdr] <= NewReplacement;
|
|
|
|
LineReplacementBits <= #1 NewReplacement;
|
|
|
|
end else begin
|
|
|
|
LineReplacementBits <= #1 ReplacementBits[RAdr];
|
|
|
|
end
|
2022-10-04 20:14:58 +00:00
|
|
|
end
|
|
|
|
end
|
2021-07-21 04:17:42 +00:00
|
|
|
|
2021-07-21 19:01:14 +00:00
|
|
|
genvar index;
|
2022-02-03 17:18:48 +00:00
|
|
|
if(NUMWAYS == 2) begin : PseudoLRU
|
2022-01-05 16:25:08 +00:00
|
|
|
assign LRUEn[0] = 1'b0;
|
2022-02-13 21:47:27 +00:00
|
|
|
assign NewReplacement[0] = HitWay[1];
|
2022-01-05 16:25:08 +00:00
|
|
|
assign VictimWay[1] = ~LineReplacementBits[0];
|
|
|
|
assign VictimWay[0] = LineReplacementBits[0];
|
2022-02-03 17:18:48 +00:00
|
|
|
end else if (NUMWAYS == 4) begin : PseudoLRU
|
|
|
|
// 1 hot encoding for VictimWay; LRU = LineReplacementBits
|
|
|
|
//| LRU 2 | LRU 1 | LRU 0 | VictimWay
|
|
|
|
//+-------+-------+-------+-----------
|
|
|
|
//| 1 | - | 1 | 0001
|
|
|
|
//| 1 | - | 0 | 0010
|
|
|
|
//| 0 | 1 | - | 0100
|
|
|
|
//| 0 | 0 | - | 1000
|
2022-01-05 16:25:08 +00:00
|
|
|
|
|
|
|
assign VictimWay[0] = ~LineReplacementBits[2] & ~LineReplacementBits[0];
|
|
|
|
assign VictimWay[1] = ~LineReplacementBits[2] & LineReplacementBits[0];
|
|
|
|
assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1];
|
|
|
|
assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1];
|
|
|
|
|
2022-02-13 21:47:27 +00:00
|
|
|
// New LRU bits which are updated is function only of the HitWay.
|
2022-01-05 16:25:08 +00:00
|
|
|
// However the not updated bits come from the old LRU.
|
2022-02-13 21:47:27 +00:00
|
|
|
assign LRUEn[2] = |HitWay;
|
|
|
|
assign LRUEn[1] = HitWay[3] | HitWay[2];
|
|
|
|
assign LRUEn[0] = HitWay[1] | HitWay[0];
|
2022-01-05 16:25:08 +00:00
|
|
|
|
2022-02-13 21:47:27 +00:00
|
|
|
assign LRUMask[2] = HitWay[1] | HitWay[0];
|
|
|
|
assign LRUMask[1] = HitWay[2];
|
|
|
|
assign LRUMask[0] = HitWay[0];
|
2021-07-21 04:17:42 +00:00
|
|
|
|
2022-02-03 17:18:48 +00:00
|
|
|
mux2 #(1) LRUMuxes[NUMWAYS-2:0](LineReplacementBits, LRUMask, LRUEn, NewReplacement);
|
|
|
|
end
|
|
|
|
/* *** 8-way not yet working - look for a general way to write this for all NUMWAYS
|
|
|
|
else if (NUMWAYS == 8) begin : PseudoLRU
|
2022-01-05 16:25:08 +00:00
|
|
|
|
|
|
|
// selects
|
|
|
|
assign LRUEn[6] = 1'b1;
|
2022-02-13 21:47:27 +00:00
|
|
|
assign LRUEn[5] = HitWay[7] | HitWay[6] | HitWay[5] | HitWay[4];
|
|
|
|
assign LRUEn[4] = HitWay[7] | HitWay[6];
|
|
|
|
assign LRUEn[3] = HitWay[5] | HitWay[4];
|
|
|
|
assign LRUEn[2] = HitWay[3] | HitWay[2] | HitWay[1] | HitWay[0];
|
|
|
|
assign LRUEn[1] = HitWay[3] | HitWay[2];
|
|
|
|
assign LRUEn[0] = HitWay[1] | HitWay[0];
|
2022-01-05 16:25:08 +00:00
|
|
|
|
|
|
|
// mask
|
2022-02-13 21:47:27 +00:00
|
|
|
assign LRUMask[6] = HitWay[7] | HitWay[6] | HitWay[5] | HitWay[4];
|
|
|
|
assign LRUMask[5] = HitWay[7] | HitWay[6];
|
|
|
|
assign LRUMask[4] = HitWay[7];
|
|
|
|
assign LRUMask[3] = HitWay[5];
|
|
|
|
assign LRUMask[2] = HitWay[3] | HitWay[2];
|
|
|
|
assign LRUMask[1] = HitWay[2];
|
|
|
|
assign LRUMask[0] = HitWay[0];
|
2022-01-05 16:25:08 +00:00
|
|
|
|
|
|
|
for(index = 0; index < NUMWAYS-1; index++)
|
2022-02-03 17:18:48 +00:00
|
|
|
assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index];
|
2022-01-05 16:25:08 +00:00
|
|
|
|
|
|
|
assign EncVicWay[2] = LineReplacementBits[6];
|
|
|
|
assign EncVicWay[1] = LineReplacementBits[6] ? LineReplacementBits[5] : LineReplacementBits[2];
|
|
|
|
assign EncVicWay[0] = LineReplacementBits[6] ? LineReplacementBits[5] ? LineReplacementBits[4] : LineReplacementBits[3] :
|
|
|
|
LineReplacementBits[2] ? LineReplacementBits[1] : LineReplacementBits[0];
|
|
|
|
|
|
|
|
|
|
|
|
onehotdecoder #(3)
|
|
|
|
waydec(.bin(EncVicWay),
|
|
|
|
.decoded({VictimWay[0], VictimWay[1], VictimWay[2], VictimWay[3],
|
|
|
|
VictimWay[4], VictimWay[5], VictimWay[6], VictimWay[7]}));
|
2022-02-03 17:18:48 +00:00
|
|
|
end */
|
2021-07-21 04:17:42 +00:00
|
|
|
endmodule
|
|
|
|
|
2021-08-26 02:09:42 +00:00
|
|
|
|