cvw/testbench/common/DCacheFlushFSM.sv
Rose Thompson a8ab3c8342 Ok that is a stange bug.
The testbench used logic for the shadow ram, but the memory used bit. This caused questa to allocate huge amounts of memory and crash. Changing shadow ram to bit fixed the issue.
2023-12-20 12:25:34 -06:00

153 lines
6.9 KiB
Systemverilog

///////////////////////////////////////////
// DCacheFlushFSM.sv
//
// Written: David Harris David_Harris@hmc.edu and Ross Thompson ross1728@gmail.com
// Modified: 14 June 2023
//
// Purpose: The L1 data cache and any feature L2 or high cache will not necessary writeback all dirty
// line before the end of test. Signature based regression tests need to check the L1 data cache
// in addition to the main memory. These modules create a shadow memory with a projection of the
// D$ contents.
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// 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
//
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
module DCacheFlushFSM import cvw::*; #(parameter cvw_t P)
(input logic clk,
input logic reset,
input logic start,
output logic done);
genvar adr;
bit [P.XLEN-1:0] ShadowRAM[P.UNCORE_RAM_BASE>>(1+P.XLEN/32):(P.UNCORE_RAM_RANGE+P.UNCORE_RAM_BASE)>>1+(P.XLEN/32)];
logic startD;
if(P.DCACHE_SUPPORTED) begin
localparam numlines = P.DCACHE_WAYSIZEINBYTES*8/P.DCACHE_LINELENINBITS;
localparam numways = P.DCACHE_NUMWAYS;
localparam linelen = P.DCACHE_LINELENINBITS;
localparam linebytelen = linelen/8;
localparam sramlen = P.CACHE_SRAMLEN;
localparam cachesramwords = linelen/sramlen;
localparam numwords = sramlen/P.XLEN;
localparam lognumlines = $clog2(numlines);
localparam loglinebytelen = $clog2(linebytelen);
localparam lognumways = $clog2(numways);
localparam tagstart = lognumlines + loglinebytelen;
genvar index, way, cacheWord;
logic [sramlen-1:0] CacheData [numways-1:0] [numlines-1:0] [cachesramwords-1:0];
logic [sramlen-1:0] cacheline;
logic [P.XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [cachesramwords-1:0];
logic CacheValid [numways-1:0] [numlines-1:0] [cachesramwords-1:0];
logic CacheDirty [numways-1:0] [numlines-1:0] [cachesramwords-1:0];
logic [P.PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [cachesramwords-1:0];
for(index = 0; index < numlines; index++) begin
for(way = 0; way < numways; way++) begin
for(cacheWord = 0; cacheWord < cachesramwords; cacheWord++) begin
copyShadow #(.P(P), .tagstart(tagstart),
.loglinebytelen(loglinebytelen), .sramlen(sramlen))
copyShadow(.clk,
.start,
.tag(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][P.PA_BITS-1-tagstart:0]),
.valid(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].ValidBits[index]),
.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]),
// these dirty bit selections would be needed if dirty is moved inside the tag array.
//.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]),
//.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][P.PA_BITS+tagstart]),
.data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].wordram.CacheDataMem.RAM[index]),
.index(index),
.cacheWord(cacheWord),
.CacheData(CacheData[way][index][cacheWord]),
.CacheAdr(CacheAdr[way][index][cacheWord]),
.CacheTag(CacheTag[way][index][cacheWord]),
.CacheValid(CacheValid[way][index][cacheWord]),
.CacheDirty(CacheDirty[way][index][cacheWord]));
end
end
end
integer i, j, k, l;
always @(posedge clk) begin
if (startD) begin
for(i = 0; i < numlines; i++) begin
for(j = 0; j < numways; j++) begin
for(l = 0; l < cachesramwords; l++) begin
if (CacheValid[j][i][l] & CacheDirty[j][i][l]) begin
for(k = 0; k < numwords; k++) begin
//cacheline = CacheData[j][i][0];
// does not work with modelsim
// # ** Error: ../testbench/testbench.sv(483): Range must be bounded by constant expressions.
// see https://verificationacademy.com/forums/systemverilog/range-must-be-bounded-constant-expressions
//ShadowRAM[CacheAdr[j][i][k] >> $clog2(P.XLEN/8)] = cacheline[P.XLEN*(k+1)-1:P.XLEN*k];
/* verilator lint_off WIDTHTRUNC */
// *** lint error: address trunc warning for shadowram index
ShadowRAM[(CacheAdr[j][i][l] >> $clog2(P.XLEN/8)) + {{{P.PA_BITS-32}{1'b0}}, k}] = CacheData[j][i][l][P.XLEN*k +: P.XLEN];
/* verilator lint_on WIDTHTRUNC */
end
end
end
end
end
end
end
end
flop #(1) doneReg1(.clk, .d(start), .q(startD));
flop #(1) doneReg2(.clk, .d(startD), .q(done));
endmodule
module copyShadow import cvw::*; #(parameter cvw_t P,
parameter tagstart, loglinebytelen, sramlen)
(input logic clk,
input logic start,
input logic [P.PA_BITS-1:tagstart] tag,
input logic valid, dirty,
input logic [sramlen-1:0] data,
input logic [32-1:0] index,
input logic [32-1:0] cacheWord,
output logic [sramlen-1:0] CacheData,
output logic [P.PA_BITS-1:0] CacheAdr,
output logic [P.XLEN-1:0] CacheTag,
output logic CacheValid,
output logic CacheDirty);
logic [P.XLEN+1:0] TagExtend;
logic [P.XLEN+1:0] IndexExtend;
logic [P.XLEN+1:0] CacheWordExtend;
logic [P.XLEN+1:0] CacheAdrExtend;
assign TagExtend = {{{P.XLEN-(P.PA_BITS-tagstart)+2}{1'b0}}, tag};
assign IndexExtend = {{{P.XLEN-32+2}{1'b0}}, index};
assign CacheWordExtend = {{{P.XLEN-32+2}{1'b0}}, cacheWord};
always_ff @(posedge clk) begin
if(start) begin
CacheTag = TagExtend[P.XLEN-1:0];
CacheValid = valid;
CacheDirty = dirty;
CacheData = data;
CacheAdrExtend = (TagExtend << tagstart) + (IndexExtend << loglinebytelen) + (CacheWordExtend << $clog2(sramlen/8));
end
end
assign CacheAdr = CacheAdrExtend[P.PA_BITS-1:0];
endmodule