2021-07-07 22:52:16 +00:00
|
|
|
///////////////////////////////////////////
|
2022-02-03 15:36:11 +00:00
|
|
|
// cacheway
|
2021-07-07 22:52:16 +00:00
|
|
|
//
|
|
|
|
// Written: ross1728@gmail.com July 07, 2021
|
|
|
|
// Implements the data, tag, valid, dirty, and replacement bits.
|
|
|
|
//
|
|
|
|
// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement.
|
|
|
|
//
|
2023-01-11 23:15:08 +00:00
|
|
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
2021-07-07 22:52:16 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
2021-07-07 22:52:16 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
2021-07-07 22:52:16 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
|
|
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
|
|
|
// may obtain a copy of the License at
|
2021-07-07 22:52:16 +00:00
|
|
|
//
|
2023-01-10 19:35:20 +00:00
|
|
|
// https://solderpad.org/licenses/SHL-2.1/
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
|
|
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
|
|
// either express or implied. See the License for the specific language governing permissions
|
|
|
|
// and limitations under the License.
|
2022-01-07 12:58:40 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
2021-07-07 22:52:16 +00:00
|
|
|
|
|
|
|
`include "wally-config.vh"
|
|
|
|
|
2023-01-15 03:43:29 +00:00
|
|
|
module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|
|
|
OFFSETLEN = 5, INDEXLEN = 9, DIRTY_BITS = 1) (
|
|
|
|
input logic clk,
|
|
|
|
input logic CacheEn,
|
|
|
|
input logic reset,
|
|
|
|
input logic [$clog2(NUMLINES)-1:0] CAdr,
|
|
|
|
input logic [`PA_BITS-1:0] PAdr,
|
|
|
|
input logic [LINELEN-1:0] LineWriteData,
|
|
|
|
input logic SetValid,
|
|
|
|
input logic ClearValid,
|
|
|
|
input logic SetDirty,
|
|
|
|
input logic ClearDirty,
|
|
|
|
input logic SelWriteback,
|
|
|
|
input logic SelFlush,
|
|
|
|
input logic VictimWay,
|
|
|
|
input logic FlushWay,
|
|
|
|
input logic InvalidateCache,
|
|
|
|
input logic FlushStage,
|
|
|
|
input logic [LINELEN/8-1:0] LineByteMask,
|
2022-02-04 19:31:32 +00:00
|
|
|
|
2023-01-15 03:43:29 +00:00
|
|
|
output logic [LINELEN-1:0] ReadDataLineWay,
|
|
|
|
output logic HitWay,
|
|
|
|
output logic ValidWay,
|
|
|
|
output logic DirtyWay,
|
|
|
|
output logic [TAGLEN-1:0] TagWay);
|
2021-07-07 22:52:16 +00:00
|
|
|
|
2023-01-15 03:43:29 +00:00
|
|
|
localparam integer WORDSPERLINE = LINELEN/`XLEN;
|
|
|
|
localparam integer BYTESPERLINE = LINELEN/8;
|
|
|
|
localparam LOGWPL = $clog2(WORDSPERLINE);
|
|
|
|
localparam LOGXLENBYTES = $clog2(`XLEN/8);
|
|
|
|
localparam integer BYTESPERWORD = `XLEN/8;
|
2022-02-08 23:52:09 +00:00
|
|
|
|
2023-01-15 03:43:29 +00:00
|
|
|
logic [NUMLINES-1:0] ValidBits;
|
|
|
|
logic [NUMLINES-1:0] DirtyBits;
|
|
|
|
logic [LINELEN-1:0] ReadDataLine;
|
|
|
|
logic [TAGLEN-1:0] ReadTag;
|
|
|
|
logic Dirty;
|
|
|
|
logic SelTag;
|
|
|
|
logic SelectedWriteWordEn;
|
|
|
|
logic [LINELEN/8-1:0] FinalByteMask;
|
|
|
|
logic SetValidEN;
|
|
|
|
logic SetValidWay;
|
|
|
|
logic ClearValidWay;
|
|
|
|
logic SetDirtyWay;
|
|
|
|
logic ClearDirtyWay;
|
|
|
|
logic SelNonHit;
|
|
|
|
logic SelData;
|
|
|
|
logic FlushWayEn, VictimWayEn;
|
2022-12-09 22:42:05 +00:00
|
|
|
|
2022-12-09 23:07:35 +00:00
|
|
|
// FlushWay and VictimWay are part of a one hot way selection. Must clear them if FlushWay not selected
|
|
|
|
// or VictimWay not selected.
|
2022-12-09 22:42:05 +00:00
|
|
|
assign FlushWayEn = FlushWay & SelFlush;
|
2022-12-14 15:49:15 +00:00
|
|
|
assign VictimWayEn = VictimWay & SelWriteback;
|
2022-12-09 22:42:05 +00:00
|
|
|
|
2022-12-14 15:49:15 +00:00
|
|
|
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
|
2022-02-08 23:52:09 +00:00
|
|
|
|
2022-12-04 18:30:56 +00:00
|
|
|
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
2022-12-09 22:42:05 +00:00
|
|
|
//assign SelTag = VictimWay | FlushWay;
|
2022-12-14 15:49:15 +00:00
|
|
|
//assign SelData = HitWay | FlushWayEn | VictimWayEn;
|
2022-12-09 22:42:05 +00:00
|
|
|
|
2022-12-14 15:49:15 +00:00
|
|
|
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
|
2022-12-04 18:30:56 +00:00
|
|
|
|
2022-02-08 23:52:09 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Write Enable demux
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
2022-12-04 07:15:47 +00:00
|
|
|
|
2022-12-04 07:20:51 +00:00
|
|
|
// RT: Can we merge these two muxes? This is also shared in cacheLRU.
|
2022-12-14 15:49:15 +00:00
|
|
|
//mux3 #(1) selectwaymux(HitWay, VictimWay, FlushWay, {SelFlush, SetValid}, SelData);
|
|
|
|
//mux3 #(1) selecteddatamux(HitWay, VictimWay, FlushWay, {SelFlush, SelNonHit}, SelData);
|
2022-12-04 07:15:47 +00:00
|
|
|
|
2022-12-14 15:49:15 +00:00
|
|
|
assign SetValidWay = SetValid & SelData;
|
|
|
|
assign ClearValidWay = ClearValid & SelData;
|
|
|
|
assign SetDirtyWay = SetDirty & SelData;
|
|
|
|
assign ClearDirtyWay = ClearDirty & SelData;
|
2022-12-04 07:15:47 +00:00
|
|
|
|
2022-02-08 23:52:09 +00:00
|
|
|
// If writing the whole line set all write enables to 1, else only set the correct word.
|
2022-11-29 16:52:40 +00:00
|
|
|
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage;
|
2022-07-19 04:37:18 +00:00
|
|
|
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
|
2022-11-29 16:52:40 +00:00
|
|
|
assign SetValidEN = SetValidWay & ~FlushStage;
|
2022-02-04 19:31:32 +00:00
|
|
|
|
2022-02-03 16:00:57 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
2022-02-03 16:52:22 +00:00
|
|
|
// Tag Array
|
2022-02-03 16:00:57 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
2022-11-30 16:40:48 +00:00
|
|
|
|
2022-12-20 16:36:45 +00:00
|
|
|
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
2022-11-30 17:26:48 +00:00
|
|
|
.addr(CAdr), .dout(ReadTag), .bwe('1),
|
|
|
|
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
2022-11-30 06:05:34 +00:00
|
|
|
|
|
|
|
|
2022-02-03 16:52:22 +00:00
|
|
|
|
|
|
|
// AND portion of distributed tag multiplexer
|
2022-12-05 23:19:51 +00:00
|
|
|
assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
|
2022-12-04 22:09:09 +00:00
|
|
|
assign DirtyWay = SelTag & Dirty & ValidWay;
|
2022-11-29 20:09:48 +00:00
|
|
|
assign HitWay = ValidWay & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]);
|
2021-10-26 03:05:11 +00:00
|
|
|
|
2022-02-03 16:52:22 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Data Array
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2022-09-23 16:46:53 +00:00
|
|
|
genvar words;
|
2022-07-17 21:20:04 +00:00
|
|
|
|
2022-07-19 04:37:18 +00:00
|
|
|
localparam integer SRAMLEN = 128;
|
2022-07-18 02:05:31 +00:00
|
|
|
localparam integer NUMSRAM = LINELEN/SRAMLEN;
|
|
|
|
localparam integer SRAMLENINBYTES = SRAMLEN/8;
|
|
|
|
localparam integer LOGNUMSRAM = $clog2(NUMSRAM);
|
|
|
|
|
|
|
|
for(words = 0; words < NUMSRAM; words++) begin: word
|
2022-12-20 16:36:45 +00:00
|
|
|
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CAdr),
|
2022-09-21 17:20:00 +00:00
|
|
|
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
2022-11-14 03:36:12 +00:00
|
|
|
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
2022-11-29 16:52:40 +00:00
|
|
|
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
|
2022-07-17 21:20:04 +00:00
|
|
|
end
|
2021-07-07 22:52:16 +00:00
|
|
|
|
2022-02-03 16:52:22 +00:00
|
|
|
// AND portion of distributed read multiplexers
|
2022-12-09 22:42:05 +00:00
|
|
|
assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux.
|
2022-02-03 16:33:01 +00:00
|
|
|
|
2022-02-03 16:00:57 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Valid Bits
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
2021-07-07 22:52:16 +00:00
|
|
|
|
2022-02-03 16:00:57 +00:00
|
|
|
always_ff @(posedge clk) begin // Valid bit array,
|
2022-11-29 20:09:48 +00:00
|
|
|
if (reset) ValidBits <= #1 '0;
|
2022-12-14 15:49:15 +00:00
|
|
|
if(CacheEn) begin
|
2022-11-29 20:09:48 +00:00
|
|
|
ValidWay <= #1 ValidBits[CAdr];
|
2023-01-20 15:41:18 +00:00
|
|
|
if(InvalidateCache) ValidBits <= #1 '0;
|
2022-11-30 17:04:37 +00:00
|
|
|
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay;
|
2022-09-22 21:09:09 +00:00
|
|
|
end
|
|
|
|
end
|
2021-10-26 03:05:11 +00:00
|
|
|
|
2022-11-30 17:01:25 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Dirty Bits
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Dirty bits
|
|
|
|
if (DIRTY_BITS) begin:dirty
|
|
|
|
always_ff @(posedge clk) begin
|
2022-11-30 17:04:37 +00:00
|
|
|
// reset is optional. Consider merging with TAG array in the future.
|
|
|
|
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
|
2022-12-14 15:49:15 +00:00
|
|
|
if(CacheEn) begin
|
2022-11-30 17:01:25 +00:00
|
|
|
Dirty <= #1 DirtyBits[CAdr];
|
|
|
|
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end else assign Dirty = 1'b0;
|
|
|
|
|
2022-02-04 19:31:32 +00:00
|
|
|
|
2022-02-03 16:33:01 +00:00
|
|
|
endmodule
|
2021-07-07 22:52:16 +00:00
|
|
|
|
|
|
|
|