mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Changed names of address in caches.
Removed old cache files.
This commit is contained in:
parent
1ab3a17ff7
commit
e74e8c2e86
24
pipelined/src/cache/cache.sv
vendored
24
pipelined/src/cache/cache.sv
vendored
@ -36,9 +36,9 @@ module cache #(parameter integer LINELEN,
|
|||||||
input logic [1:0] RW,
|
input logic [1:0] RW,
|
||||||
input logic [1:0] Atomic,
|
input logic [1:0] Atomic,
|
||||||
input logic FlushCache,
|
input logic FlushCache,
|
||||||
input logic [11:0] LsuAdrE, // 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] LsuPAdrM, // physical address
|
input logic [`PA_BITS-1:0] PAdr, // physical address
|
||||||
input logic [11:0] PreLsuPAdrM, // physical or virtual address
|
input logic [11:0] NoTranAdr, // physical or virtual address
|
||||||
input logic [`XLEN-1:0] FinalWriteData,
|
input logic [`XLEN-1:0] FinalWriteData,
|
||||||
output logic [`XLEN-1:0] ReadDataWord,
|
output logic [`XLEN-1:0] ReadDataWord,
|
||||||
output logic CacheCommitted,
|
output logic CacheCommitted,
|
||||||
@ -121,8 +121,8 @@ module cache #(parameter integer LINELEN,
|
|||||||
// Read Path CPU (IEU) side
|
// Read Path CPU (IEU) side
|
||||||
|
|
||||||
mux3 #(INDEXLEN)
|
mux3 #(INDEXLEN)
|
||||||
AdrSelMux(.d0(LsuAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
AdrSelMux(.d0(NextAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||||
.d1(PreLsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
.d1(NoTranAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||||
.d2(FlushAdr),
|
.d2(FlushAdr),
|
||||||
.s(SelAdr),
|
.s(SelAdr),
|
||||||
.y(RAdr));
|
.y(RAdr));
|
||||||
@ -132,7 +132,7 @@ module cache #(parameter integer LINELEN,
|
|||||||
cacheway #(.NUMLINES(NUMLINES), .LINELEN(LINELEN), .TAGLEN(TAGLEN),
|
cacheway #(.NUMLINES(NUMLINES), .LINELEN(LINELEN), .TAGLEN(TAGLEN),
|
||||||
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN))
|
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN))
|
||||||
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
|
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
|
||||||
.PAdr(LsuPAdrM),
|
.PAdr(PAdr),
|
||||||
.WriteEnable(SRAMWayWriteEnable),
|
.WriteEnable(SRAMWayWriteEnable),
|
||||||
.VDWriteEnable(VDWriteEnableWay),
|
.VDWriteEnable(VDWriteEnableWay),
|
||||||
.WriteWordEnable(SRAMWordEnable),
|
.WriteWordEnable(SRAMWordEnable),
|
||||||
@ -149,7 +149,7 @@ module cache #(parameter integer LINELEN,
|
|||||||
cachereplacementpolicy(.clk, .reset,
|
cachereplacementpolicy(.clk, .reset,
|
||||||
.WayHit,
|
.WayHit,
|
||||||
.VictimWay,
|
.VictimWay,
|
||||||
.LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
.PAdr(PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||||
.RAdr,
|
.RAdr,
|
||||||
.LRUWriteEn);
|
.LRUWriteEn);
|
||||||
end else begin:vict
|
end else begin:vict
|
||||||
@ -176,14 +176,14 @@ module cache #(parameter integer LINELEN,
|
|||||||
assign ReadDataLineSets[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
assign ReadDataLineSets[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
||||||
end
|
end
|
||||||
// variable input mux
|
// variable input mux
|
||||||
assign ReadDataWord = ReadDataLineSets[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]];
|
assign ReadDataWord = ReadDataLineSets[PAdr[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]];
|
||||||
end else begin: readdata
|
end else begin: readdata
|
||||||
logic [31:0] ReadLineSetsF [LINELEN/16-1:0];
|
logic [31:0] ReadLineSetsF [LINELEN/16-1:0];
|
||||||
logic [31:0] FinalInstrRawF;
|
logic [31:0] FinalInstrRawF;
|
||||||
for(index = 0; index < LINELEN / 16 - 1; index++)
|
for(index = 0; index < LINELEN / 16 - 1; index++)
|
||||||
assign ReadLineSetsF[index] = ReadDataLineM[((index+1)*16)+16-1 : (index*16)];
|
assign ReadLineSetsF[index] = ReadDataLineM[((index+1)*16)+16-1 : (index*16)];
|
||||||
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadDataLineM[LINELEN-1:LINELEN-16]};
|
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadDataLineM[LINELEN-1:LINELEN-16]};
|
||||||
assign FinalInstrRawF = ReadLineSetsF[LsuPAdrM[$clog2(LINELEN / 32) + 1 : 1]];
|
assign FinalInstrRawF = ReadLineSetsF[PAdr[$clog2(LINELEN / 32) + 1 : 1]];
|
||||||
if (`XLEN == 64) assign ReadDataWord = {32'b0, FinalInstrRawF};
|
if (`XLEN == 64) assign ReadDataWord = {32'b0, FinalInstrRawF};
|
||||||
else assign ReadDataWord = FinalInstrRawF;
|
else assign ReadDataWord = FinalInstrRawF;
|
||||||
end
|
end
|
||||||
@ -191,7 +191,7 @@ module cache #(parameter integer LINELEN,
|
|||||||
// Write Path CPU (IEU) side
|
// Write Path CPU (IEU) side
|
||||||
|
|
||||||
onehotdecoder #(LOGWPL)
|
onehotdecoder #(LOGWPL)
|
||||||
adrdec(.bin(LsuPAdrM[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]),
|
adrdec(.bin(PAdr[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]),
|
||||||
.decoded(MemPAdrDecodedW));
|
.decoded(MemPAdrDecodedW));
|
||||||
|
|
||||||
assign SRAMWordEnable = SRAMLineWriteEnableM ? '1 : MemPAdrDecodedW;
|
assign SRAMWordEnable = SRAMLineWriteEnableM ? '1 : MemPAdrDecodedW;
|
||||||
@ -211,8 +211,8 @@ module cache #(parameter integer LINELEN,
|
|||||||
.y(SRAMWriteData));
|
.y(SRAMWriteData));
|
||||||
|
|
||||||
|
|
||||||
mux3 #(`PA_BITS) BaseAdrMux(.d0({LsuPAdrM[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
mux3 #(`PA_BITS) BaseAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
||||||
.d1({VictimTag, LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
.d1({VictimTag, PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
||||||
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
|
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
|
||||||
.s({SelFlush, SelEvict}),
|
.s({SelFlush, SelEvict}),
|
||||||
.y(CacheBusAdr));
|
.y(CacheBusAdr));
|
||||||
|
12
pipelined/src/cache/cachereplacementpolicy.sv
vendored
12
pipelined/src/cache/cachereplacementpolicy.sv
vendored
@ -29,7 +29,7 @@ module cachereplacementpolicy
|
|||||||
(input logic clk, reset,
|
(input logic clk, reset,
|
||||||
input logic [NUMWAYS-1:0] WayHit,
|
input logic [NUMWAYS-1:0] WayHit,
|
||||||
output logic [NUMWAYS-1:0] VictimWay,
|
output logic [NUMWAYS-1:0] VictimWay,
|
||||||
input logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] LsuPAdrM,
|
input logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] PAdr,
|
||||||
input logic [INDEXLEN-1:0] RAdr,
|
input logic [INDEXLEN-1:0] RAdr,
|
||||||
input logic LRUWriteEn
|
input logic LRUWriteEn
|
||||||
);
|
);
|
||||||
@ -44,7 +44,7 @@ module cachereplacementpolicy
|
|||||||
logic [NUMWAYS-2:0] NewReplacement;
|
logic [NUMWAYS-2:0] NewReplacement;
|
||||||
logic [NUMWAYS-2:0] NewReplacementD;
|
logic [NUMWAYS-2:0] NewReplacementD;
|
||||||
|
|
||||||
logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] LsuPAdrMD;
|
logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] PAdrD;
|
||||||
logic [INDEXLEN-1:0] RAdrD;
|
logic [INDEXLEN-1:0] RAdrD;
|
||||||
logic LRUWriteEnD;
|
logic LRUWriteEnD;
|
||||||
|
|
||||||
@ -52,18 +52,18 @@ module cachereplacementpolicy
|
|||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
RAdrD <= '0;
|
RAdrD <= '0;
|
||||||
LsuPAdrMD <= '0;
|
PAdrD <= '0;
|
||||||
LRUWriteEnD <= 0;
|
LRUWriteEnD <= 0;
|
||||||
NewReplacementD <= '0;
|
NewReplacementD <= '0;
|
||||||
for(int index = 0; index < NUMLINES; index++)
|
for(int index = 0; index < NUMLINES; index++)
|
||||||
ReplacementBits[index] <= '0;
|
ReplacementBits[index] <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
RAdrD <= RAdr;
|
RAdrD <= RAdr;
|
||||||
LsuPAdrMD <= LsuPAdrM;
|
PAdrD <= PAdr;
|
||||||
LRUWriteEnD <= LRUWriteEn;
|
LRUWriteEnD <= LRUWriteEn;
|
||||||
NewReplacementD <= NewReplacement;
|
NewReplacementD <= NewReplacement;
|
||||||
if (LRUWriteEnD) begin
|
if (LRUWriteEnD) begin
|
||||||
ReplacementBits[LsuPAdrMD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD;
|
ReplacementBits[PAdrD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
254
pipelined/src/cache/dcache.sv
vendored
254
pipelined/src/cache/dcache.sv
vendored
@ -1,254 +0,0 @@
|
|||||||
///////////////////////////////////////////
|
|
||||||
// dcache (data cache)
|
|
||||||
//
|
|
||||||
// Written: ross1728@gmail.com July 07, 2021
|
|
||||||
// Implements the L1 data cache
|
|
||||||
//
|
|
||||||
// Purpose: Storage for data and meta data.
|
|
||||||
//
|
|
||||||
// A component of the Wally configurable RISC-V project.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
||||||
//
|
|
||||||
// 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 substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
///////////////////////////////////////////
|
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module dcache #(parameter integer LINELEN,
|
|
||||||
parameter integer NUMLINES,
|
|
||||||
parameter integer NUMWAYS)
|
|
||||||
(input logic clk,
|
|
||||||
input logic reset,
|
|
||||||
input logic CPUBusy,
|
|
||||||
|
|
||||||
// mmu
|
|
||||||
input logic CacheableM,
|
|
||||||
// cpu side
|
|
||||||
input logic [1:0] LsuRWM,
|
|
||||||
input logic [1:0] LsuAtomicM,
|
|
||||||
input logic FlushDCacheM,
|
|
||||||
input logic [11:0] LsuAdrE, // virtual address, but we only use the lower 12 bits.
|
|
||||||
input logic [`PA_BITS-1:0] LsuPAdrM, // physical address
|
|
||||||
input logic [11:0] PreLsuPAdrM, // physical or virtual address
|
|
||||||
input logic [`XLEN-1:0] FinalWriteDataM,
|
|
||||||
output logic [`XLEN-1:0] ReadDataWordM,
|
|
||||||
output logic DCacheCommittedM,
|
|
||||||
|
|
||||||
// Bus fsm interface
|
|
||||||
input logic IgnoreRequest,
|
|
||||||
output logic DCacheFetchLine,
|
|
||||||
output logic DCacheWriteLine,
|
|
||||||
|
|
||||||
input logic DCacheBusAck,
|
|
||||||
output logic [`PA_BITS-1:0] DCacheBusAdr,
|
|
||||||
|
|
||||||
|
|
||||||
input logic [LINELEN-1:0] DCacheMemWriteData,
|
|
||||||
output logic [`XLEN-1:0] ReadDataLineSetsM [(LINELEN/`XLEN)-1:0],
|
|
||||||
|
|
||||||
output logic DCacheStall,
|
|
||||||
|
|
||||||
// to performance counters
|
|
||||||
output logic DCacheMiss,
|
|
||||||
output logic DCacheAccess
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
localparam integer LINEBYTELEN = LINELEN/8;
|
|
||||||
localparam integer OFFSETLEN = $clog2(LINEBYTELEN);
|
|
||||||
localparam integer INDEXLEN = $clog2(NUMLINES);
|
|
||||||
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
|
|
||||||
localparam integer WORDSPERLINE = LINELEN/`XLEN;
|
|
||||||
localparam integer LOGWPL = $clog2(WORDSPERLINE);
|
|
||||||
localparam integer LOGXLENBYTES = $clog2(`XLEN/8);
|
|
||||||
|
|
||||||
localparam integer FlushAdrThreshold = NUMLINES;
|
|
||||||
|
|
||||||
logic [1:0] SelAdrM;
|
|
||||||
logic [INDEXLEN-1:0] RAdr;
|
|
||||||
logic [LINELEN-1:0] SRAMWriteData;
|
|
||||||
logic SetValid, ClearValid;
|
|
||||||
logic SetDirty, ClearDirty;
|
|
||||||
logic [LINELEN-1:0] ReadDataLineWayMasked [NUMWAYS-1:0];
|
|
||||||
logic [NUMWAYS-1:0] WayHit;
|
|
||||||
logic CacheHit;
|
|
||||||
logic [LINELEN-1:0] ReadDataLineM;
|
|
||||||
logic [WORDSPERLINE-1:0] SRAMWordEnable;
|
|
||||||
|
|
||||||
logic SRAMWordWriteEnableM;
|
|
||||||
logic SRAMLineWriteEnableM;
|
|
||||||
logic [NUMWAYS-1:0] SRAMLineWayWriteEnableM;
|
|
||||||
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
|
|
||||||
|
|
||||||
|
|
||||||
logic [NUMWAYS-1:0] VictimWay;
|
|
||||||
logic [NUMWAYS-1:0] VictimDirtyWay;
|
|
||||||
logic VictimDirty;
|
|
||||||
|
|
||||||
logic [2**LOGWPL-1:0] MemPAdrDecodedW;
|
|
||||||
|
|
||||||
logic [TAGLEN-1:0] VictimTagWay [NUMWAYS-1:0];
|
|
||||||
logic [TAGLEN-1:0] VictimTag;
|
|
||||||
|
|
||||||
logic [INDEXLEN-1:0] FlushAdr;
|
|
||||||
logic [INDEXLEN-1:0] FlushAdrP1;
|
|
||||||
logic [INDEXLEN-1:0] FlushAdrQ;
|
|
||||||
logic FlushAdrCntEn;
|
|
||||||
logic FlushAdrCntRst;
|
|
||||||
logic FlushAdrFlag;
|
|
||||||
|
|
||||||
logic [NUMWAYS-1:0] FlushWay;
|
|
||||||
logic [NUMWAYS-1:0] NextFlushWay;
|
|
||||||
logic FlushWayCntEn;
|
|
||||||
logic FlushWayCntRst;
|
|
||||||
|
|
||||||
logic VDWriteEnable;
|
|
||||||
logic SelEvict;
|
|
||||||
logic LRUWriteEn;
|
|
||||||
logic [NUMWAYS-1:0] VDWriteEnableWay;
|
|
||||||
logic SelFlush;
|
|
||||||
|
|
||||||
// Read Path CPU (IEU) side
|
|
||||||
|
|
||||||
mux3 #(INDEXLEN)
|
|
||||||
AdrSelMux(.d0(LsuAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.d1(PreLsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.d2(FlushAdr),
|
|
||||||
.s(SelAdrM),
|
|
||||||
.y(RAdr));
|
|
||||||
|
|
||||||
cacheway #(.NUMLINES(NUMLINES), .LINELEN(LINELEN), .TAGLEN(TAGLEN),
|
|
||||||
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN))
|
|
||||||
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
|
|
||||||
.PAdr(LsuPAdrM),
|
|
||||||
.WriteEnable(SRAMWayWriteEnable),
|
|
||||||
.VDWriteEnable(VDWriteEnableWay),
|
|
||||||
.WriteWordEnable(SRAMWordEnable),
|
|
||||||
.TagWriteEnable(SRAMLineWayWriteEnableM),
|
|
||||||
.WriteData(SRAMWriteData),
|
|
||||||
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelEvict,
|
|
||||||
.VictimWay, .FlushWay, .SelFlush,
|
|
||||||
.ReadDataLineWayMasked,
|
|
||||||
.WayHit, .VictimDirtyWay, .VictimTagWay,
|
|
||||||
.InvalidateAll(1'b0));
|
|
||||||
|
|
||||||
if(NUMWAYS > 1) begin:vict
|
|
||||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
|
||||||
cachereplacementpolicy(.clk, .reset,
|
|
||||||
.WayHit,
|
|
||||||
.VictimWay,
|
|
||||||
.LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.RAdr,
|
|
||||||
.LRUWriteEn);
|
|
||||||
end else begin:vict
|
|
||||||
assign VictimWay = 1'b1; // one hot.
|
|
||||||
end
|
|
||||||
|
|
||||||
assign CacheHit = | WayHit;
|
|
||||||
assign VictimDirty = | VictimDirtyWay;
|
|
||||||
|
|
||||||
|
|
||||||
// ReadDataLineWayMaskedM is a 2d array of cache line len by number of ways.
|
|
||||||
// Need to OR together each way in a bitwise manner.
|
|
||||||
// Final part of the AO Mux. First is the AND in the cacheway.
|
|
||||||
or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadDataLineM));
|
|
||||||
or_rows #(NUMWAYS, TAGLEN) VictimTagAOMux(.a(VictimTagWay), .y(VictimTag));
|
|
||||||
|
|
||||||
|
|
||||||
// Convert the Read data bus ReadDataSelectWay into sets of XLEN so we can
|
|
||||||
// easily build a variable input mux.
|
|
||||||
// *** consider using a limited range shift to do this final muxing.
|
|
||||||
genvar index;
|
|
||||||
for (index = 0; index < WORDSPERLINE; index++)
|
|
||||||
assign ReadDataLineSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
|
|
||||||
|
|
||||||
// variable input mux
|
|
||||||
|
|
||||||
assign ReadDataWordM = ReadDataLineSetsM[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]];
|
|
||||||
|
|
||||||
// Write Path CPU (IEU) side
|
|
||||||
|
|
||||||
onehotdecoder #(LOGWPL)
|
|
||||||
adrdec(.bin(LsuPAdrM[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]),
|
|
||||||
.decoded(MemPAdrDecodedW));
|
|
||||||
|
|
||||||
assign SRAMWordEnable = SRAMLineWriteEnableM ? '1 : MemPAdrDecodedW;
|
|
||||||
|
|
||||||
assign SRAMLineWayWriteEnableM = SRAMLineWriteEnableM ? VictimWay : '0;
|
|
||||||
|
|
||||||
mux2 #(NUMWAYS) WriteEnableMux(.d0(SRAMWordWriteEnableM ? WayHit : '0),
|
|
||||||
.d1(SRAMLineWayWriteEnableM),
|
|
||||||
.s(SRAMLineWriteEnableM),
|
|
||||||
.y(SRAMWayWriteEnable));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteDataM}}),
|
|
||||||
.d1(DCacheMemWriteData),
|
|
||||||
.s(SRAMLineWriteEnableM),
|
|
||||||
.y(SRAMWriteData));
|
|
||||||
|
|
||||||
|
|
||||||
mux3 #(`PA_BITS) BaseAdrMux(.d0({LsuPAdrM[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
|
||||||
.d1({VictimTag, LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
|
|
||||||
.d2({VictimTag, FlushAdrQ, {{OFFSETLEN}{1'b0}}}),
|
|
||||||
.s({SelFlush, SelEvict}),
|
|
||||||
.y(DCacheBusAdr));
|
|
||||||
|
|
||||||
|
|
||||||
// flush address and way generation.
|
|
||||||
// increment on 2nd to last way
|
|
||||||
flopenr #(INDEXLEN)
|
|
||||||
FlushAdrReg(.clk,
|
|
||||||
.reset(reset | FlushAdrCntRst),
|
|
||||||
.en(FlushAdrCntEn & FlushWay[NUMWAYS-2]),
|
|
||||||
.d(FlushAdrP1),
|
|
||||||
.q(FlushAdr));
|
|
||||||
assign FlushAdrP1 = FlushAdr + 1'b1;
|
|
||||||
|
|
||||||
flopenr #(INDEXLEN)
|
|
||||||
FlushAdrQReg(.clk,
|
|
||||||
.reset(reset | FlushAdrCntRst),
|
|
||||||
.en(FlushAdrCntEn),
|
|
||||||
.d(FlushAdr),
|
|
||||||
.q(FlushAdrQ));
|
|
||||||
|
|
||||||
flopenl #(NUMWAYS)
|
|
||||||
FlushWayReg(.clk,
|
|
||||||
.load(reset | FlushWayCntRst),
|
|
||||||
.en(FlushWayCntEn),
|
|
||||||
.val({{NUMWAYS-1{1'b0}}, 1'b1}),
|
|
||||||
.d(NextFlushWay),
|
|
||||||
.q(FlushWay));
|
|
||||||
|
|
||||||
assign VDWriteEnableWay = FlushWay & {NUMWAYS{VDWriteEnable}};
|
|
||||||
|
|
||||||
assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]};
|
|
||||||
|
|
||||||
assign FlushAdrFlag = FlushAdr == FlushAdrThreshold[INDEXLEN-1:0] & FlushWay[NUMWAYS-1];
|
|
||||||
|
|
||||||
// controller
|
|
||||||
|
|
||||||
dcachefsm dcachefsm(.clk, .reset, .DCacheFetchLine, .DCacheWriteLine, .DCacheBusAck,
|
|
||||||
.LsuRWM, .LsuAtomicM, .CPUBusy, .CacheableM, .IgnoreRequest,
|
|
||||||
.CacheHit, .VictimDirty, .DCacheStall, .DCacheCommittedM,
|
|
||||||
.DCacheMiss, .DCacheAccess, .SelAdrM, .SetValid,
|
|
||||||
.ClearValid, .SetDirty, .ClearDirty, .SRAMWordWriteEnableM,
|
|
||||||
.SRAMLineWriteEnableM, .SelEvict, .SelFlush,
|
|
||||||
.FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst,
|
|
||||||
.FlushWayCntRst, .FlushAdrFlag, .FlushDCacheM,
|
|
||||||
.VDWriteEnable, .LRUWriteEn);
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // dcache
|
|
398
pipelined/src/cache/dcachefsm.sv
vendored
398
pipelined/src/cache/dcachefsm.sv
vendored
@ -1,398 +0,0 @@
|
|||||||
///////////////////////////////////////////
|
|
||||||
// dcache (data cache) fsm
|
|
||||||
//
|
|
||||||
// Written: ross1728@gmail.com August 25, 2021
|
|
||||||
// Implements the L1 data cache fsm
|
|
||||||
//
|
|
||||||
// Purpose: Controller for the dcache fsm
|
|
||||||
//
|
|
||||||
// A component of the Wally configurable RISC-V project.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
||||||
//
|
|
||||||
// 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 substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
///////////////////////////////////////////
|
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module dcachefsm
|
|
||||||
(input logic clk,
|
|
||||||
input logic reset,
|
|
||||||
// inputs from IEU
|
|
||||||
input logic [1:0] LsuRWM,
|
|
||||||
input logic [1:0] LsuAtomicM,
|
|
||||||
input logic FlushDCacheM,
|
|
||||||
// hazard inputs
|
|
||||||
input logic CPUBusy,
|
|
||||||
input logic CacheableM,
|
|
||||||
// interlock fsm
|
|
||||||
input logic IgnoreRequest,
|
|
||||||
// Bus inputs
|
|
||||||
input logic DCacheBusAck,
|
|
||||||
// dcache internals
|
|
||||||
input logic CacheHit,
|
|
||||||
input logic VictimDirty,
|
|
||||||
input logic FlushAdrFlag,
|
|
||||||
|
|
||||||
// hazard outputs
|
|
||||||
output logic DCacheStall,
|
|
||||||
// counter outputs
|
|
||||||
output logic DCacheMiss,
|
|
||||||
output logic DCacheAccess,
|
|
||||||
// Bus outputs
|
|
||||||
output logic DCacheCommittedM,
|
|
||||||
output logic DCacheWriteLine,
|
|
||||||
output logic DCacheFetchLine,
|
|
||||||
|
|
||||||
// dcache internals
|
|
||||||
output logic [1:0] SelAdrM,
|
|
||||||
output logic SetValid,
|
|
||||||
output logic ClearValid,
|
|
||||||
output logic SetDirty,
|
|
||||||
output logic ClearDirty,
|
|
||||||
output logic SRAMWordWriteEnableM,
|
|
||||||
output logic SRAMLineWriteEnableM,
|
|
||||||
output logic SelEvict,
|
|
||||||
output logic LRUWriteEn,
|
|
||||||
output logic SelFlush,
|
|
||||||
output logic FlushAdrCntEn,
|
|
||||||
output logic FlushWayCntEn,
|
|
||||||
output logic FlushAdrCntRst,
|
|
||||||
output logic FlushWayCntRst,
|
|
||||||
output logic VDWriteEnable
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
logic AnyCPUReqM;
|
|
||||||
|
|
||||||
typedef enum {STATE_READY,
|
|
||||||
|
|
||||||
STATE_MISS_FETCH_WDV,
|
|
||||||
STATE_MISS_FETCH_DONE,
|
|
||||||
STATE_MISS_EVICT_DIRTY,
|
|
||||||
STATE_MISS_WRITE_CACHE_LINE,
|
|
||||||
STATE_MISS_READ_WORD,
|
|
||||||
STATE_MISS_READ_WORD_DELAY,
|
|
||||||
STATE_MISS_WRITE_WORD,
|
|
||||||
|
|
||||||
STATE_CPU_BUSY,
|
|
||||||
STATE_CPU_BUSY_FINISH_AMO,
|
|
||||||
|
|
||||||
STATE_FLUSH,
|
|
||||||
STATE_FLUSH_WRITE_BACK,
|
|
||||||
STATE_FLUSH_CLEAR_DIRTY} statetype;
|
|
||||||
|
|
||||||
(* mark_debug = "true" *) statetype CurrState, NextState;
|
|
||||||
|
|
||||||
assign AnyCPUReqM = |LsuRWM | (|LsuAtomicM);
|
|
||||||
|
|
||||||
// outputs for the performance counters.
|
|
||||||
assign DCacheAccess = AnyCPUReqM & CacheableM & CurrState == STATE_READY;
|
|
||||||
assign DCacheMiss = DCacheAccess & CacheableM & ~CacheHit;
|
|
||||||
|
|
||||||
always_ff @(posedge clk)
|
|
||||||
if (reset) CurrState <= #1 STATE_READY;
|
|
||||||
else CurrState <= #1 NextState;
|
|
||||||
|
|
||||||
// next state logic and some state ouputs.
|
|
||||||
always_comb begin
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
SelAdrM = 2'b00;
|
|
||||||
SetValid = 1'b0;
|
|
||||||
ClearValid = 1'b0;
|
|
||||||
SetDirty = 1'b0;
|
|
||||||
ClearDirty = 1'b0;
|
|
||||||
SRAMWordWriteEnableM = 1'b0;
|
|
||||||
SRAMLineWriteEnableM = 1'b0;
|
|
||||||
SelEvict = 1'b0;
|
|
||||||
LRUWriteEn = 1'b0;
|
|
||||||
SelFlush = 1'b0;
|
|
||||||
FlushAdrCntEn = 1'b0;
|
|
||||||
FlushWayCntEn = 1'b0;
|
|
||||||
FlushAdrCntRst = 1'b0;
|
|
||||||
FlushWayCntRst = 1'b0;
|
|
||||||
VDWriteEnable = 1'b0;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
DCacheFetchLine = 1'b0;
|
|
||||||
DCacheWriteLine = 1'b0;
|
|
||||||
|
|
||||||
case (CurrState)
|
|
||||||
STATE_READY: begin
|
|
||||||
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
SelAdrM = 2'b00;
|
|
||||||
SRAMWordWriteEnableM = 1'b0;
|
|
||||||
SetDirty = 1'b0;
|
|
||||||
LRUWriteEn = 1'b0;
|
|
||||||
|
|
||||||
// TLB Miss
|
|
||||||
if(IgnoreRequest) begin
|
|
||||||
// the LSU arbiter has not yet selected the PTW.
|
|
||||||
// The CPU needs to be stalled until that happens.
|
|
||||||
// If we set DCacheStall for 1 cycle before going to
|
|
||||||
// PTW ready the CPU will stall.
|
|
||||||
// The page table walker asserts it's control 1 cycle
|
|
||||||
// after the TLBs miss.
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Flush dcache to next level of memory
|
|
||||||
else if(FlushDCacheM) begin
|
|
||||||
NextState = STATE_FLUSH;
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b10;
|
|
||||||
FlushAdrCntRst = 1'b1;
|
|
||||||
FlushWayCntRst = 1'b1;
|
|
||||||
end
|
|
||||||
|
|
||||||
// amo hit
|
|
||||||
else if(LsuAtomicM[1] & (&LsuRWM) & CacheableM & CacheHit) begin
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_FINISH_AMO;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
SRAMWordWriteEnableM = 1'b1;
|
|
||||||
SetDirty = 1'b1;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
// read hit valid cached
|
|
||||||
else if(LsuRWM[1] & CacheableM & CacheHit) begin
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
// write hit valid cached
|
|
||||||
else if (LsuRWM[0] & CacheableM & CacheHit) begin
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
SRAMWordWriteEnableM = 1'b1;
|
|
||||||
SetDirty = 1'b1;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
// read or write miss valid cached
|
|
||||||
else if((|LsuRWM) & CacheableM & ~CacheHit) begin
|
|
||||||
NextState = STATE_MISS_FETCH_WDV;
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
DCacheFetchLine = 1'b1;
|
|
||||||
end
|
|
||||||
else NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_FETCH_WDV: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
|
|
||||||
if (DCacheBusAck) begin
|
|
||||||
NextState = STATE_MISS_FETCH_DONE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_FETCH_DONE: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
if(VictimDirty) begin
|
|
||||||
NextState = STATE_MISS_EVICT_DIRTY;
|
|
||||||
DCacheWriteLine = 1'b1;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_WRITE_CACHE_LINE;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_WRITE_CACHE_LINE: begin
|
|
||||||
SRAMLineWriteEnableM = 1'b1;
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
NextState = STATE_MISS_READ_WORD;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
SetValid = 1'b1;
|
|
||||||
ClearDirty = 1'b1;
|
|
||||||
//LRUWriteEn = 1'b1; // DO not update LRU on SRAM fetch update. Wait for subsequent read/write
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_READ_WORD: begin
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
if (LsuRWM[0] & ~LsuAtomicM[1]) begin // handles stores and amo write.
|
|
||||||
NextState = STATE_MISS_WRITE_WORD;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_READ_WORD_DELAY;
|
|
||||||
// delay state is required as the read signal LsuRWM[1] is still high when we
|
|
||||||
// return to the ready state because the cache is stalling the cpu.
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_READ_WORD_DELAY: begin
|
|
||||||
//SelAdrM = 2'b01;
|
|
||||||
SRAMWordWriteEnableM = 1'b0;
|
|
||||||
SetDirty = 1'b0;
|
|
||||||
LRUWriteEn = 1'b0;
|
|
||||||
if(&LsuRWM & LsuAtomicM[1]) begin // amo write
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_FINISH_AMO;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
SRAMWordWriteEnableM = 1'b1;
|
|
||||||
SetDirty = 1'b1;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_WRITE_WORD: begin
|
|
||||||
SRAMWordWriteEnableM = 1'b1;
|
|
||||||
SetDirty = 1'b1;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_MISS_EVICT_DIRTY: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
SelEvict = 1'b1;
|
|
||||||
if(DCacheBusAck) begin
|
|
||||||
NextState = STATE_MISS_WRITE_CACHE_LINE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_EVICT_DIRTY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
STATE_CPU_BUSY: begin
|
|
||||||
SelAdrM = 2'b00;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_CPU_BUSY_FINISH_AMO: begin
|
|
||||||
SelAdrM = 2'b01;
|
|
||||||
SRAMWordWriteEnableM = 1'b0;
|
|
||||||
SetDirty = 1'b0;
|
|
||||||
LRUWriteEn = 1'b0;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_FINISH_AMO;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
SRAMWordWriteEnableM = 1'b1;
|
|
||||||
SetDirty = 1'b1;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_FLUSH: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b10;
|
|
||||||
SelFlush = 1'b1;
|
|
||||||
FlushAdrCntEn = 1'b1;
|
|
||||||
FlushWayCntEn = 1'b1;
|
|
||||||
if(VictimDirty) begin
|
|
||||||
NextState = STATE_FLUSH_WRITE_BACK;
|
|
||||||
FlushAdrCntEn = 1'b0;
|
|
||||||
FlushWayCntEn = 1'b0;
|
|
||||||
DCacheWriteLine = 1'b1;
|
|
||||||
end else if (FlushAdrFlag) begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
FlushAdrCntEn = 1'b0;
|
|
||||||
FlushWayCntEn = 1'b0;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_FLUSH;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_FLUSH_WRITE_BACK: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
SelAdrM = 2'b10;
|
|
||||||
SelFlush = 1'b1;
|
|
||||||
if(DCacheBusAck) begin
|
|
||||||
NextState = STATE_FLUSH_CLEAR_DIRTY;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_FLUSH_WRITE_BACK;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
STATE_FLUSH_CLEAR_DIRTY: begin
|
|
||||||
DCacheStall = 1'b1;
|
|
||||||
ClearDirty = 1'b1;
|
|
||||||
VDWriteEnable = 1'b1;
|
|
||||||
SelFlush = 1'b1;
|
|
||||||
SelAdrM = 2'b10;
|
|
||||||
FlushAdrCntEn = 1'b0;
|
|
||||||
FlushWayCntEn = 1'b0;
|
|
||||||
if(FlushAdrFlag) begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
DCacheStall = 1'b0;
|
|
||||||
SelAdrM = 2'b00;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_FLUSH;
|
|
||||||
FlushAdrCntEn = 1'b1;
|
|
||||||
FlushWayCntEn = 1'b1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
default: begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
assign DCacheCommittedM = CurrState != STATE_READY;
|
|
||||||
|
|
||||||
endmodule // dcachefsm
|
|
||||||
|
|
165
pipelined/src/cache/icache.sv
vendored
165
pipelined/src/cache/icache.sv
vendored
@ -1,165 +0,0 @@
|
|||||||
///////////////////////////////////////////
|
|
||||||
// icache.sv
|
|
||||||
//
|
|
||||||
// Written: jaallen@g.hmc.edu 2021-03-02
|
|
||||||
// Modified:
|
|
||||||
//
|
|
||||||
// Purpose: Cache instructions for the ifu so it can access memory less often, saving cycles
|
|
||||||
//
|
|
||||||
// A component of the Wally configurable RISC-V project.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
||||||
//
|
|
||||||
// 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 substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
///////////////////////////////////////////
|
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module icache #(parameter integer LINELEN,
|
|
||||||
parameter integer NUMLINES,
|
|
||||||
parameter integer NUMWAYS)
|
|
||||||
(
|
|
||||||
// Basic pipeline stuff
|
|
||||||
input logic clk, reset,
|
|
||||||
input logic CPUBusy,
|
|
||||||
|
|
||||||
// mmu
|
|
||||||
input logic [1:0] IfuRWF,
|
|
||||||
|
|
||||||
// cpu side
|
|
||||||
input logic InvalidateICacheM,
|
|
||||||
input logic [11:0] PCNextF,
|
|
||||||
input logic [`PA_BITS-1:0] PCPF,
|
|
||||||
input logic [`XLEN-1:0] PCF,
|
|
||||||
|
|
||||||
// bus fsm interface
|
|
||||||
input logic IgnoreRequest,
|
|
||||||
input logic [LINELEN-1:0] ICacheMemWriteData,
|
|
||||||
output logic ICacheFetchLine,
|
|
||||||
|
|
||||||
(* mark_debug = "true" *) input logic ICacheBusAck,
|
|
||||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] ICacheBusAdr,
|
|
||||||
// High if the icache is requesting a stall
|
|
||||||
output logic ICacheStallF,
|
|
||||||
|
|
||||||
// The raw (not decompressed) instruction that was requested
|
|
||||||
// If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros
|
|
||||||
(* mark_debug = "true" *) output logic [31:0] FinalInstrRawF
|
|
||||||
);
|
|
||||||
|
|
||||||
// Configuration parameters
|
|
||||||
localparam integer LINEBYTELEN = LINELEN/8;
|
|
||||||
|
|
||||||
localparam integer OFFSETLEN = $clog2(LINEBYTELEN);
|
|
||||||
localparam integer INDEXLEN = $clog2(NUMLINES);
|
|
||||||
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
|
|
||||||
|
|
||||||
// *** not used?
|
|
||||||
localparam WORDSPERLINE = LINELEN/`XLEN;
|
|
||||||
localparam LOGWPL = $clog2(WORDSPERLINE);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Input signals to cache memory
|
|
||||||
logic ICacheMemWriteEnable;
|
|
||||||
// Output signals from cache memory
|
|
||||||
logic [LINELEN-1:0] ReadLineF;
|
|
||||||
logic SelAdr;
|
|
||||||
logic [INDEXLEN-1:0] RAdr;
|
|
||||||
logic [NUMWAYS-1:0] VictimWay;
|
|
||||||
logic LRUWriteEn;
|
|
||||||
logic [NUMWAYS-1:0] WayHit;
|
|
||||||
logic hit;
|
|
||||||
|
|
||||||
|
|
||||||
logic [LINELEN-1:0] ReadDataLineWayMasked [NUMWAYS-1:0];
|
|
||||||
|
|
||||||
logic [31:0] ReadLineSetsF [LINELEN/16-1:0];
|
|
||||||
|
|
||||||
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
|
|
||||||
|
|
||||||
|
|
||||||
mux2 #(INDEXLEN)
|
|
||||||
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.s(SelAdr),
|
|
||||||
.y(RAdr));
|
|
||||||
|
|
||||||
|
|
||||||
cacheway #(.NUMLINES(NUMLINES), .LINELEN(LINELEN), .TAGLEN(TAGLEN),
|
|
||||||
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN), .DIRTY_BITS(0))
|
|
||||||
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
|
|
||||||
.PAdr(PCPF),
|
|
||||||
.WriteEnable(SRAMWayWriteEnable),
|
|
||||||
.VDWriteEnable(1'b0),
|
|
||||||
.WriteWordEnable({{(LINELEN/`XLEN){1'b1}}}),
|
|
||||||
.TagWriteEnable(SRAMWayWriteEnable),
|
|
||||||
.WriteData(ICacheMemWriteData),
|
|
||||||
.SetValid(ICacheMemWriteEnable),
|
|
||||||
.ClearValid(1'b0), .SetDirty(1'b0), .ClearDirty(1'b0), .SelEvict(1'b0),
|
|
||||||
.VictimWay,
|
|
||||||
.FlushWay(1'b0), .SelFlush(1'b0),
|
|
||||||
.ReadDataLineWayMasked, .WayHit,
|
|
||||||
.VictimDirtyWay(), .VictimTagWay(),
|
|
||||||
.InvalidateAll(InvalidateICacheM));
|
|
||||||
|
|
||||||
if(NUMWAYS > 1) begin:vict
|
|
||||||
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
|
|
||||||
cachereplacementpolicy(.clk, .reset,
|
|
||||||
.WayHit,
|
|
||||||
.VictimWay,
|
|
||||||
.LsuPAdrM(PCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
|
||||||
.RAdr,
|
|
||||||
.LRUWriteEn);
|
|
||||||
end else begin:vict
|
|
||||||
assign VictimWay = 1'b1; // one hot.
|
|
||||||
end
|
|
||||||
|
|
||||||
assign hit = | WayHit;
|
|
||||||
|
|
||||||
// ReadDataLineWayMasked is a 2d array of cache line len by number of ways.
|
|
||||||
// Need to OR together each way in a bitwise manner.
|
|
||||||
// Final part of the AO Mux. First is the AND in the cacheway.
|
|
||||||
or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadLineF));
|
|
||||||
|
|
||||||
genvar index;
|
|
||||||
for(index = 0; index < LINELEN / 16 - 1; index++)
|
|
||||||
assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)];
|
|
||||||
assign ReadLineSetsF[LINELEN/16-1] = {16'b0, ReadLineF[LINELEN-1:LINELEN-16]};
|
|
||||||
|
|
||||||
assign FinalInstrRawF = ReadLineSetsF[PCPF[$clog2(LINELEN / 32) + 1 : 1]];
|
|
||||||
|
|
||||||
assign ICacheBusAdr = {PCPF[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}};
|
|
||||||
|
|
||||||
|
|
||||||
// truncate the offset from PCPF for memory address generation
|
|
||||||
|
|
||||||
assign SRAMWayWriteEnable = ICacheMemWriteEnable ? VictimWay : '0;
|
|
||||||
|
|
||||||
|
|
||||||
icachefsm icachefsm(.clk,
|
|
||||||
.reset,
|
|
||||||
.CPUBusy,
|
|
||||||
.ICacheMemWriteEnable,
|
|
||||||
.ICacheStallF,
|
|
||||||
.IgnoreRequest,
|
|
||||||
.ICacheBusAck,
|
|
||||||
.ICacheFetchLine,
|
|
||||||
.IfuRWF,
|
|
||||||
.hit,
|
|
||||||
.SelAdr,
|
|
||||||
.LRUWriteEn);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
|
164
pipelined/src/cache/icachefsm.sv
vendored
164
pipelined/src/cache/icachefsm.sv
vendored
@ -1,164 +0,0 @@
|
|||||||
///////////////////////////////////////////
|
|
||||||
// icache.sv
|
|
||||||
//
|
|
||||||
// Written: ross1728@gmail.com June 04, 2021
|
|
||||||
// Modified:
|
|
||||||
//
|
|
||||||
// Purpose: I Cache controller
|
|
||||||
//
|
|
||||||
// A component of the Wally configurable RISC-V project.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
|
||||||
//
|
|
||||||
// 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 substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
///////////////////////////////////////////
|
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module icachefsm
|
|
||||||
(// Inputs from pipeline
|
|
||||||
input logic clk, reset,
|
|
||||||
|
|
||||||
input logic CPUBusy,
|
|
||||||
|
|
||||||
input logic IgnoreRequest,
|
|
||||||
input logic [1:0] IfuRWF,
|
|
||||||
|
|
||||||
// BUS interface
|
|
||||||
input logic ICacheBusAck,
|
|
||||||
|
|
||||||
// icache internal inputs
|
|
||||||
input logic hit,
|
|
||||||
|
|
||||||
// Load data into the cache
|
|
||||||
output logic ICacheMemWriteEnable,
|
|
||||||
|
|
||||||
// Outputs to pipeline control stuff
|
|
||||||
output logic ICacheStallF,
|
|
||||||
|
|
||||||
// Bus interface outputs
|
|
||||||
output logic ICacheFetchLine,
|
|
||||||
|
|
||||||
// icache internal outputs
|
|
||||||
output logic SelAdr,
|
|
||||||
output logic LRUWriteEn
|
|
||||||
);
|
|
||||||
|
|
||||||
// FSM states
|
|
||||||
typedef enum {STATE_READY,
|
|
||||||
|
|
||||||
STATE_MISS_FETCH_WDV, // aligned miss, issue read to AHB and wait for data.
|
|
||||||
STATE_MISS_FETCH_DONE, // write data into SRAM/LUT
|
|
||||||
STATE_MISS_READ, // read line 1 from SRAM/LUT
|
|
||||||
STATE_MISS_READ_DELAY, // read line 1 from SRAM/LUT
|
|
||||||
|
|
||||||
STATE_CPU_BUSY
|
|
||||||
} statetype;
|
|
||||||
|
|
||||||
(* mark_debug = "true" *) statetype CurrState, NextState;
|
|
||||||
logic PreCntEn;
|
|
||||||
|
|
||||||
// the FSM is always runing, do not stall.
|
|
||||||
always_ff @(posedge clk)
|
|
||||||
if (reset) CurrState <= #1 STATE_READY;
|
|
||||||
else CurrState <= #1 NextState;
|
|
||||||
|
|
||||||
// Next state logic
|
|
||||||
always_comb begin
|
|
||||||
//IfuBusFetch = 1'b0;
|
|
||||||
ICacheMemWriteEnable = 1'b0;
|
|
||||||
SelAdr = 1'b0;
|
|
||||||
ICacheStallF = 1'b1;
|
|
||||||
LRUWriteEn = 1'b0;
|
|
||||||
case (CurrState)
|
|
||||||
STATE_READY: begin
|
|
||||||
SelAdr = 1'b0;
|
|
||||||
if(IgnoreRequest) begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
end
|
|
||||||
else if (IfuRWF[1] & hit) begin
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end else if (IfuRWF[1] & ~hit) begin
|
|
||||||
SelAdr = 1'b1; /// *********(
|
|
||||||
NextState = STATE_MISS_FETCH_WDV;
|
|
||||||
end else begin
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
end else begin
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
// branch 3 miss no spill
|
|
||||||
STATE_MISS_FETCH_WDV: begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
//IfuBusFetch = 1'b1;
|
|
||||||
if (ICacheBusAck) begin
|
|
||||||
NextState = STATE_MISS_FETCH_DONE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_MISS_FETCH_DONE: begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
ICacheMemWriteEnable = 1'b1;
|
|
||||||
NextState = STATE_MISS_READ;
|
|
||||||
end
|
|
||||||
STATE_MISS_READ: begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
NextState = STATE_MISS_READ_DELAY;
|
|
||||||
end
|
|
||||||
STATE_MISS_READ_DELAY: begin
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_CPU_BUSY: begin
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY;
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
SelAdr = 1'b1;
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
assign ICacheFetchLine = CurrState == STATE_MISS_FETCH_WDV;
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
@ -264,12 +264,12 @@ module ifu (
|
|||||||
.CacheMiss(),
|
.CacheMiss(),
|
||||||
.CacheAccess(),
|
.CacheAccess(),
|
||||||
.FinalWriteData('0),
|
.FinalWriteData('0),
|
||||||
.RW(IfuRWF), //aways read
|
.RW(IfuRWF),
|
||||||
.Atomic(2'b00),
|
.Atomic(2'b00),
|
||||||
.FlushCache(1'b0),
|
.FlushCache(1'b0),
|
||||||
.LsuAdrE(PCNextFMux), // fixme
|
.NextAdr(PCNextFMux),
|
||||||
.LsuPAdrM(PCPF), // fixme
|
.PAdr(PCPF),
|
||||||
.PreLsuPAdrM(PCFMux[11:0]), //fixme
|
.NoTranAdr(PCFMux[11:0]),
|
||||||
.CacheCommitted(),
|
.CacheCommitted(),
|
||||||
.InvalidateCacheM(InvalidateICacheM));
|
.InvalidateCacheM(InvalidateICacheM));
|
||||||
|
|
||||||
|
@ -298,15 +298,16 @@ module lsu
|
|||||||
|
|
||||||
if(`MEM_DCACHE) begin : dcache
|
if(`MEM_DCACHE) begin : dcache
|
||||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||||
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
||||||
dcache(.clk, .reset, .CPUBusy,
|
dcache(.clk, .reset, .CPUBusy,
|
||||||
.RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00),
|
.RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00),
|
||||||
.LsuAdrE, .LsuPAdrM, .PreLsuPAdrM(PreLsuPAdrM[11:0]), // still don't like this name PreLsuPAdrM, not always physical
|
.NextAdr(LsuAdrE), .PAdr(LsuPAdrM), .NoTranAdr(PreLsuPAdrM[11:0]),
|
||||||
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
|
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
|
||||||
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||||
.IgnoreRequest, .CacheCommitted(DCacheCommittedM),
|
.IgnoreRequest, .CacheCommitted(DCacheCommittedM),
|
||||||
.CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData),
|
.CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData),
|
||||||
.CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
|
.CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
|
||||||
|
|
||||||
end else begin : passthrough
|
end else begin : passthrough
|
||||||
assign ReadDataWordM = 0;
|
assign ReadDataWordM = 0;
|
||||||
assign DCacheStall = 0;
|
assign DCacheStall = 0;
|
||||||
|
@ -279,7 +279,7 @@ module testbench;
|
|||||||
end
|
end
|
||||||
|
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1);
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,3);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0);
|
||||||
`INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]);
|
`INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]);
|
||||||
`INIT_CHECKPOINT_VAL(MEDELEG, [`XLEN-1:0]);
|
`INIT_CHECKPOINT_VAL(MEDELEG, [`XLEN-1:0]);
|
||||||
`INIT_CHECKPOINT_VAL(MIDELEG, [`XLEN-1:0]);
|
`INIT_CHECKPOINT_VAL(MIDELEG, [`XLEN-1:0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user