mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'openhwgroup:main' into main
This commit is contained in:
commit
0b317c4823
34
src/cache/cache.sv
vendored
34
src/cache/cache.sv
vendored
@ -76,7 +76,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
logic [1:0] AdrSelMuxSel;
|
logic [1:0] AdrSelMuxSel;
|
||||||
logic [SETLEN-1:0] CacheSet;
|
logic [SETLEN-1:0] CacheSet;
|
||||||
logic [LINELEN-1:0] LineWriteData;
|
logic [LINELEN-1:0] LineWriteData;
|
||||||
logic ClearValid, ClearDirty, SetDirty, SetValid;
|
logic 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;
|
||||||
@ -116,7 +116,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
// 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, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
|
cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
|
||||||
.clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask,
|
.clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask,
|
||||||
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay,
|
.SetValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay,
|
||||||
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
||||||
|
|
||||||
// Select victim way for associative caches
|
// Select victim way for associative caches
|
||||||
@ -188,18 +188,24 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
// Flush logic
|
// Flush logic
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Flush address (line number)
|
if (!READ_ONLY_CACHE) begin:flushlogic
|
||||||
assign ResetOrFlushCntRst = reset | FlushCntRst;
|
// Flush address (line number)
|
||||||
flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr);
|
assign ResetOrFlushCntRst = reset | FlushCntRst;
|
||||||
mux2 #(SETLEN) FlushAdrMux(NextFlushAdr, FlushAdrP1, FlushAdrCntEn, FlushAdr);
|
flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr);
|
||||||
assign FlushAdrP1 = NextFlushAdr + 1'b1;
|
mux2 #(SETLEN) FlushAdrMux(NextFlushAdr, FlushAdrP1, FlushAdrCntEn, FlushAdr);
|
||||||
assign FlushAdrFlag = (NextFlushAdr == FLUSHADRTHRESHOLD[SETLEN-1:0]);
|
assign FlushAdrP1 = NextFlushAdr + 1'b1;
|
||||||
|
assign FlushAdrFlag = (NextFlushAdr == FLUSHADRTHRESHOLD[SETLEN-1:0]);
|
||||||
|
|
||||||
// Flush way
|
// Flush way
|
||||||
flopenl #(NUMWAYS) FlushWayReg(clk, FlushWayCntEn, ResetOrFlushCntRst, {{NUMWAYS-1{1'b0}}, 1'b1}, NextFlushWay, FlushWay);
|
flopenl #(NUMWAYS) FlushWayReg(clk, FlushWayCntEn, ResetOrFlushCntRst, {{NUMWAYS-1{1'b0}}, 1'b1}, NextFlushWay, FlushWay);
|
||||||
if(NUMWAYS > 1) assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]};
|
if(NUMWAYS > 1) assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]};
|
||||||
else assign NextFlushWay = FlushWay[NUMWAYS-1];
|
else assign NextFlushWay = FlushWay[NUMWAYS-1];
|
||||||
assign FlushWayFlag = FlushWay[NUMWAYS-1];
|
assign FlushWayFlag = FlushWay[NUMWAYS-1];
|
||||||
|
end // block: flushlogic
|
||||||
|
else begin:flushlogic
|
||||||
|
assign FlushWayFlag = 0;
|
||||||
|
assign FlushAdrFlag = 0;
|
||||||
|
end
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Cache FSM
|
// Cache FSM
|
||||||
@ -209,7 +215,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
.FlushStage, .CacheRW, .CacheAtomic, .Stall,
|
.FlushStage, .CacheRW, .CacheAtomic, .Stall,
|
||||||
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
||||||
.CacheMiss, .CacheAccess, .SelAdr,
|
.CacheMiss, .CacheAccess, .SelAdr,
|
||||||
.ClearValid, .ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush,
|
.ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush,
|
||||||
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
|
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
|
||||||
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
||||||
.InvalidateCache, .CacheEn, .LRUWriteEn);
|
.InvalidateCache, .CacheEn, .LRUWriteEn);
|
||||||
|
4
src/cache/cacheLRU.sv
vendored
4
src/cache/cacheLRU.sv
vendored
@ -67,11 +67,15 @@ module cacheLRU
|
|||||||
assign AllValid = &ValidWay;
|
assign AllValid = &ValidWay;
|
||||||
|
|
||||||
///// Update replacement bits.
|
///// Update replacement bits.
|
||||||
|
|
||||||
|
// coverage off
|
||||||
|
// Excluded from coverage b/c it is untestable without varying NUMWAYS.
|
||||||
function integer log2 (integer value);
|
function integer log2 (integer value);
|
||||||
for (log2=0; value>0; log2=log2+1)
|
for (log2=0; value>0; log2=log2+1)
|
||||||
value = value>>1;
|
value = value>>1;
|
||||||
return log2;
|
return log2;
|
||||||
endfunction // log2
|
endfunction // log2
|
||||||
|
// coverage on
|
||||||
|
|
||||||
// On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay.
|
// On a miss we need to ignore HitWay and derive the new replacement bits with the VictimWay.
|
||||||
mux2 #(NUMWAYS) WayMux(HitWay, VictimWay, SetValid, Way);
|
mux2 #(NUMWAYS) WayMux(HitWay, VictimWay, SetValid, Way);
|
||||||
|
2
src/cache/cachefsm.sv
vendored
2
src/cache/cachefsm.sv
vendored
@ -55,7 +55,6 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
input logic FlushAdrFlag, // On last set of a cache flush
|
input logic FlushAdrFlag, // On last set of a cache flush
|
||||||
input logic FlushWayFlag, // On the last way for any set of a cache flush
|
input logic FlushWayFlag, // On the last way for any set of a cache flush
|
||||||
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
|
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
|
||||||
output logic ClearValid, // Clear the valid bit in the selected way and set
|
|
||||||
output logic SetValid, // Set the dirty bit in the selected way and set
|
output logic SetValid, // Set the dirty bit in the selected way and set
|
||||||
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||||
output logic SetDirty, // Set the dirty bit in the selected way and set
|
output logic SetDirty, // Set the dirty bit in the selected way and set
|
||||||
@ -146,7 +145,6 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
assign SetValid = CurrState == STATE_WRITE_LINE;
|
assign SetValid = CurrState == STATE_WRITE_LINE;
|
||||||
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) |
|
assign SetDirty = (CurrState == STATE_READY & AnyUpdateHit) |
|
||||||
(CurrState == STATE_WRITE_LINE & (StoreAMO));
|
(CurrState == STATE_WRITE_LINE & (StoreAMO));
|
||||||
assign ClearValid = '0;
|
|
||||||
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) |
|
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) |
|
||||||
(CurrState == STATE_FLUSH & LineDirty); // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
(CurrState == STATE_FLUSH & LineDirty); // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
|
||||||
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
|
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
|
||||||
|
49
src/cache/cacheway.sv
vendored
49
src/cache/cacheway.sv
vendored
@ -38,8 +38,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
input logic [$clog2(NUMLINES)-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
|
input logic [$clog2(NUMLINES)-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
|
||||||
input logic [`PA_BITS-1:0] PAdr, // Physical address
|
input logic [`PA_BITS-1:0] PAdr, // Physical address
|
||||||
input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only)
|
input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only)
|
||||||
input logic SetValid, // Set the dirty bit in the selected way and set
|
input logic SetValid, // Set the valid bit in the selected way and set
|
||||||
input logic ClearValid, // Clear the valid bit in the selected way and set
|
|
||||||
input logic SetDirty, // Set the dirty bit in the selected way and set
|
input logic SetDirty, // Set the dirty bit in the selected way and set
|
||||||
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||||
input logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
input logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||||
@ -71,21 +70,25 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
logic [LINELEN/8-1:0] FinalByteMask;
|
logic [LINELEN/8-1:0] FinalByteMask;
|
||||||
logic SetValidEN;
|
logic SetValidEN;
|
||||||
logic SetValidWay;
|
logic SetValidWay;
|
||||||
logic ClearValidWay;
|
|
||||||
logic SetDirtyWay;
|
logic SetDirtyWay;
|
||||||
logic ClearDirtyWay;
|
logic ClearDirtyWay;
|
||||||
logic SelNonHit;
|
logic SelNonHit;
|
||||||
logic SelData;
|
logic SelData;
|
||||||
logic FlushWayEn, VictimWayEn;
|
|
||||||
|
|
||||||
// FlushWay and VictimWay are part of a one hot way selection. Must clear them if FlushWay not selected
|
|
||||||
// or VictimWay not selected.
|
|
||||||
assign FlushWayEn = FlushWay & SelFlush;
|
|
||||||
assign VictimWayEn = VictimWay & SelWriteback;
|
|
||||||
|
|
||||||
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
|
if (!READ_ONLY_CACHE) begin:flushlogic
|
||||||
|
logic FlushWayEn;
|
||||||
|
|
||||||
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
||||||
|
|
||||||
|
// FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected.
|
||||||
|
assign FlushWayEn = FlushWay & SelFlush;
|
||||||
|
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
|
||||||
|
end
|
||||||
|
else begin:flushlogic // no flush operation for read-only caches.
|
||||||
|
assign SelTag = VictimWay;
|
||||||
|
assign SelNonHit = SetValid;
|
||||||
|
end
|
||||||
|
|
||||||
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
|
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
|
||||||
|
|
||||||
@ -94,12 +97,16 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
assign SetValidWay = SetValid & SelData;
|
assign SetValidWay = SetValid & SelData;
|
||||||
assign ClearValidWay = ClearValid & SelData;
|
|
||||||
assign SetDirtyWay = SetDirty & SelData;
|
|
||||||
assign ClearDirtyWay = ClearDirty & SelData;
|
assign ClearDirtyWay = ClearDirty & SelData;
|
||||||
|
if (!READ_ONLY_CACHE) begin
|
||||||
|
assign SetDirtyWay = SetDirty & SelData;
|
||||||
|
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
assign SelectedWriteWordEn = SetValidWay & ~FlushStage;
|
||||||
|
end
|
||||||
|
|
||||||
// If writing the whole line set all write enables to 1, else only set the correct word.
|
// If writing the whole line set all write enables to 1, else only set the correct word.
|
||||||
assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage;
|
|
||||||
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
|
assign FinalByteMask = SetValidWay ? '1 : LineByteMask; // OR
|
||||||
assign SetValidEN = SetValidWay & ~FlushStage;
|
assign SetValidEN = SetValidWay & ~FlushStage;
|
||||||
|
|
||||||
@ -107,8 +114,8 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
// Tag Array
|
// Tag Array
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
||||||
.addr(CacheSet), .dout(ReadTag), .bwe('1),
|
.addr(CacheSet), .dout(ReadTag),
|
||||||
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
||||||
|
|
||||||
// AND portion of distributed tag multiplexer
|
// AND portion of distributed tag multiplexer
|
||||||
@ -128,10 +135,18 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
localparam LOGNUMSRAM = $clog2(NUMSRAM);
|
localparam LOGNUMSRAM = $clog2(NUMSRAM);
|
||||||
|
|
||||||
for(words = 0; words < NUMSRAM; words++) begin: word
|
for(words = 0; words < NUMSRAM; words++) begin: word
|
||||||
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
if (!READ_ONLY_CACHE) begin:wordram
|
||||||
|
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||||
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||||
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||||
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
|
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
|
||||||
|
end
|
||||||
|
else begin:wordram // no byte-enable needed for i$.
|
||||||
|
ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
|
||||||
|
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||||
|
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
|
||||||
|
.we(SelectedWriteWordEn));
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// AND portion of distributed read multiplexers
|
// AND portion of distributed read multiplexers
|
||||||
@ -146,7 +161,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
if(CacheEn) begin
|
if(CacheEn) begin
|
||||||
ValidWay <= #1 ValidBits[CacheSet];
|
ValidWay <= #1 ValidBits[CacheSet];
|
||||||
if(InvalidateCache) ValidBits <= #1 '0;
|
if(InvalidateCache) ValidBits <= #1 '0;
|
||||||
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay;
|
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
105
src/generic/mem/ram1p1rwe.sv
Normal file
105
src/generic/mem/ram1p1rwe.sv
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// 1 port sram.
|
||||||
|
//
|
||||||
|
// Written: avercruysse@hmc.edu (Modified from ram1p1rwbe, by ross1728@gmail.com)
|
||||||
|
// Created: 04 April 2023
|
||||||
|
//
|
||||||
|
// Purpose: ram1p1wre, but without byte-enable. Used for icache data.
|
||||||
|
// Be careful using this module, since coverage is turned off for (ce & we).
|
||||||
|
// In read-only caches, we never get (we=1, ce=0), so this waiver is needed.
|
||||||
|
//
|
||||||
|
// Documentation:
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module ram1p1rwe #(parameter DEPTH=64, WIDTH=44) (
|
||||||
|
input logic clk,
|
||||||
|
input logic ce,
|
||||||
|
input logic [$clog2(DEPTH)-1:0] addr,
|
||||||
|
input logic [WIDTH-1:0] din,
|
||||||
|
input logic we,
|
||||||
|
output logic [WIDTH-1:0] dout
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [WIDTH-1:0] RAM[DEPTH-1:0];
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// TRUE SRAM macro
|
||||||
|
// ***************************************************************************
|
||||||
|
if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
|
||||||
|
// 64 x 128-bit SRAM
|
||||||
|
ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||||
|
.A(addr), .D(din),
|
||||||
|
.BWEB('0), .Q(dout));
|
||||||
|
|
||||||
|
end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
|
||||||
|
// 64 x 44-bit SRAM
|
||||||
|
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||||
|
.A(addr), .D(din),
|
||||||
|
.BWEB('0), .Q(dout));
|
||||||
|
|
||||||
|
end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
|
||||||
|
// 64 x 22-bit SRAM
|
||||||
|
ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
|
||||||
|
.A(addr), .D(din),
|
||||||
|
.BWEB('0), .Q(dout));
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// READ first SRAM model
|
||||||
|
// ***************************************************************************
|
||||||
|
end else begin: ram
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
// Read
|
||||||
|
logic [$clog2(DEPTH)-1:0] addrd;
|
||||||
|
flopen #($clog2(DEPTH)) adrreg(clk, ce, addr, addrd);
|
||||||
|
assign dout = RAM[addrd];
|
||||||
|
|
||||||
|
/* // Read
|
||||||
|
always_ff @(posedge clk)
|
||||||
|
if(ce) dout <= #1 mem[addr]; */
|
||||||
|
|
||||||
|
// Write divided into part for bytes and part for extra msbs
|
||||||
|
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
|
||||||
|
// Therefore these always blocks use the older always @(posedge clk)
|
||||||
|
if(WIDTH >= 8)
|
||||||
|
always @(posedge clk)
|
||||||
|
// coverage off
|
||||||
|
// ce only goes low when cachefsm is in READY state and Flush is asserted.
|
||||||
|
// for read-only caches, we only goes high in the STATE_WRITE_LINE cachefsm state.
|
||||||
|
// so we can never get we=1, ce=0 for I$.
|
||||||
|
if (ce & we)
|
||||||
|
// coverage on
|
||||||
|
for(i = 0; i < WIDTH/8; i++)
|
||||||
|
RAM[addr][i*8 +: 8] <= #1 din[i*8 +: 8];
|
||||||
|
|
||||||
|
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
|
||||||
|
always @(posedge clk)
|
||||||
|
// coverage off
|
||||||
|
// (see the above explanation)
|
||||||
|
if (ce & we)
|
||||||
|
// coverage on
|
||||||
|
RAM[addr][WIDTH-1:WIDTH-WIDTH%8] <= #1 din[WIDTH-1:WIDTH-WIDTH%8];
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -724,7 +724,7 @@ module DCacheFlushFSM
|
|||||||
// these dirty bit selections would be needed if dirty is moved inside the tag array.
|
// 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].dirty.DirtyMem.RAM[index]),
|
||||||
//.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS+tagstart]),
|
//.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS+tagstart]),
|
||||||
.data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].CacheDataMem.RAM[index]),
|
.data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].wordram.CacheDataMem.RAM[index]),
|
||||||
.index(index),
|
.index(index),
|
||||||
.cacheWord(cacheWord),
|
.cacheWord(cacheWord),
|
||||||
.CacheData(CacheData[way][index][cacheWord]),
|
.CacheData(CacheData[way][index][cacheWord]),
|
||||||
|
@ -67,6 +67,7 @@ main:
|
|||||||
# fcvt.w.q a0, ft0
|
# fcvt.w.q a0, ft0
|
||||||
# fcvt.q.d ft3, ft0
|
# fcvt.q.d ft3, ft0
|
||||||
|
|
||||||
|
# Completing branch coverage in fctrl.sv
|
||||||
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
|
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
|
||||||
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
|
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
|
||||||
.word 0xd0400053 // Line 156 All False Test case - illegal instruction?
|
.word 0xd0400053 // Line 156 All False Test case - illegal instruction?
|
||||||
@ -74,6 +75,11 @@ main:
|
|||||||
.word 0xd2400053 // Line 168 All False Test case - illegal instruction?
|
.word 0xd2400053 // Line 168 All False Test case - illegal instruction?
|
||||||
.word 0xc2400053 // Line 174 All False Test case - illegal instruction?
|
.word 0xc2400053 // Line 174 All False Test case - illegal instruction?
|
||||||
|
|
||||||
|
# Increasing conditional coverage in fctrl.sv
|
||||||
|
.word 0xc5000007 // Attempting to toggle (Op7 != 7) to 0 on line 97 in fctrl, not sure what instruction this works out to
|
||||||
|
.word 0xe0101053 // toggling (Rs2D == 0) to 0 on line 139 in fctrl. Illegal Intsr (like fclass but incorrect rs2)
|
||||||
|
.word 0xe0100053 // toggling (Rs2D == 0) to 0 on line 141 in fctrl. Illegal Intsr (like fmv but incorrect rs2)
|
||||||
|
|
||||||
# Test illegal instructions are detected
|
# Test illegal instructions are detected
|
||||||
.word 0x00000007 // illegal floating-point load (bad Funct3)
|
.word 0x00000007 // illegal floating-point load (bad Funct3)
|
||||||
.word 0x00000027 // illegal floating-point store (bad Funct3)
|
.word 0x00000027 // illegal floating-point store (bad Funct3)
|
||||||
|
@ -35,20 +35,12 @@ main:
|
|||||||
//.hword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
|
//.hword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
|
||||||
// binary version 0000 0000 0000 0000 0010 0000 0000 0000
|
// binary version 0000 0000 0000 0000 0010 0000 0000 0000
|
||||||
mv s0, sp
|
mv s0, sp
|
||||||
c.fld fs0, 0(s0)
|
c.fld fs0, 0(s0) // Previously uncovered instructions
|
||||||
|
|
||||||
c.fsd fs0, 0(s0)
|
c.fsd fs0, 0(s0)
|
||||||
|
.hword 0x2002 // c.fldsp fs0, 0
|
||||||
|
.hword 0xA002 // c.fsdsp fs0, 0
|
||||||
|
.hword 0x9C41 // line 134 Illegal compressed instruction
|
||||||
|
|
||||||
// c.fldsp fs0, 0
|
//.hword 0x9C01 //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else
|
||||||
.hword 0x2002
|
|
||||||
|
|
||||||
// c.fsdsp fs0, 0
|
|
||||||
.hword 0xA002
|
|
||||||
|
|
||||||
//# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else
|
|
||||||
//.hword 0x9C01
|
|
||||||
|
|
||||||
# Line Illegal compressed instruction
|
|
||||||
.hword 0x9C41
|
|
||||||
|
|
||||||
j done
|
j done
|
||||||
|
Loading…
Reference in New Issue
Block a user