mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
More parameterization. Copied Lim. Still no slow down.
This commit is contained in:
parent
b91b54589e
commit
052bc95966
14
src/cache/cache.sv
vendored
14
src/cache/cache.sv
vendored
@ -27,9 +27,7 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module cache #(parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) (
|
||||||
|
|
||||||
module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) (
|
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
|
input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
|
||||||
@ -40,7 +38,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
input logic FlushCache, // Flush all dirty lines back to memory
|
input logic FlushCache, // Flush all dirty lines back to memory
|
||||||
input logic InvalidateCache, // Clear all valid bits
|
input logic InvalidateCache, // Clear all valid bits
|
||||||
input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits.
|
input logic [11:0] NextSet, // 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, // Which bytes to write (D$ only)
|
input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
|
||||||
input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only)
|
input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only)
|
||||||
output logic CacheCommitted, // Cache has started bus operation that shouldn't be interrupted
|
output logic CacheCommitted, // Cache has started bus operation that shouldn't be interrupted
|
||||||
@ -57,7 +55,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
input logic [LOGBWPL-1:0] BeatCount, // Beat in burst
|
input logic [LOGBWPL-1:0] BeatCount, // Beat in burst
|
||||||
input logic [LINELEN-1:0] FetchBuffer, // Buffer long enough to hold entire cache line arriving from bus
|
input logic [LINELEN-1:0] FetchBuffer, // Buffer long enough to hold entire cache line arriving from bus
|
||||||
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
|
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
|
||||||
output logic [`PA_BITS-1:0] CacheBusAdr // Address for bus access
|
output logic [PA_BITS-1:0] CacheBusAdr // Address for bus access
|
||||||
);
|
);
|
||||||
|
|
||||||
// Cache parameters
|
// Cache parameters
|
||||||
@ -65,7 +63,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field
|
localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field
|
||||||
localparam SETLEN = $clog2(NUMLINES); // Number of set bits
|
localparam SETLEN = $clog2(NUMLINES); // Number of set bits
|
||||||
localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits
|
localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits
|
||||||
localparam TAGLEN = `PA_BITS - SETTOP; // Number of tag bits
|
localparam TAGLEN = PA_BITS - SETTOP; // Number of tag bits
|
||||||
localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line
|
localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line
|
||||||
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^
|
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^
|
||||||
localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete
|
localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete
|
||||||
@ -114,7 +112,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
AdrSelMuxSel, CacheSet);
|
AdrSelMuxSel, CacheSet);
|
||||||
|
|
||||||
// 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 #(PA_BITS, XLEN, 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, .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);
|
||||||
@ -152,7 +150,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
.PAdr(WordOffsetAddr), .ReadDataLine, .ReadDataWord);
|
.PAdr(WordOffsetAddr), .ReadDataLine, .ReadDataWord);
|
||||||
|
|
||||||
// Bus address for fetch, writeback, or flush writeback
|
// Bus address for fetch, writeback, or flush writeback
|
||||||
mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
||||||
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
|
||||||
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
|
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
|
||||||
.s({SelFlush, SelWriteback}), .y(CacheBusAdr));
|
.s({SelFlush, SelWriteback}), .y(CacheBusAdr));
|
||||||
|
16
src/cache/cacheway.sv
vendored
16
src/cache/cacheway.sv
vendored
@ -27,16 +27,14 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
||||||
|
|
||||||
module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|
||||||
OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) (
|
OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) (
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
||||||
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
||||||
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 valid bit in the selected way and set
|
input logic SetValid, // Set 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
|
||||||
@ -54,11 +52,11 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
output logic DirtyWay, // This way is dirty
|
output logic DirtyWay, // This way is dirty
|
||||||
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
|
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
|
||||||
|
|
||||||
localparam WORDSPERLINE = LINELEN/`XLEN;
|
localparam WORDSPERLINE = LINELEN/XLEN;
|
||||||
localparam BYTESPERLINE = LINELEN/8;
|
localparam BYTESPERLINE = LINELEN/8;
|
||||||
localparam LOGWPL = $clog2(WORDSPERLINE);
|
localparam LOGWPL = $clog2(WORDSPERLINE);
|
||||||
localparam LOGXLENBYTES = $clog2(`XLEN/8);
|
localparam LOGXLENBYTES = $clog2(XLEN/8);
|
||||||
localparam BYTESPERWORD = `XLEN/8;
|
localparam BYTESPERWORD = XLEN/8;
|
||||||
|
|
||||||
logic [NUMLINES-1:0] ValidBits;
|
logic [NUMLINES-1:0] ValidBits;
|
||||||
logic [NUMLINES-1:0] DirtyBits;
|
logic [NUMLINES-1:0] DirtyBits;
|
||||||
@ -113,12 +111,12 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
|
|
||||||
ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
||||||
.addr(CacheSet), .dout(ReadTag),
|
.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
|
||||||
assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
|
assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
|
||||||
assign DirtyWay = SelTag & Dirty & ValidWay;
|
assign DirtyWay = SelTag & Dirty & ValidWay;
|
||||||
assign HitWay = ValidWay & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]);
|
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Data Array
|
// Data Array
|
||||||
|
@ -27,9 +27,10 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module ahbcacheinterface #(
|
module ahbcacheinterface #(
|
||||||
|
parameter AHBW,
|
||||||
|
parameter LLEN,
|
||||||
|
parameter PA_BITS,
|
||||||
parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline
|
parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline
|
||||||
parameter AHBWLOGBWPL, // Log2 of ^
|
parameter AHBWLOGBWPL, // Log2 of ^
|
||||||
parameter LINELEN, // Number of bits in cacheline
|
parameter LINELEN, // Number of bits in cacheline
|
||||||
@ -44,14 +45,14 @@ module ahbcacheinterface #(
|
|||||||
output logic [2:0] HSIZE, // AHB transaction width
|
output logic [2:0] HSIZE, // AHB transaction width
|
||||||
output logic [2:0] HBURST, // AHB burst length
|
output logic [2:0] HBURST, // AHB burst length
|
||||||
// bus interface buses
|
// bus interface buses
|
||||||
input logic [`AHBW-1:0] HRDATA, // AHB read data
|
input logic [AHBW-1:0] HRDATA, // AHB read data
|
||||||
output logic [`PA_BITS-1:0] HADDR, // AHB address
|
output logic [PA_BITS-1:0] HADDR, // AHB address
|
||||||
output logic [`AHBW-1:0] HWDATA, // AHB write data
|
output logic [AHBW-1:0] HWDATA, // AHB write data
|
||||||
output logic [`AHBW/8-1:0] HWSTRB, // AHB byte mask
|
output logic [AHBW/8-1:0] HWSTRB, // AHB byte mask
|
||||||
|
|
||||||
// cache interface
|
// cache interface
|
||||||
input logic [`PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
input logic [PA_BITS-1:0] CacheBusAdr, // Address of cache line
|
||||||
input logic [`LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
input logic [LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
|
||||||
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
|
||||||
input logic Cacheable, // Memory operation is cachable
|
input logic Cacheable, // Memory operation is cachable
|
||||||
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
|
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
|
||||||
@ -61,8 +62,8 @@ module ahbcacheinterface #(
|
|||||||
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
|
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
|
||||||
|
|
||||||
// uncached interface
|
// uncached interface
|
||||||
input logic [`PA_BITS-1:0] PAdr, // Physical address of uncached memory operation
|
input logic [PA_BITS-1:0] PAdr, // Physical address of uncached memory operation
|
||||||
input logic [`LLEN-1:0] WriteDataM, // IEU write data for uncached store
|
input logic [LLEN-1:0] WriteDataM, // IEU write data for uncached store
|
||||||
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
|
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
|
||||||
input logic [2:0] Funct3, // Size of uncached memory operation
|
input logic [2:0] Funct3, // Size of uncached memory operation
|
||||||
|
|
||||||
@ -74,11 +75,11 @@ module ahbcacheinterface #(
|
|||||||
|
|
||||||
|
|
||||||
localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index
|
localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index
|
||||||
logic [`PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
|
logic [PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
|
||||||
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
|
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
|
||||||
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
|
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
|
||||||
logic [`AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
|
logic [AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
|
||||||
logic [`AHBW-1:0] PreHWDATA; // AHB Address phase write data
|
logic [AHBW-1:0] PreHWDATA; // AHB Address phase write data
|
||||||
|
|
||||||
genvar index;
|
genvar index;
|
||||||
|
|
||||||
@ -86,35 +87,35 @@ module ahbcacheinterface #(
|
|||||||
for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer
|
for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer
|
||||||
logic [BEATSPERLINE-1:0] CaptureBeat;
|
logic [BEATSPERLINE-1:0] CaptureBeat;
|
||||||
assign CaptureBeat[index] = CaptureEn & (index == BeatCountDelayed);
|
assign CaptureBeat[index] = CaptureEn & (index == BeatCountDelayed);
|
||||||
flopen #(`AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA),
|
flopen #(AHBW) fb(.clk(HCLK), .en(CaptureBeat[index]), .d(HRDATA),
|
||||||
.q(FetchBuffer[(index+1)*`AHBW-1:index*`AHBW]));
|
.q(FetchBuffer[(index+1)*AHBW-1:index*AHBW]));
|
||||||
end
|
end
|
||||||
|
|
||||||
mux2 #(`PA_BITS) localadrmux(PAdr, CacheBusAdr, Cacheable, LocalHADDR);
|
mux2 #(PA_BITS) localadrmux(PAdr, CacheBusAdr, Cacheable, LocalHADDR);
|
||||||
assign HADDR = ({{`PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(`AHBW/8)) + LocalHADDR;
|
assign HADDR = ({{PA_BITS-AHBWLOGBWPL{1'b0}}, BeatCount} << $clog2(AHBW/8)) + LocalHADDR;
|
||||||
|
|
||||||
mux2 #(3) sizemux(.d0(Funct3), .d1(`AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable), .y(HSIZE));
|
mux2 #(3) sizemux(.d0(Funct3), .d1(AHBW == 32 ? 3'b010 : 3'b011), .s(Cacheable), .y(HSIZE));
|
||||||
|
|
||||||
// When AHBW is less than LLEN need extra muxes to select the subword from cache's read data.
|
// When AHBW is less than LLEN need extra muxes to select the subword from cache's read data.
|
||||||
logic [`AHBW-1:0] CacheReadDataWordAHB;
|
logic [AHBW-1:0] CacheReadDataWordAHB;
|
||||||
if(LLENPOVERAHBW > 1) begin
|
if(LLENPOVERAHBW > 1) begin
|
||||||
logic [`AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
logic [AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
|
||||||
genvar index;
|
genvar index;
|
||||||
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
|
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
|
||||||
assign AHBWordSets[index] = CacheReadDataWordM[(index*`AHBW)+`AHBW-1: (index*`AHBW)];
|
assign AHBWordSets[index] = CacheReadDataWordM[(index*AHBW)+AHBW-1: (index*AHBW)];
|
||||||
end
|
end
|
||||||
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
|
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
|
||||||
end else assign CacheReadDataWordAHB = CacheReadDataWordM[`AHBW-1:0];
|
end else assign CacheReadDataWordAHB = CacheReadDataWordM[AHBW-1:0];
|
||||||
|
|
||||||
mux2 #(`AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[`AHBW-1:0]),
|
mux2 #(AHBW) HWDATAMux(.d0(CacheReadDataWordAHB), .d1(WriteDataM[AHBW-1:0]),
|
||||||
.s(~(CacheableOrFlushCacheM)), .y(PreHWDATA));
|
.s(~(CacheableOrFlushCacheM)), .y(PreHWDATA));
|
||||||
flopen #(`AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec
|
flopen #(AHBW) wdreg(HCLK, HREADY, PreHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec
|
||||||
|
|
||||||
// *** bummer need a second byte mask for bus as it is AHBW rather than LLEN.
|
// *** bummer need a second byte mask for bus as it is AHBW rather than LLEN.
|
||||||
// probably can merge by muxing PAdrM's LLEN/8-1 index bit based on HTRANS being != 0.
|
// probably can merge by muxing PAdrM's LLEN/8-1 index bit based on HTRANS being != 0.
|
||||||
swbytemask #(`AHBW) busswbytemask(.Size(HSIZE), .Adr(HADDR[$clog2(`AHBW/8)-1:0]), .ByteMask(BusByteMaskM));
|
swbytemask #(AHBW) busswbytemask(.Size(HSIZE), .Adr(HADDR[$clog2(AHBW/8)-1:0]), .ByteMask(BusByteMaskM));
|
||||||
|
|
||||||
flopen #(`AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[`AHBW/8-1:0], HWSTRB);
|
flopen #(AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[AHBW/8-1:0], HWSTRB);
|
||||||
|
|
||||||
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm(
|
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm(
|
||||||
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
|
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module ahbinterface #(
|
module ahbinterface #(
|
||||||
|
parameter XLEN,
|
||||||
parameter LSU = 0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
|
parameter LSU = 0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
|
||||||
)(
|
)(
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
`define BURST_EN 1 // Enables burst mode. Disable to show the lost performance.
|
`define BURST_EN 1 // Enables burst mode. Disable to show the lost performance.
|
||||||
|
|
||||||
// HCLK and clk must be the same clock!
|
// HCLK and clk must be the same clock!
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
|
||||||
|
|
||||||
module forward(
|
module forward(
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
|
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module decompress (
|
module decompress #(parameter XLEN)(
|
||||||
input logic [31:0] InstrRawD, // 32-bit instruction or raw compressed 16-bit instruction in bottom half
|
input logic [31:0] InstrRawD, // 32-bit instruction or raw compressed 16-bit instruction in bottom half
|
||||||
output logic [31:0] InstrD, // Decompressed instruction
|
output logic [31:0] InstrD, // Decompressed instruction
|
||||||
output logic IllegalCompInstrD // Invalid decompressed instruction
|
output logic IllegalCompInstrD // Invalid decompressed instruction
|
||||||
|
@ -214,7 +214,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic IROMce;
|
logic IROMce;
|
||||||
assign IROMce = ~GatedStallD | reset;
|
assign IROMce = ~GatedStallD | reset;
|
||||||
assign IFURWF = 2'b10;
|
assign IFURWF = 2'b10;
|
||||||
irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[P.XLEN-1:0]), .IROMInstrF);
|
irom #(P) irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[P.XLEN-1:0]), .IROMInstrF);
|
||||||
end else begin
|
end else begin
|
||||||
assign IFURWF = 2'b10;
|
assign IFURWF = 2'b10;
|
||||||
end
|
end
|
||||||
@ -232,7 +232,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
|
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
|
||||||
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
|
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
|
||||||
cache #(.LINELEN(P.ICACHE_LINELENINBITS),
|
cache #(.PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS),
|
||||||
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
|
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
|
||||||
.NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
|
.NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
|
||||||
icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD),
|
icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD),
|
||||||
@ -249,7 +249,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
.NextSet(PCSpillNextF[11:0]),
|
.NextSet(PCSpillNextF[11:0]),
|
||||||
.PAdr(PCPF),
|
.PAdr(PCPF),
|
||||||
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
|
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
|
||||||
ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
|
ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
|
||||||
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
|
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
|
||||||
.HRDATA,
|
.HRDATA,
|
||||||
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
|
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
|
||||||
@ -269,7 +269,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign BusRW = ~ITLBMissF & ~SelIROM ? IFURWF : '0;
|
assign BusRW = ~ITLBMissF & ~SelIROM ? IFURWF : '0;
|
||||||
assign IFUHSIZE = 3'b010;
|
assign IFUHSIZE = 3'b010;
|
||||||
|
|
||||||
ahbinterface #(0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
|
ahbinterface #(P.XLEN, 0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
|
||||||
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
|
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
|
||||||
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
|
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
|
||||||
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
|
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
|
||||||
@ -351,7 +351,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
// expand 16-bit compressed instructions to 32 bits
|
// expand 16-bit compressed instructions to 32 bits
|
||||||
if (P.C_SUPPORTED) begin
|
if (P.C_SUPPORTED) begin
|
||||||
logic IllegalCompInstrD;
|
logic IllegalCompInstrD;
|
||||||
decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD);
|
decompress #(P.XLEN) decomp(.InstrRawD, .InstrD, .IllegalCompInstrD);
|
||||||
assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
||||||
end else begin
|
end else begin
|
||||||
assign InstrD = InstrRawD;
|
assign InstrD = InstrRawD;
|
||||||
|
@ -24,27 +24,25 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`include "wally-config.vh"
|
module irom import cvw::*; #(parameter cvw_t P) (
|
||||||
|
|
||||||
module irom(
|
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
|
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
|
||||||
input logic [`XLEN-1:0] Adr, // PCNextFSpill
|
input logic [P.XLEN-1:0] Adr, // PCNextFSpill
|
||||||
output logic [31:0] IROMInstrF // Instruction read data
|
output logic [31:0] IROMInstrF // Instruction read data
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam XLENBYTES = `XLEN/8;
|
localparam XLENBYTES = {{P.PA_BITS-32{1'b0}}, P.XLEN/8}; // XLEN/8, adjusted for width
|
||||||
localparam ADDR_WDITH = $clog2(`IROM_RANGE/XLENBYTES);
|
localparam ADDR_WDITH = $clog2(P.IROM_RANGE[P.PA_BITS-1:0]/XLENBYTES);
|
||||||
localparam OFFSET = $clog2(XLENBYTES);
|
localparam OFFSET = $clog2(XLENBYTES);
|
||||||
|
|
||||||
logic [`XLEN-1:0] IROMInstrFFull;
|
logic [P.XLEN-1:0] IROMInstrFFull;
|
||||||
logic [31:0] RawIROMInstrF;
|
logic [31:0] RawIROMInstrF;
|
||||||
|
|
||||||
logic [1:0] AdrD;
|
logic [1:0] AdrD;
|
||||||
flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
|
flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
|
||||||
|
|
||||||
rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
rom1p1r #(ADDR_WDITH, P.XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
|
||||||
if (`XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
|
||||||
else begin
|
else begin
|
||||||
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
|
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
|
||||||
// haves. Adr is the Next PCF not PCF so we delay 1 cycle.
|
// haves. Adr is the Next PCF not PCF so we delay 1 cycle.
|
||||||
|
@ -263,7 +263,7 @@ module lsu (
|
|||||||
assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0;
|
assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0;
|
||||||
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
|
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
|
||||||
|
|
||||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
cache #(.PA_BITS(`PA_BITS), .XLEN(`XLEN), .LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||||
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache(
|
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache(
|
||||||
.clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM),
|
.clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM),
|
||||||
.FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM),
|
.FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM),
|
||||||
@ -275,7 +275,7 @@ module lsu (
|
|||||||
.FetchBuffer, .CacheBusRW,
|
.FetchBuffer, .CacheBusRW,
|
||||||
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
|
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
|
||||||
|
|
||||||
ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface(
|
ahbcacheinterface #(.AHBW(`AHBW), .LLEN(`LLEN), .PA_BITS(`PA_BITS), .BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface(
|
||||||
.HCLK(clk), .HRESETn(~reset), .Flush(FlushW),
|
.HCLK(clk), .HRESETn(~reset), .Flush(FlushW),
|
||||||
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
|
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
|
||||||
.HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY),
|
.HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY),
|
||||||
@ -300,7 +300,7 @@ module lsu (
|
|||||||
assign LSUHADDR = PAdrM;
|
assign LSUHADDR = PAdrM;
|
||||||
assign LSUHSIZE = LSUFunct3M;
|
assign LSUHSIZE = LSUFunct3M;
|
||||||
|
|
||||||
ahbinterface #(1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
ahbinterface #(`XLEN, 1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
||||||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
|
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
|
||||||
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||||
|
Loading…
Reference in New Issue
Block a user