Cache code cleanup

This commit is contained in:
David Harris 2023-01-07 15:39:13 -08:00
parent 5fbba604f1
commit 7f7605737f

View File

@ -1,114 +1,102 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// cache (data cache) // cache
// //
// Written: ross1728@gmail.com July 07, 2021 // Written: ross1728@gmail.com July 07, 2021
// Implements the L1 data cache // Implements the L1 instruction/data cache
// //
// Purpose: Storage for data and meta data. // Purpose: Storage for data and meta data.
// //
// A component of the Wally configurable RISC-V project. // A component of the Wally configurable RISC-V project.
// //
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
// //
// MIT LICENSE // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
// 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:
// //
// The above copyright notice and this permission notice shall be included in all copies or // Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// substantial portions of the Software. // 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
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // https://solderpad.org/licenses/SHL-2.1/
// 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 // Unless required by applicable law or agreed to in writing, any work distributed under the
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // either express or implied. See the License for the specific language governing permissions
// OR OTHER DEALINGS IN THE SOFTWARE. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, DCACHE) ( module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, DCACHE) (
input logic clk, input logic clk,
input logic reset, input logic reset,
// cpu side input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
input logic FlushStage, input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
input logic Stall, // cpu side
input logic [1:0] CacheRW, input logic [1:0] CacheRW, // [1] Read, [0] Write
input logic [1:0] CacheAtomic, input logic [1:0] CacheAtomic, // Atomic operation
input logic FlushCache, input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, input logic InvalidateCache, // Clear all valid bits
input logic [11:0] NextAdr, // virtual address, but we only use the lower 12 bits. input logic [11:0] NextAdr, // Virtual address, but we only use the lower 12 bits.
input logic [`PA_BITS-1:0] PAdr, // physical address input logic [`PA_BITS-1:0] PAdr, // Physical address
input logic [(WORDLEN-1)/8:0] ByteMask, input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
input logic [WORDLEN-1:0] CacheWriteData, input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only)
output logic CacheCommitted, output logic CacheCommitted, // Cache has started bus operation that shouldn't be interrupted
output logic CacheStall, output logic CacheStall, // Cache stalls pipeline during multicycle operation
// to performance counters to cpu output logic [WORDLEN-1:0] ReadDataWord, // Word read from cache (goes to CPU and bus)
output logic CacheMiss, // to performance counters to cpu
output logic CacheAccess, output logic CacheMiss, // Cache miss
// lsu control output logic CacheAccess, // Cache access
input logic SelHPTW, // lsu control
// Bus fsm interface input logic SelHPTW, // Use PAdr from Hardware Page Table Walker rather than NextAdr
output logic [1:0] CacheBusRW, // Bus fsm interface
input logic CacheBusAck, input logic CacheBusAck, // Bus operation completed
input logic SelBusBeat, input logic SelBusBeat, // Word in cache line comes from BeatCount
input logic [LOGBWPL-1:0] BeatCount, input logic [LOGBWPL-1:0] BeatCount, // Beat in burst
input logic [LINELEN-1:0] FetchBuffer, input logic [LINELEN-1:0] FetchBuffer, // Buffer long enough to hold entire cache line arriving from bus
output logic [`PA_BITS-1:0] CacheBusAdr, output logic [1:0] CacheBusRW, // [1] Read or [0] write bus
output logic [WORDLEN-1:0] ReadDataWord); output logic [`PA_BITS-1:0] CacheBusAdr // Address for bus access
);
// Cache parameters // Cache parameters
localparam LINEBYTELEN = LINELEN/8; localparam LINEBYTELEN = LINELEN/8; // Line length in bytes
localparam OFFSETLEN = $clog2(LINEBYTELEN); localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field
localparam SETLEN = $clog2(NUMLINES); localparam SETLEN = $clog2(NUMLINES); // Number of set bits
localparam SETTOP = SETLEN+OFFSETLEN; localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits
localparam TAGLEN = `PA_BITS - SETTOP; localparam TAGLEN = `PA_BITS - SETTOP; // Number of tag bits
localparam WORDSPERLINE = LINELEN/WORDLEN; localparam WORDSPERLINE = LINELEN/WORDLEN; // Number of words in cache line
localparam FlushAdrThreshold = NUMLINES - 1; localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete
localparam LOGLLENBYTES = $clog2(WORDLEN/8); // Number of bits to address a word
localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN; // *** see if this is the same as WORDSPERLINE
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE); // ***
logic SelAdr; logic SelAdr;
logic [SETLEN-1:0] CAdr; logic [1:0] AdrSelMuxSel;
logic [LINELEN-1:0] LineWriteData; logic [SETLEN-1:0] CAdr;
logic ClearValid; logic [LINELEN-1:0] LineWriteData;
logic ClearDirty; logic ClearValid, ClearDirty, SetDirty, SetValid;
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0]; logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] HitWay, ValidWay; logic [NUMWAYS-1:0] HitWay, ValidWay;
logic CacheHit; logic CacheHit;
logic SetDirty; logic [NUMWAYS-1:0] VictimWay, DirtyWay;
logic SetValid; logic LineDirty;
logic [NUMWAYS-1:0] VictimWay; logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] DirtyWay; logic [TAGLEN-1:0] Tag;
logic LineDirty; logic [SETLEN-1:0] FlushAdr, NextFlushAdr, FlushAdrP1;
logic [TAGLEN-1:0] TagWay [NUMWAYS-1:0]; logic FlushAdrCntEn, FlushCntRst;
logic [TAGLEN-1:0] Tag; logic FlushAdrFlag, FlushWayFlag;
logic [SETLEN-1:0] FlushAdr; logic [NUMWAYS-1:0] FlushWay, NextFlushWay;
logic [SETLEN-1:0] NextFlushAdr; logic FlushWayCntEn;
logic [SETLEN-1:0] FlushAdrP1; logic SelWriteback;
logic FlushAdrCntEn; logic LRUWriteEn;
logic FlushCntRst; logic SelFlush;
logic FlushAdrFlag; logic ResetOrFlushCntRst;
logic FlushWayFlag; logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic [NUMWAYS-1:0] FlushWay; logic SelFetchBuffer;
logic [NUMWAYS-1:0] NextFlushWay; logic CacheEn;
logic FlushWayCntEn; logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic SelWriteback; logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel;
logic LRUWriteEn;
logic SelFlush;
logic ResetOrFlushCntRst;
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
logic SelFetchBuffer;
logic CacheEn;
localparam LOGLLENBYTES = $clog2(WORDLEN/8);
localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN;
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel;
genvar index; genvar index;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -119,9 +107,9 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
// and FlushAdr when handling D$ flushes // and FlushAdr when handling D$ flushes
// The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap
// sets PCNextF to XTVEC and the icache must start reading the instruction. // sets PCNextF to XTVEC and the icache must start reading the instruction.
mux3 #(SETLEN) AdrSelMux( assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((DCACHE == 0) & FlushStage))};
.d0(NextAdr[SETTOP-1:OFFSETLEN]), .d1(PAdr[SETTOP-1:OFFSETLEN]), .d2(FlushAdr), mux3 #(SETLEN) AdrSelMux(NextAdr[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr,
.s({SelFlush, ((SelAdr | SelHPTW) & ~((DCACHE == 0) & FlushStage))}), .y(CAdr)); AdrSelMuxSel, CAdr);
// Array of cache ways, along with victim, hit, dirty, and read merging logic // Array of cache ways, along with victim, hit, dirty, and read merging logic
cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE) cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE)
@ -184,7 +172,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
.d(FlushAdrP1), .q(NextFlushAdr)); .d(FlushAdrP1), .q(NextFlushAdr));
assign FlushAdr = FlushAdrCntEn ? FlushAdrP1 : NextFlushAdr; assign FlushAdr = FlushAdrCntEn ? FlushAdrP1 : NextFlushAdr;
assign FlushAdrP1 = NextFlushAdr + 1'b1; assign FlushAdrP1 = NextFlushAdr + 1'b1;
assign FlushAdrFlag = (NextFlushAdr == FlushAdrThreshold[SETLEN-1:0]); assign FlushAdrFlag = (NextFlushAdr == FLUSHADRTHRESHOLD[SETLEN-1:0]);
flopenl #(NUMWAYS) FlushWayReg(.clk, .load(ResetOrFlushCntRst), .en(FlushWayCntEn), flopenl #(NUMWAYS) FlushWayReg(.clk, .load(ResetOrFlushCntRst), .en(FlushWayCntEn),
.val({{NUMWAYS-1{1'b0}}, 1'b1}), .d(NextFlushWay), .q(FlushWay)); .val({{NUMWAYS-1{1'b0}}, 1'b1}), .d(NextFlushWay), .q(FlushWay));
assign FlushWayFlag = FlushWay[NUMWAYS-1]; assign FlushWayFlag = FlushWay[NUMWAYS-1];