mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally
This commit is contained in:
commit
d7571bb9b1
1
.gitignore
vendored
1
.gitignore
vendored
@ -117,3 +117,4 @@ pipelined/srt/testgen
|
|||||||
pipelined/srt/qslc_r4a2
|
pipelined/srt/qslc_r4a2
|
||||||
pipelined/srt/qslc_r4a2.sv
|
pipelined/srt/qslc_r4a2.sv
|
||||||
pipelined/srt/testvectors
|
pipelined/srt/testvectors
|
||||||
|
pipelined/regression/wkdir
|
@ -271,7 +271,7 @@ connect_debug_port u_ila_0/probe51 [get_nets [list wallypipelinedsoc/core/hzu/BP
|
|||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe52]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe52]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe52]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe52]
|
||||||
connect_debug_port u_ila_0/probe52 [get_nets [list wallypipelinedsoc/core/hzu/CSRWriteFencePendingDEM ]]
|
connect_debug_port u_ila_0/probe52 [get_nets [list wallypipelinedsoc/core/hzu/CSRWriteFenceM ]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe53]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe53]
|
||||||
@ -356,7 +356,7 @@ connect_debug_port u_ila_0/probe68 [get_nets [list wallypipelinedsoc/core/hzu/St
|
|||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe69]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe69]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe69]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe69]
|
||||||
connect_debug_port u_ila_0/probe69 [get_nets [list wallypipelinedsoc/core/hzu/StallD ]]
|
connect_debug_port u_ila_0/probe69 [get_nets [list wallypipelinedsoc/core/hzu/StallD_inferred_i_2_n_0 ]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe70]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe70]
|
||||||
|
@ -70,8 +70,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 16
|
`define PMP_ENTRIES 16
|
||||||
|
@ -72,8 +72,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
|
@ -71,8 +71,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 1
|
`define IDIV_BITSPERCYCLE 1
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 0
|
`define PMP_ENTRIES 0
|
||||||
|
@ -70,8 +70,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
|
@ -71,8 +71,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
|
@ -70,8 +70,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 0
|
`define PMP_ENTRIES 0
|
||||||
|
@ -74,8 +74,9 @@
|
|||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Address space
|
// Address space
|
||||||
`define RESET_VECTOR 64'h0000000000001000
|
`define RESET_VECTOR 64'h0000000000001000
|
||||||
|
@ -72,8 +72,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
|
@ -72,8 +72,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 64
|
`define PMP_ENTRIES 64
|
||||||
|
@ -72,8 +72,9 @@
|
|||||||
`define ICACHE_LINELENINBITS 512
|
`define ICACHE_LINELENINBITS 512
|
||||||
|
|
||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// DIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define DIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
|
`define IDIV_ON_FPU 0
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 0
|
`define PMP_ENTRIES 0
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
# output.
|
# output.
|
||||||
#
|
#
|
||||||
##################################
|
##################################
|
||||||
import sys,os
|
import sys,os,shutil
|
||||||
|
|
||||||
class bcolors:
|
class bcolors:
|
||||||
HEADER = '\033[95m'
|
HEADER = '\033[95m'
|
||||||
@ -26,6 +26,7 @@ class bcolors:
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
regressionDir = os.path.dirname(os.path.abspath(__file__))
|
regressionDir = os.path.dirname(os.path.abspath(__file__))
|
||||||
os.chdir(regressionDir)
|
os.chdir(regressionDir)
|
||||||
|
|
||||||
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
|
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
|
||||||
# name: the name of this test configuration (used in printing human-readable
|
# name: the name of this test configuration (used in printing human-readable
|
||||||
# output and picking logfile names)
|
# output and picking logfile names)
|
||||||
@ -158,9 +159,13 @@ def main():
|
|||||||
try:
|
try:
|
||||||
os.chdir(regressionDir)
|
os.chdir(regressionDir)
|
||||||
os.mkdir("logs")
|
os.mkdir("logs")
|
||||||
|
#print(os.getcwd())
|
||||||
|
#print(regressionDir)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
shutil.rmtree("wkdir")
|
||||||
|
os.mkdir("wkdir")
|
||||||
|
|
||||||
if '-makeTests' in sys.argv:
|
if '-makeTests' in sys.argv:
|
||||||
os.chdir(regressionDir)
|
os.chdir(regressionDir)
|
||||||
os.system('./make-tests.sh | tee ./logs/make-tests.log')
|
os.system('./make-tests.sh | tee ./logs/make-tests.log')
|
||||||
|
4
pipelined/regression/wkdir/.gitignore
vendored
4
pipelined/regression/wkdir/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
# Ignore everything in this directory
|
|
||||||
*
|
|
||||||
# Except this file
|
|
||||||
!.gitignore
|
|
19
pipelined/src/cache/cache.sv
vendored
19
pipelined/src/cache/cache.sv
vendored
@ -94,14 +94,14 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
logic [NUMWAYS-1:0] NextFlushWay;
|
logic [NUMWAYS-1:0] NextFlushWay;
|
||||||
logic FlushWayCntEn;
|
logic FlushWayCntEn;
|
||||||
logic FlushWayCntRst;
|
logic FlushWayCntRst;
|
||||||
logic SelEvict;
|
logic SelWriteback;
|
||||||
logic LRUWriteEn;
|
logic LRUWriteEn;
|
||||||
logic SelFlush;
|
logic SelFlush;
|
||||||
logic ResetOrFlushAdr, ResetOrFlushWay;
|
logic ResetOrFlushAdr, ResetOrFlushWay;
|
||||||
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
|
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
|
||||||
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
|
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
|
||||||
logic SelFetchBuffer;
|
logic SelFetchBuffer;
|
||||||
logic ce;
|
logic CacheEn;
|
||||||
|
|
||||||
localparam LOGLLENBYTES = $clog2(WORDLEN/8);
|
localparam LOGLLENBYTES = $clog2(WORDLEN/8);
|
||||||
localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN;
|
localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN;
|
||||||
@ -124,12 +124,12 @@ 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, DCACHE)
|
cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE)
|
||||||
CacheWays[NUMWAYS-1:0](.clk, .reset, .ce, .CAdr, .PAdr, .LineWriteData, .LineByteMask,
|
CacheWays[NUMWAYS-1:0](.clk, .reset, .CacheEn, .CAdr, .PAdr, .LineWriteData, .LineByteMask,
|
||||||
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelEvict, .VictimWay,
|
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay,
|
||||||
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
|
||||||
if(NUMWAYS > 1) begin:vict
|
if(NUMWAYS > 1) begin:vict
|
||||||
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU(
|
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU(
|
||||||
.clk, .reset, .ce, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CAdr, .LRUWriteEn(LRUWriteEn & ~FlushStage),
|
.clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CAdr, .LRUWriteEn(LRUWriteEn & ~FlushStage),
|
||||||
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache);
|
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache);
|
||||||
end else assign VictimWay = 1'b1; // one hot.
|
end else assign VictimWay = 1'b1; // one hot.
|
||||||
assign CacheHit = | HitWay;
|
assign CacheHit = | HitWay;
|
||||||
@ -163,7 +163,8 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
end
|
end
|
||||||
|
|
||||||
assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1.
|
assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1.
|
||||||
assign LineByteMask = ~SetValid & ~SetDirty ? '0 : ~SetValid & SetDirty ? DemuxedByteMask : '1; // if store hit only enable the word and subword bytes, else write all bytes.
|
logic [LINELEN/8-1:0] LineByteMask2;
|
||||||
|
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
|
||||||
|
|
||||||
for(index = 0; index < LINELEN/8; index++) begin
|
for(index = 0; index < LINELEN/8; index++) begin
|
||||||
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
|
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
|
||||||
@ -173,7 +174,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
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, SelEvict}), .y(CacheBusAdr));
|
.s({SelFlush, SelWriteback}), .y(CacheBusAdr));
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Flush address and way generation during flush
|
// Flush address and way generation during flush
|
||||||
@ -198,10 +199,10 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
|||||||
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
|
||||||
.CacheMiss, .CacheAccess, .SelAdr,
|
.CacheMiss, .CacheAccess, .SelAdr,
|
||||||
.ClearValid, .ClearDirty, .SetDirty,
|
.ClearValid, .ClearDirty, .SetDirty,
|
||||||
.SetValid, .SelEvict, .SelFlush,
|
.SetValid, .SelWriteback, .SelFlush,
|
||||||
.FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst,
|
.FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst,
|
||||||
.FlushWayCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
.FlushWayCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
|
||||||
.InvalidateCache,
|
.InvalidateCache,
|
||||||
.ce,
|
.CacheEn,
|
||||||
.LRUWriteEn);
|
.LRUWriteEn);
|
||||||
endmodule
|
endmodule
|
||||||
|
4
pipelined/src/cache/cacheLRU.sv
vendored
4
pipelined/src/cache/cacheLRU.sv
vendored
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
module cacheLRU
|
module cacheLRU
|
||||||
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)(
|
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)(
|
||||||
input logic clk, reset, ce, FlushStage,
|
input logic clk, reset, CacheEn, FlushStage,
|
||||||
input logic [NUMWAYS-1:0] HitWay,
|
input logic [NUMWAYS-1:0] HitWay,
|
||||||
input logic [NUMWAYS-1:0] ValidWay,
|
input logic [NUMWAYS-1:0] ValidWay,
|
||||||
output logic [NUMWAYS-1:0] VictimWay,
|
output logic [NUMWAYS-1:0] VictimWay,
|
||||||
@ -120,7 +120,7 @@ module cacheLRU
|
|||||||
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
|
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
||||||
if(ce) begin
|
if(CacheEn) begin
|
||||||
if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
|
||||||
else if (LRUWriteEn & ~FlushStage) begin
|
else if (LRUWriteEn & ~FlushStage) begin
|
||||||
LRUMemory[CAdr] <= NextLRU; ///***** RT: This is not right. Logically should be PAdr, but it breaks linux.
|
LRUMemory[CAdr] <= NextLRU; ///***** RT: This is not right. Logically should be PAdr, but it breaks linux.
|
||||||
|
8
pipelined/src/cache/cachefsm.sv
vendored
8
pipelined/src/cache/cachefsm.sv
vendored
@ -64,7 +64,7 @@ module cachefsm
|
|||||||
output logic ClearDirty,
|
output logic ClearDirty,
|
||||||
output logic SetDirty,
|
output logic SetDirty,
|
||||||
output logic SetValid,
|
output logic SetValid,
|
||||||
output logic SelEvict,
|
output logic SelWriteback,
|
||||||
output logic LRUWriteEn,
|
output logic LRUWriteEn,
|
||||||
output logic SelFlush,
|
output logic SelFlush,
|
||||||
output logic FlushAdrCntEn,
|
output logic FlushAdrCntEn,
|
||||||
@ -72,7 +72,7 @@ module cachefsm
|
|||||||
output logic FlushAdrCntRst,
|
output logic FlushAdrCntRst,
|
||||||
output logic FlushWayCntRst,
|
output logic FlushWayCntRst,
|
||||||
output logic SelFetchBuffer,
|
output logic SelFetchBuffer,
|
||||||
output logic ce);
|
output logic CacheEn);
|
||||||
|
|
||||||
logic resetDelay;
|
logic resetDelay;
|
||||||
logic AMO, StoreAMO;
|
logic AMO, StoreAMO;
|
||||||
@ -170,7 +170,7 @@ module cachefsm
|
|||||||
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
|
assign LRUWriteEn = (CurrState == STATE_READY & AnyHit) |
|
||||||
(CurrState == STATE_MISS_WRITE_CACHE_LINE);
|
(CurrState == STATE_MISS_WRITE_CACHE_LINE);
|
||||||
// Flush and eviction controls
|
// Flush and eviction controls
|
||||||
assign SelEvict = (CurrState == STATE_MISS_EVICT_DIRTY & ~CacheBusAck) |
|
assign SelWriteback = (CurrState == STATE_MISS_EVICT_DIRTY & ~CacheBusAck) |
|
||||||
(CurrState == STATE_READY & AnyMiss & LineDirty);
|
(CurrState == STATE_READY & AnyMiss & LineDirty);
|
||||||
assign SelFlush = (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_CHECK) |
|
assign SelFlush = (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_CHECK) |
|
||||||
(CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_WRITE_BACK);
|
(CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_WRITE_BACK);
|
||||||
@ -201,6 +201,6 @@ module cachefsm
|
|||||||
resetDelay;
|
resetDelay;
|
||||||
|
|
||||||
assign SelFetchBuffer = CurrState == STATE_MISS_WRITE_CACHE_LINE | CurrState == STATE_MISS_READ_DELAY;
|
assign SelFetchBuffer = CurrState == STATE_MISS_WRITE_CACHE_LINE | CurrState == STATE_MISS_READ_DELAY;
|
||||||
assign ce = (CurrState == STATE_READY & ~Stall | CacheStall) | (CurrState != STATE_READY) | reset;
|
assign CacheEn = (CurrState == STATE_READY & ~Stall | CacheStall) | (CurrState != STATE_READY) | reset;
|
||||||
|
|
||||||
endmodule // cachefsm
|
endmodule // cachefsm
|
||||||
|
35
pipelined/src/cache/cacheway.sv
vendored
35
pipelined/src/cache/cacheway.sv
vendored
@ -33,7 +33,7 @@
|
|||||||
module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
||||||
parameter OFFSETLEN = 5, parameter INDEXLEN = 9, parameter DIRTY_BITS = 1) (
|
parameter OFFSETLEN = 5, parameter INDEXLEN = 9, parameter DIRTY_BITS = 1) (
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic ce,
|
input logic CacheEn,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic [$clog2(NUMLINES)-1:0] CAdr,
|
input logic [$clog2(NUMLINES)-1:0] CAdr,
|
||||||
input logic [`PA_BITS-1:0] PAdr,
|
input logic [`PA_BITS-1:0] PAdr,
|
||||||
@ -42,7 +42,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
input logic ClearValid,
|
input logic ClearValid,
|
||||||
input logic SetDirty,
|
input logic SetDirty,
|
||||||
input logic ClearDirty,
|
input logic ClearDirty,
|
||||||
input logic SelEvict,
|
input logic SelWriteback,
|
||||||
input logic SelFlush,
|
input logic SelFlush,
|
||||||
input logic VictimWay,
|
input logic VictimWay,
|
||||||
input logic FlushWay,
|
input logic FlushWay,
|
||||||
@ -76,8 +76,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
logic ClearValidWay;
|
logic ClearValidWay;
|
||||||
logic SetDirtyWay;
|
logic SetDirtyWay;
|
||||||
logic ClearDirtyWay;
|
logic ClearDirtyWay;
|
||||||
logic SelectedWay;
|
logic SelNonHit;
|
||||||
logic SelWriteback;
|
|
||||||
logic SelData;
|
logic SelData;
|
||||||
logic FlushWayEn, VictimWayEn;
|
logic FlushWayEn, VictimWayEn;
|
||||||
|
|
||||||
@ -85,28 +84,28 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
// FlushWay and VictimWay are part of a one hot way selection. Must clear them if FlushWay not selected
|
// FlushWay and VictimWay are part of a one hot way selection. Must clear them if FlushWay not selected
|
||||||
// or VictimWay not selected.
|
// or VictimWay not selected.
|
||||||
assign FlushWayEn = FlushWay & SelFlush;
|
assign FlushWayEn = FlushWay & SelFlush;
|
||||||
assign VictimWayEn = VictimWay & SelEvict;
|
assign VictimWayEn = VictimWay & SelWriteback;
|
||||||
|
|
||||||
assign SelWriteback = FlushWayEn | SetValid | SelEvict;
|
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
|
||||||
|
|
||||||
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
||||||
//assign SelTag = VictimWay | FlushWay;
|
//assign SelTag = VictimWay | FlushWay;
|
||||||
assign SelData = HitWay | FlushWayEn | VictimWayEn;
|
//assign SelData = HitWay | FlushWayEn | VictimWayEn;
|
||||||
|
|
||||||
mux2 #(1) selectedwaymux(HitWay, SelTag, SelWriteback , SelectedWay);
|
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Write Enable demux
|
// Write Enable demux
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// RT: Can we merge these two muxes? This is also shared in cacheLRU.
|
// RT: Can we merge these two muxes? This is also shared in cacheLRU.
|
||||||
//mux3 #(1) selectwaymux(HitWay, VictimWay, FlushWay, {SelFlush, SetValid}, SelectedWay);
|
//mux3 #(1) selectwaymux(HitWay, VictimWay, FlushWay, {SelFlush, SetValid}, SelData);
|
||||||
//mux3 #(1) selecteddatamux(HitWay, VictimWay, FlushWay, {SelFlush, SelEvict}, SelData);
|
//mux3 #(1) selecteddatamux(HitWay, VictimWay, FlushWay, {SelFlush, SelNonHit}, SelData);
|
||||||
|
|
||||||
assign SetValidWay = SetValid & SelectedWay;
|
assign SetValidWay = SetValid & SelData;
|
||||||
assign ClearValidWay = ClearValid & SelectedWay;
|
assign ClearValidWay = ClearValid & SelData;
|
||||||
assign SetDirtyWay = SetDirty & SelectedWay;
|
assign SetDirtyWay = SetDirty & SelData;
|
||||||
assign ClearDirtyWay = ClearDirty & SelectedWay;
|
assign ClearDirtyWay = ClearDirty & SelData;
|
||||||
|
|
||||||
// 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 SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage;
|
||||||
@ -117,7 +116,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
// Tag Array
|
// Tag Array
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce,
|
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
|
||||||
.addr(CAdr), .dout(ReadTag), .bwe('1),
|
.addr(CAdr), .dout(ReadTag), .bwe('1),
|
||||||
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
||||||
|
|
||||||
@ -140,7 +139,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
localparam integer LOGNUMSRAM = $clog2(NUMSRAM);
|
localparam integer LOGNUMSRAM = $clog2(NUMSRAM);
|
||||||
|
|
||||||
for(words = 0; words < NUMSRAM; words++) begin: word
|
for(words = 0; words < NUMSRAM; words++) begin: word
|
||||||
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce, .addr(CAdr),
|
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CAdr),
|
||||||
.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]));
|
||||||
@ -155,7 +154,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
|
|
||||||
always_ff @(posedge clk) begin // Valid bit array,
|
always_ff @(posedge clk) begin // Valid bit array,
|
||||||
if (reset) ValidBits <= #1 '0;
|
if (reset) ValidBits <= #1 '0;
|
||||||
if(ce) begin
|
if(CacheEn) begin
|
||||||
ValidWay <= #1 ValidBits[CAdr];
|
ValidWay <= #1 ValidBits[CAdr];
|
||||||
if(InvalidateCache & ~FlushStage) ValidBits <= #1 '0;
|
if(InvalidateCache & ~FlushStage) ValidBits <= #1 '0;
|
||||||
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay;
|
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay;
|
||||||
@ -171,7 +170,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
|
|||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
// reset is optional. Consider merging with TAG array in the future.
|
// reset is optional. Consider merging with TAG array in the future.
|
||||||
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
|
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
|
||||||
if(ce) begin
|
if(CacheEn) begin
|
||||||
Dirty <= #1 DirtyBits[CAdr];
|
Dirty <= #1 DirtyBits[CAdr];
|
||||||
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay;
|
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay;
|
||||||
end
|
end
|
||||||
|
@ -43,7 +43,7 @@ module fdivsqrt(
|
|||||||
input logic FDivStartE, IDivStartE,
|
input logic FDivStartE, IDivStartE,
|
||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic StallE,
|
input logic StallE,
|
||||||
input logic TrapM,
|
input logic FlushE,
|
||||||
input logic SqrtE, SqrtM,
|
input logic SqrtE, SqrtM,
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
input logic [2:0] Funct3E, Funct3M,
|
input logic [2:0] Funct3E, Funct3M,
|
||||||
@ -52,7 +52,8 @@ module fdivsqrt(
|
|||||||
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
||||||
// output logic DivDone,
|
// output logic DivDone,
|
||||||
output logic [`NE+1:0] QeM,
|
output logic [`NE+1:0] QeM,
|
||||||
output logic [`DIVb:0] QmM
|
output logic [`DIVb:0] QmM,
|
||||||
|
output logic [`XLEN-1:0] FPIntDivResultM
|
||||||
// output logic [`XLEN-1:0] RemM,
|
// output logic [`XLEN-1:0] RemM,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ module fdivsqrt(
|
|||||||
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E);
|
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E);
|
||||||
fdivsqrtfsm fdivsqrtfsm(
|
fdivsqrtfsm fdivsqrtfsm(
|
||||||
.clk, .reset, .FmtE, .XsE, .SqrtE,
|
.clk, .reset, .FmtE, .XsE, .SqrtE,
|
||||||
.FDivBusyE, .FDivStartE, .IDivStartE, .IFDivStartE, .FDivDoneE, .StallE, .StallM, .TrapM, /*.DivDone, */ .XZeroE, .YZeroE,
|
.FDivBusyE, .FDivStartE, .IDivStartE, .IFDivStartE, .FDivDoneE, .StallE, .StallM, .FlushE, /*.DivDone, */ .XZeroE, .YZeroE,
|
||||||
.XNaNE, .YNaNE, .MDUE, .n,
|
.XNaNE, .YNaNE, .MDUE, .n,
|
||||||
.XInfE, .YInfE, .WZero, .SpecialCaseM);
|
.XInfE, .YInfE, .WZero, .SpecialCaseM);
|
||||||
fdivsqrtiter fdivsqrtiter(
|
fdivsqrtiter fdivsqrtiter(
|
||||||
@ -88,5 +89,5 @@ module fdivsqrt(
|
|||||||
.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun,
|
.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun,
|
||||||
.SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAE,
|
.SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAE,
|
||||||
.n, .ALTBM, .m, .BZero, .As,
|
.n, .ALTBM, .m, .BZero, .As,
|
||||||
.QmM, .WZero, .DivSM);
|
.QmM, .WZero, .DivSM, .FPIntDivResultM);
|
||||||
endmodule
|
endmodule
|
@ -42,7 +42,7 @@ module fdivsqrtfsm(
|
|||||||
input logic SqrtE,
|
input logic SqrtE,
|
||||||
input logic StallE,
|
input logic StallE,
|
||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic TrapM,
|
input logic FlushE,
|
||||||
input logic WZero,
|
input logic WZero,
|
||||||
input logic MDUE,
|
input logic MDUE,
|
||||||
input logic [`DIVBLEN:0] n,
|
input logic [`DIVBLEN:0] n,
|
||||||
@ -107,7 +107,7 @@ module fdivsqrtfsm(
|
|||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset | TrapM) begin
|
if (reset | FlushE) begin
|
||||||
state <= #1 IDLE;
|
state <= #1 IDLE;
|
||||||
end else if (IFDivStartE) begin
|
end else if (IFDivStartE) begin
|
||||||
step <= cycles;
|
step <= cycles;
|
||||||
|
@ -43,7 +43,8 @@ module fdivsqrtpostproc(
|
|||||||
input logic [`DIVBLEN:0] n, m,
|
input logic [`DIVBLEN:0] n, m,
|
||||||
output logic [`DIVb:0] QmM,
|
output logic [`DIVb:0] QmM,
|
||||||
output logic WZero,
|
output logic WZero,
|
||||||
output logic DivSM
|
output logic DivSM,
|
||||||
|
output logic [`XLEN-1:0] FPIntDivResultM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`DIVb+3:0] W, Sum, RemDM;
|
logic [`DIVb+3:0] W, Sum, RemDM;
|
||||||
@ -53,7 +54,7 @@ module fdivsqrtpostproc(
|
|||||||
logic [`DIVBLEN:0] NormShiftM;
|
logic [`DIVBLEN:0] NormShiftM;
|
||||||
logic [`DIVb:0] IntQuotM, NormQuotM;
|
logic [`DIVb:0] IntQuotM, NormQuotM;
|
||||||
logic [`DIVb+3:0] IntRemM, NormRemM;
|
logic [`DIVb+3:0] IntRemM, NormRemM;
|
||||||
logic [`DIVb+3:0] PreResultM, ResultM;
|
logic [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
|
||||||
|
|
||||||
// check for early termination on an exact result. If the result is not exact, the sticky should be set
|
// check for early termination on an exact result. If the result is not exact, the sticky should be set
|
||||||
aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
|
aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
|
||||||
@ -136,8 +137,9 @@ module fdivsqrtpostproc(
|
|||||||
|
|
||||||
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
|
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
|
||||||
|
|
||||||
assign ResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
|
assign PreFPIntDivResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
|
||||||
|
assign FPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0];
|
||||||
|
|
||||||
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit
|
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit
|
||||||
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
||||||
endmodule
|
endmodule
|
@ -38,7 +38,7 @@ module fpu (
|
|||||||
input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU)
|
input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU)
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input (from IEU)
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input (from IEU)
|
||||||
input logic StallE, StallM, StallW, // stall signals (from HZU)
|
input logic StallE, StallM, StallW, // stall signals (from HZU)
|
||||||
input logic TrapM,
|
//input logic TrapM,
|
||||||
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
||||||
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
|
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
|
||||||
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
||||||
@ -55,7 +55,8 @@ module fpu (
|
|||||||
output logic FCvtIntW, // select FCvtIntRes (to IEU)
|
output logic FCvtIntW, // select FCvtIntRes (to IEU)
|
||||||
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
|
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
|
||||||
output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction (to privileged unit)
|
output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction (to privileged unit)
|
||||||
output logic [4:0] SetFflagsM // FPU flags (to privileged unit)
|
output logic [4:0] SetFflagsM, // FPU flags (to privileged unit)
|
||||||
|
output logic [`XLEN-1:0] FPIntDivResultW
|
||||||
);
|
);
|
||||||
|
|
||||||
// FPU specifics:
|
// FPU specifics:
|
||||||
@ -152,6 +153,7 @@ module fpu (
|
|||||||
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
|
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||||
logic [`FLEN-1:0] BoxedOneE; // Zero value for Z for multiplication, with NaN boxing if needed
|
logic [`FLEN-1:0] BoxedOneE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||||
logic StallUnpackedM;
|
logic StallUnpackedM;
|
||||||
|
logic [`XLEN-1:0] FPIntDivResultM;
|
||||||
|
|
||||||
// DECODE STAGE
|
// DECODE STAGE
|
||||||
|
|
||||||
@ -266,8 +268,8 @@ module fpu (
|
|||||||
fdivsqrt fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]),
|
fdivsqrt fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]),
|
||||||
.XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE,
|
.XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E,
|
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E,
|
||||||
.StallE, .StallM, .TrapM, .DivSM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM,
|
.StallE, .StallM, .FlushE, .DivSM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM,
|
||||||
.QmM /*, .DivDone(DivDoneM) */);
|
.QmM, .FPIntDivResultM /*, .DivDone(DivDoneM) */);
|
||||||
|
|
||||||
//
|
//
|
||||||
// compare
|
// compare
|
||||||
@ -387,7 +389,8 @@ module fpu (
|
|||||||
|
|
||||||
// M/W pipe registers
|
// M/W pipe registers
|
||||||
flopenrc #(`FLEN) MWRegFp(clk, reset, FlushW, ~StallW, FpResM, FpResW);
|
flopenrc #(`FLEN) MWRegFp(clk, reset, FlushW, ~StallW, FpResM, FpResW);
|
||||||
flopenrc #(`XLEN) MWRegInt(clk, reset, FlushW, ~StallW, FCvtIntResM, FCvtIntResW);
|
flopenrc #(`XLEN) MWRegIntCvtRes(clk, reset, FlushW, ~StallW, FCvtIntResM, FCvtIntResW);
|
||||||
|
flopenrc #(`XLEN) MWRegIntDivRes(clk, reset, FlushW, ~StallW, FPIntDivResultM, FPIntDivResultW);
|
||||||
|
|
||||||
// BEGIN WRITEBACK STAGE
|
// BEGIN WRITEBACK STAGE
|
||||||
|
|
||||||
|
@ -32,13 +32,13 @@
|
|||||||
|
|
||||||
module hazard(
|
module hazard(
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFencePendingDEM, RetM, TrapM,
|
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
|
||||||
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
||||||
(* mark_debug = "true" *) input logic LSUStallM, IFUStallF,
|
(* mark_debug = "true" *) input logic LSUStallM, IFUStallF,
|
||||||
(* mark_debug = "true" *) input logic FCvtIntStallD, FStallD,
|
(* mark_debug = "true" *) input logic FCvtIntStallD, FStallD,
|
||||||
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
||||||
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
||||||
(* mark_debug = "true" *) input logic wfiM, IntPendingM,
|
(* mark_debug = "true" *) input logic wfiM, IntPendingM,
|
||||||
// Stall & flush outputs
|
// Stall & flush outputs
|
||||||
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
|
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
|
||||||
(* mark_debug = "true" *) output logic FlushD, FlushE, FlushM, FlushW
|
(* mark_debug = "true" *) output logic FlushD, FlushE, FlushM, FlushW
|
||||||
@ -46,6 +46,8 @@ module hazard(
|
|||||||
|
|
||||||
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
|
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
|
||||||
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
|
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
|
||||||
|
logic FlushDCause, FlushECause, FlushMCause, FlushWCause;
|
||||||
|
|
||||||
|
|
||||||
// stalls and flushes
|
// stalls and flushes
|
||||||
// loads: stall for one cycle if the subsequent instruction depends on the load
|
// loads: stall for one cycle if the subsequent instruction depends on the load
|
||||||
@ -59,23 +61,20 @@ module hazard(
|
|||||||
// A stage must stall if the next stage is stalled
|
// A stage must stall if the next stage is stalled
|
||||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||||
|
|
||||||
// *** can stalls be pushed into earlier stages (e.g. no stall after Decode?)
|
assign FlushDCause = TrapM | RetM | BPPredWrongE | CSRWriteFenceM;
|
||||||
|
assign FlushECause = TrapM | RetM | (BPPredWrongE & ~(DivBusyE | FDivBusyE)) | CSRWriteFenceM;
|
||||||
|
assign FlushMCause = TrapM | RetM | CSRWriteFenceM;
|
||||||
|
// on Trap the memory stage should be flushed going into the W stage,
|
||||||
|
// except if the instruction causing the Trap is an ecall or ebreak.
|
||||||
|
assign FlushWCause = TrapM & ~(BreakpointFaultM | EcallFaultM);
|
||||||
|
|
||||||
// *** consider replacing CSRWriteFencePendingDEM with a flush rather than a stall.
|
assign StallFCause = '0;
|
||||||
assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
|
||||||
// stall in decode if instruction is a load/mul/csr dependent on previous
|
// stall in decode if instruction is a load/mul/csr dependent on previous
|
||||||
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
|
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FStallD) & ~FlushDCause;
|
||||||
assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
|
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
|
||||||
// WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap
|
// WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap
|
||||||
assign StallMCause = ((wfiM) & (~TrapM & ~IntPendingM));
|
assign StallMCause = ((wfiM) & (~TrapM & ~IntPendingM));
|
||||||
assign StallWCause = ((IFUStallF | LSUStallM) & ~TrapM); // | (FDivBusyE & ~TrapM & ~IntPendingM);
|
assign StallWCause = (IFUStallF | LSUStallM) & ~TrapM;
|
||||||
|
|
||||||
// head version
|
|
||||||
// assign StallWCause = LSUStallM | IFUStallF | (FDivBusyE & ~TrapM & ~IntPendingM); // *** FDivBusyE should look like DivBusyE
|
|
||||||
// assign StallMCause = (wfiM & (~TrapM & ~IntPendingM)); // | FDivBusyE;
|
|
||||||
// assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
|
|
||||||
// *** ross: my changes to cache and lsu need to disable ifu/lsu stalls on a Trap.
|
|
||||||
|
|
||||||
|
|
||||||
assign #1 StallF = StallFCause | StallD;
|
assign #1 StallF = StallFCause | StallD;
|
||||||
assign #1 StallD = StallDCause | StallE;
|
assign #1 StallD = StallDCause | StallE;
|
||||||
@ -89,10 +88,8 @@ module hazard(
|
|||||||
assign FirstUnstalledW = ~StallW & StallM;
|
assign FirstUnstalledW = ~StallW & StallM;
|
||||||
|
|
||||||
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
||||||
assign #1 FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE;
|
assign #1 FlushD = FirstUnstalledD | FlushDCause;
|
||||||
assign #1 FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE; // *** why is BPPredWrongE here, but not needed in simple processor
|
assign #1 FlushE = FirstUnstalledE | FlushECause ; // *** why is BPPredWrongE here, but not needed in simple processor
|
||||||
assign #1 FlushM = FirstUnstalledM | TrapM | RetM;
|
assign #1 FlushM = FirstUnstalledM | FlushMCause;
|
||||||
// on Trap the memory stage should be flushed going into the W stage,
|
assign #1 FlushW = FirstUnstalledW | FlushWCause;
|
||||||
// except if the instruction causing the Trap is an ecall or ebreak.
|
|
||||||
assign #1 FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM));
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -65,10 +65,11 @@ module controller(
|
|||||||
output logic FWriteIntM,
|
output logic FWriteIntM,
|
||||||
// Writeback stage control signals
|
// Writeback stage control signals
|
||||||
input logic StallW, FlushW,
|
input logic StallW, FlushW,
|
||||||
output logic RegWriteW, // for datapath and Hazard Unit
|
output logic RegWriteW, DivW, // for datapath and Hazard Unit
|
||||||
output logic [2:0] ResultSrcW,
|
output logic [2:0] ResultSrcW,
|
||||||
// Stall during CSRs
|
// Stall during CSRs
|
||||||
output logic CSRWriteFencePendingDEM,
|
//output logic CSRWriteFencePendingDEM,
|
||||||
|
output logic CSRWriteFenceM,
|
||||||
output logic StoreStallD
|
output logic StoreStallD
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ module controller(
|
|||||||
logic CSRZeroSrcD;
|
logic CSRZeroSrcD;
|
||||||
logic CSRReadD;
|
logic CSRReadD;
|
||||||
logic [1:0] AtomicD;
|
logic [1:0] AtomicD;
|
||||||
logic FenceD;
|
logic FenceXD;
|
||||||
logic InvalidateICacheD, FlushDCacheD;
|
logic InvalidateICacheD, FlushDCacheD;
|
||||||
logic CSRWriteD, CSRWriteE;
|
logic CSRWriteD, CSRWriteE;
|
||||||
logic InstrValidD, InstrValidE;
|
logic InstrValidD, InstrValidE;
|
||||||
@ -108,7 +109,9 @@ module controller(
|
|||||||
logic IEURegWriteE;
|
logic IEURegWriteE;
|
||||||
logic IllegalERegAdrD;
|
logic IllegalERegAdrD;
|
||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic FencePendingD, FencePendingE, FencePendingM;
|
logic FenceD, FenceE, FenceM;
|
||||||
|
logic SFenceVmaD;
|
||||||
|
logic DivE, DivM;
|
||||||
|
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
@ -176,11 +179,12 @@ module controller(
|
|||||||
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
|
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
|
||||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
||||||
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
|
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
|
||||||
PrivilegedD, FenceD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
||||||
|
|
||||||
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
||||||
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
|
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
|
||||||
assign FencePendingD = PrivilegedD & (InstrD[31:25] == 7'b0001001) | FenceD; // possible sfence.vma or fence.i
|
assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001);
|
||||||
|
assign FenceD = SFenceVmaD | FenceXD; // possible sfence.vma or fence.i
|
||||||
|
|
||||||
// ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
|
// ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
|
||||||
assign sltD = (Funct3D == 3'b010);
|
assign sltD = (Funct3D == 3'b010);
|
||||||
@ -195,7 +199,7 @@ module controller(
|
|||||||
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
||||||
if (`ZIFENCEI_SUPPORTED & `ICACHE) begin:fencei
|
if (`ZIFENCEI_SUPPORTED & `ICACHE) begin:fencei
|
||||||
logic FenceID;
|
logic FenceID;
|
||||||
assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
||||||
assign InvalidateICacheD = FenceID;
|
assign InvalidateICacheD = FenceID;
|
||||||
assign FlushDCacheD = FenceID;
|
assign FlushDCacheD = FenceID;
|
||||||
end else begin:fencei
|
end else begin:fencei
|
||||||
@ -208,8 +212,8 @@ module controller(
|
|||||||
|
|
||||||
// Execute stage pipeline control register and logic
|
// Execute stage pipeline control register and logic
|
||||||
flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE,
|
flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE,
|
||||||
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FencePendingD, InstrValidD},
|
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD},
|
||||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE});
|
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE});
|
||||||
|
|
||||||
// Branch Logic
|
// Branch Logic
|
||||||
assign BranchSignedE = ~(Funct3E[2:1] == 2'b11);
|
assign BranchSignedE = ~(Funct3E[2:1] == 2'b11);
|
||||||
@ -222,19 +226,21 @@ module controller(
|
|||||||
assign MemReadE = MemRWE[1];
|
assign MemReadE = MemRWE[1];
|
||||||
assign SCE = (ResultSrcE == 3'b100);
|
assign SCE = (ResultSrcE == 3'b100);
|
||||||
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
||||||
|
assign DivE = MDUE & Funct3E[2]; // Division operation
|
||||||
|
|
||||||
// Memory stage pipeline control register
|
// Memory stage pipeline control register
|
||||||
flopenrc #(19) controlregM(clk, reset, FlushM, ~StallM,
|
flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM,
|
||||||
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FencePendingE, InstrValidE},
|
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, DivE},
|
||||||
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FencePendingM, InstrValidM});
|
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, DivM});
|
||||||
|
|
||||||
// Writeback stage pipeline control register
|
// Writeback stage pipeline control register
|
||||||
flopenrc #(4) controlregW(clk, reset, FlushW, ~StallW,
|
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
|
||||||
{RegWriteM, ResultSrcM},
|
{RegWriteM, ResultSrcM, DivM},
|
||||||
{RegWriteW, ResultSrcW});
|
{RegWriteW, ResultSrcW, DivW});
|
||||||
|
|
||||||
// Stall pipeline at Fetch if a CSR Write or Fence is pending in the subsequent stages
|
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
|
||||||
assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FencePendingD | FencePendingE | FencePendingM;
|
assign CSRWriteFenceM = CSRWriteM | FenceM;
|
||||||
|
// assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
|
||||||
|
|
||||||
// the synchronous DTIM cannot read immediately after write
|
// the synchronous DTIM cannot read immediately after write
|
||||||
// a cache cannot read or write immediately after a write
|
// a cache cannot read or write immediately after a write
|
||||||
|
@ -57,14 +57,15 @@ module datapath (
|
|||||||
output logic [`XLEN-1:0] WriteDataM,
|
output logic [`XLEN-1:0] WriteDataM,
|
||||||
// Writeback stage signals
|
// Writeback stage signals
|
||||||
input logic StallW, FlushW,
|
input logic StallW, FlushW,
|
||||||
(* mark_debug = "true" *) input logic RegWriteW,
|
(* mark_debug = "true" *) input logic RegWriteW, DivW,
|
||||||
input logic SquashSCW,
|
input logic SquashSCW,
|
||||||
input logic [2:0] ResultSrcW,
|
input logic [2:0] ResultSrcW,
|
||||||
input logic [`XLEN-1:0] FCvtIntResW,
|
input logic [`XLEN-1:0] FCvtIntResW,
|
||||||
input logic [`XLEN-1:0] ReadDataW,
|
input logic [`XLEN-1:0] ReadDataW,
|
||||||
// input logic [`XLEN-1:0] PCLinkW,
|
// input logic [`XLEN-1:0] PCLinkW,
|
||||||
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
||||||
// Hazard Unit signals
|
input logic [`XLEN-1:0] FPIntDivResultW,
|
||||||
|
// Hazard Unit signals
|
||||||
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
||||||
output logic [4:0] RdE, RdM, RdW
|
output logic [4:0] RdE, RdM, RdW
|
||||||
);
|
);
|
||||||
@ -85,7 +86,7 @@ module datapath (
|
|||||||
// Writeback stage signals
|
// Writeback stage signals
|
||||||
logic [`XLEN-1:0] SCResultW;
|
logic [`XLEN-1:0] SCResultW;
|
||||||
logic [`XLEN-1:0] ResultW;
|
logic [`XLEN-1:0] ResultW;
|
||||||
logic [`XLEN-1:0] IFResultW, IFCvtResultW;
|
logic [`XLEN-1:0] IFResultW, IFCvtResultW, MulDivResultW;
|
||||||
|
|
||||||
// Decode stage
|
// Decode stage
|
||||||
assign Rs1D = InstrD[19:15];
|
assign Rs1D = InstrD[19:15];
|
||||||
@ -125,10 +126,16 @@ module datapath (
|
|||||||
if (`F_SUPPORTED) begin:fpmux
|
if (`F_SUPPORTED) begin:fpmux
|
||||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
||||||
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
|
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
|
||||||
|
if (`IDIV_ON_FPU) begin
|
||||||
|
mux2 #(`XLEN) divresultmuxW(MDUResultW, FPIntDivResultW, DivW, MulDivResultW);
|
||||||
|
end else begin
|
||||||
|
assign MulDivResultW = MDUResultW;
|
||||||
|
end
|
||||||
end else begin:fpmux
|
end else begin:fpmux
|
||||||
assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW;
|
assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW;
|
||||||
|
assign MulDivResultW = MDUResultW;
|
||||||
end
|
end
|
||||||
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
|
||||||
|
|
||||||
// handle Store Conditional result if atomic extension supported
|
// handle Store Conditional result if atomic extension supported
|
||||||
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
|
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
|
||||||
|
@ -58,6 +58,7 @@ module ieu (
|
|||||||
output logic InvalidateICacheM, FlushDCacheM,
|
output logic InvalidateICacheM, FlushDCacheM,
|
||||||
|
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
|
input logic [`XLEN-1:0] FPIntDivResultW,
|
||||||
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
||||||
input logic [`XLEN-1:0] FCvtIntResW,
|
input logic [`XLEN-1:0] FCvtIntResW,
|
||||||
output logic [4:0] RdW,
|
output logic [4:0] RdW,
|
||||||
@ -70,7 +71,7 @@ module ieu (
|
|||||||
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD,
|
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD,
|
||||||
output logic PCSrcE,
|
output logic PCSrcE,
|
||||||
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
||||||
output logic CSRWriteFencePendingDEM,
|
output logic CSRWriteFenceM,
|
||||||
output logic StoreStallD
|
output logic StoreStallD
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -83,6 +84,7 @@ module ieu (
|
|||||||
logic SCE;
|
logic SCE;
|
||||||
logic [4:0] RdE;
|
logic [4:0] RdE;
|
||||||
logic FWriteIntM;
|
logic FWriteIntM;
|
||||||
|
logic DivW;
|
||||||
|
|
||||||
// forwarding signals
|
// forwarding signals
|
||||||
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
|
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
|
||||||
@ -99,15 +101,15 @@ module ieu (
|
|||||||
.Funct3E, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
|
.Funct3E, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
||||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
||||||
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWriteFencePendingDEM, .StoreStallD);
|
.StallW, .FlushW, .RegWriteW, .DivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
|
||||||
|
|
||||||
datapath dp(
|
datapath dp(
|
||||||
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||||
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
|
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
|
||||||
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
|
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
|
||||||
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
|
.StallW, .FlushW, .RegWriteW, .DivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
|
||||||
.CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
.CSRReadValW, .MDUResultW, .FPIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
||||||
|
|
||||||
forward fw(
|
forward fw(
|
||||||
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
|
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
|
||||||
|
@ -55,7 +55,8 @@ module ifu (
|
|||||||
input logic RetM, TrapM,
|
input logic RetM, TrapM,
|
||||||
output logic CommittedF,
|
output logic CommittedF,
|
||||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||||
input logic InvalidateICacheM,
|
input logic CSRWriteFenceM,
|
||||||
|
input logic InvalidateICacheM,
|
||||||
output logic [31:0] InstrD, InstrM,
|
output logic [31:0] InstrD, InstrM,
|
||||||
output logic [`XLEN-1:0] PCM,
|
output logic [`XLEN-1:0] PCM,
|
||||||
// branch predictor
|
// branch predictor
|
||||||
@ -288,10 +289,10 @@ module ifu (
|
|||||||
assign PrivilegedChangePCM = RetM | TrapM;
|
assign PrivilegedChangePCM = RetM | TrapM;
|
||||||
|
|
||||||
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
|
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
|
||||||
if(`ICACHE)
|
// if(`ICACHE | `ZICSR_SUPPORTED)
|
||||||
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM),
|
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(CSRWriteFenceM),
|
||||||
.y(PCNext2F));
|
.y(PCNext2F));
|
||||||
else assign PCNext2F = PCNext1F;
|
// else assign PCNext2F = PCNext1F;
|
||||||
if(`ZICSR_SUPPORTED)
|
if(`ZICSR_SUPPORTED)
|
||||||
mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM),
|
mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM),
|
||||||
.y(UnalignedPCNextF));
|
.y(UnalignedPCNextF));
|
||||||
|
@ -36,7 +36,7 @@ module intdivrestoring (
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic TrapM,
|
input logic FlushE,
|
||||||
input logic DivSignedE, W64E,
|
input logic DivSignedE, W64E,
|
||||||
input logic DivE,
|
input logic DivE,
|
||||||
//input logic [`XLEN-1:0] SrcAE, SrcBE,
|
//input logic [`XLEN-1:0] SrcAE, SrcBE,
|
||||||
@ -48,10 +48,10 @@ module intdivrestoring (
|
|||||||
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
||||||
statetype state;
|
statetype state;
|
||||||
|
|
||||||
logic [`XLEN-1:0] W[`DIV_BITSPERCYCLE:0];
|
logic [`XLEN-1:0] W[`IDIV_BITSPERCYCLE:0];
|
||||||
logic [`XLEN-1:0] XQ[`DIV_BITSPERCYCLE:0];
|
logic [`XLEN-1:0] XQ[`IDIV_BITSPERCYCLE:0];
|
||||||
logic [`XLEN-1:0] DinE, XinE, DnE, DAbsBE, DAbsB, XnE, XInitE, WnM, XQnM;
|
logic [`XLEN-1:0] DinE, XinE, DnE, DAbsBE, DAbsB, XnE, XInitE, WnM, XQnM;
|
||||||
localparam STEPBITS = $clog2(`XLEN/`DIV_BITSPERCYCLE);
|
localparam STEPBITS = $clog2(`XLEN/`IDIV_BITSPERCYCLE);
|
||||||
logic [STEPBITS:0] step;
|
logic [STEPBITS:0] step;
|
||||||
logic Div0E, Div0M;
|
logic Div0E, Div0M;
|
||||||
logic DivStartE, SignXE, SignDE, NegQE, NegWM, NegQM;
|
logic DivStartE, SignXE, SignDE, NegQE, NegWM, NegQM;
|
||||||
@ -91,8 +91,8 @@ module intdivrestoring (
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|
||||||
// initialization multiplexers on first cycle of operation
|
// initialization multiplexers on first cycle of operation
|
||||||
mux2 #(`XLEN) wmux(W[`DIV_BITSPERCYCLE], {`XLEN{1'b0}}, DivStartE, WNext);
|
mux2 #(`XLEN) wmux(W[`IDIV_BITSPERCYCLE], {`XLEN{1'b0}}, DivStartE, WNext);
|
||||||
mux2 #(`XLEN) xmux(XQ[`DIV_BITSPERCYCLE], XInitE, DivStartE, XQNext);
|
mux2 #(`XLEN) xmux(XQ[`IDIV_BITSPERCYCLE], XInitE, DivStartE, XQNext);
|
||||||
|
|
||||||
// registers before division steps
|
// registers before division steps
|
||||||
flopen #(`XLEN) wreg(clk, DivBusyE, WNext, W[0]);
|
flopen #(`XLEN) wreg(clk, DivBusyE, WNext, W[0]);
|
||||||
@ -101,7 +101,7 @@ module intdivrestoring (
|
|||||||
|
|
||||||
// one copy of divstep for each bit produced per cycle
|
// one copy of divstep for each bit produced per cycle
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i=0; i<`DIV_BITSPERCYCLE; i = i+1)
|
for (i=0; i<`IDIV_BITSPERCYCLE; i = i+1)
|
||||||
intdivrestoringstep divstep(W[i], XQ[i], DAbsB, W[i+1], XQ[i+1]);
|
intdivrestoringstep divstep(W[i], XQ[i], DAbsB, W[i+1], XQ[i+1]);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -122,7 +122,7 @@ module intdivrestoring (
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|
||||||
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
||||||
if (reset | TrapM) begin
|
if (reset | FlushE) begin
|
||||||
state <= IDLE;
|
state <= IDLE;
|
||||||
end else if (DivStartE) begin
|
end else if (DivStartE) begin
|
||||||
step <= 1;
|
step <= 1;
|
||||||
|
@ -42,7 +42,7 @@ module muldiv (
|
|||||||
// Divide Done
|
// Divide Done
|
||||||
output logic DivBusyE,
|
output logic DivBusyE,
|
||||||
// hazards
|
// hazards
|
||||||
input logic StallM, StallW, FlushM, FlushW, TrapM
|
input logic StallM, StallW, FlushE, FlushM, FlushW
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] MDUResultM;
|
logic [`XLEN-1:0] MDUResultM;
|
||||||
@ -59,10 +59,17 @@ module muldiv (
|
|||||||
|
|
||||||
// Divide
|
// Divide
|
||||||
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
||||||
assign DivE = MDUE & Funct3E[2];
|
// When F extensions are supported, use the FPU divider instead
|
||||||
assign DivSignedE = ~Funct3E[0];
|
if (`IDIV_ON_FPU) begin
|
||||||
intdivrestoring div(.clk, .reset, .StallM, .TrapM, .DivSignedE, .W64E, .DivE,
|
assign QuotM = 0;
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
assign RemM = 0;
|
||||||
|
assign DivBusyE = 0;
|
||||||
|
end else begin
|
||||||
|
assign DivE = MDUE & Funct3E[2];
|
||||||
|
assign DivSignedE = ~Funct3E[0];
|
||||||
|
intdivrestoring div(.clk, .reset, .StallM, .FlushE, .DivSignedE, .W64E, .DivE,
|
||||||
|
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||||
|
end
|
||||||
|
|
||||||
// Result multiplexer
|
// Result multiplexer
|
||||||
always_comb
|
always_comb
|
||||||
|
@ -79,7 +79,7 @@ module wallypipelinedcore (
|
|||||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||||
logic InvalidateICacheM, FlushDCacheM;
|
logic InvalidateICacheM, FlushDCacheM;
|
||||||
logic PCSrcE;
|
logic PCSrcE;
|
||||||
logic CSRWriteFencePendingDEM;
|
logic CSRWriteFenceM;
|
||||||
logic DivBusyE;
|
logic DivBusyE;
|
||||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
@ -99,6 +99,7 @@ module wallypipelinedcore (
|
|||||||
logic FpLoadStoreM;
|
logic FpLoadStoreM;
|
||||||
logic [1:0] FResSelW;
|
logic [1:0] FResSelW;
|
||||||
logic [4:0] SetFflagsM;
|
logic [4:0] SetFflagsM;
|
||||||
|
logic [`XLEN-1:0] FPIntDivResultW;
|
||||||
|
|
||||||
// memory management unit signals
|
// memory management unit signals
|
||||||
logic ITLBWriteF;
|
logic ITLBWriteF;
|
||||||
@ -182,7 +183,7 @@ module wallypipelinedcore (
|
|||||||
.BPPredWrongE,
|
.BPPredWrongE,
|
||||||
|
|
||||||
// Mem
|
// Mem
|
||||||
.RetM, .TrapM, .CommittedF, .PrivilegedNextPCM, .InvalidateICacheM,
|
.RetM, .TrapM, .CommittedF, .PrivilegedNextPCM, .InvalidateICacheM, .CSRWriteFenceM,
|
||||||
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
|
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
|
||||||
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||||
|
|
||||||
@ -228,7 +229,7 @@ module wallypipelinedcore (
|
|||||||
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
|
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
|
||||||
|
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
.CSRReadValW, .MDUResultW,
|
.CSRReadValW, .MDUResultW, .FPIntDivResultW,
|
||||||
.RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
|
.RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
|
||||||
.InstrValidM,
|
.InstrValidM,
|
||||||
.FCvtIntResW,
|
.FCvtIntResW,
|
||||||
@ -240,7 +241,7 @@ module wallypipelinedcore (
|
|||||||
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
|
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.PCSrcE,
|
.PCSrcE,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
||||||
.CSRWriteFencePendingDEM, .StoreStallD
|
.CSRWriteFenceM, .StoreStallD
|
||||||
|
|
||||||
); // integer execution unit: integer register file, datapath and controller
|
); // integer execution unit: integer register file, datapath and controller
|
||||||
|
|
||||||
@ -316,7 +317,7 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
|
|
||||||
hazard hzu(
|
hazard hzu(
|
||||||
.BPPredWrongE, .CSRWriteFencePendingDEM, .RetM, .TrapM,
|
.BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM,
|
||||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.LSUStallM, .IFUStallF,
|
.LSUStallM, .IFUStallF,
|
||||||
.FCvtIntStallD, .FStallD,
|
.FCvtIntStallD, .FStallD,
|
||||||
@ -374,7 +375,7 @@ module wallypipelinedcore (
|
|||||||
.ForwardedSrcAE, .ForwardedSrcBE,
|
.ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.Funct3E, .Funct3M, .MDUE, .W64E,
|
.Funct3E, .Funct3M, .MDUE, .W64E,
|
||||||
.MDUResultW, .DivBusyE,
|
.MDUResultW, .DivBusyE,
|
||||||
.StallM, .StallW, .FlushM, .FlushW, .TrapM
|
.StallM, .StallW, .FlushE, .FlushM, .FlushW
|
||||||
);
|
);
|
||||||
end else begin // no M instructions supported
|
end else begin // no M instructions supported
|
||||||
assign MDUResultW = 0;
|
assign MDUResultW = 0;
|
||||||
@ -389,7 +390,7 @@ module wallypipelinedcore (
|
|||||||
.ReadDataW(ReadDataW[`FLEN-1:0]),// Read data from memory
|
.ReadDataW(ReadDataW[`FLEN-1:0]),// Read data from memory
|
||||||
.ForwardedSrcAE, // Integer input being processed (from IEU)
|
.ForwardedSrcAE, // Integer input being processed (from IEU)
|
||||||
.StallE, .StallM, .StallW, // stall signals from HZU
|
.StallE, .StallM, .StallW, // stall signals from HZU
|
||||||
.TrapM,
|
//.TrapM,
|
||||||
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
||||||
.RdM, .RdW, // which FP register to write to (from IEU)
|
.RdM, .RdW, // which FP register to write to (from IEU)
|
||||||
.STATUS_FS, // is floating-point enabled?
|
.STATUS_FS, // is floating-point enabled?
|
||||||
@ -405,7 +406,8 @@ module wallypipelinedcore (
|
|||||||
.FCvtIntW, // fpu result selection
|
.FCvtIntW, // fpu result selection
|
||||||
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
|
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
|
||||||
.IllegalFPUInstrM, // Is the instruction an illegal fpu instruction
|
.IllegalFPUInstrM, // Is the instruction an illegal fpu instruction
|
||||||
.SetFflagsM // FPU flags (to privileged unit)
|
.SetFflagsM, // FPU flags (to privileged unit)
|
||||||
|
.FPIntDivResultW
|
||||||
); // floating point unit
|
); // floating point unit
|
||||||
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
||||||
assign FStallD = 0;
|
assign FStallD = 0;
|
||||||
|
@ -434,7 +434,7 @@ module riscvassertions;
|
|||||||
initial begin
|
initial begin
|
||||||
assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||||
assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
||||||
assert (`DIV_BITSPERCYCLE == 1 | `DIV_BITSPERCYCLE==2 | `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4");
|
assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||||
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
||||||
assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
||||||
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||||
@ -463,6 +463,7 @@ module riscvassertions;
|
|||||||
assert ((`DCACHE == 0 & `ICACHE == 0) | `BUS) else $error("Dcache and Icache requires DBUS.");
|
assert ((`DCACHE == 0 & `ICACHE == 0) | `BUS) else $error("Dcache and Icache requires DBUS.");
|
||||||
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
||||||
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||||
|
assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
|
||||||
end
|
end
|
||||||
|
|
||||||
// *** DH 8/23/
|
// *** DH 8/23/
|
||||||
|
@ -8,8 +8,7 @@ wally_workdir = $(work)/wally-riscv-arch-test
|
|||||||
current_dir = $(shell pwd)
|
current_dir = $(shell pwd)
|
||||||
#XLEN ?= 64
|
#XLEN ?= 64
|
||||||
|
|
||||||
all: root fsd_fld_tempfix arch32 wally32 wally32e arch64 wally64
|
all: root arch32 wally32 wally32e arch64 wally64
|
||||||
#all: root fsd_fld_tempfix wally32
|
|
||||||
|
|
||||||
root:
|
root:
|
||||||
mkdir -p $(work_dir)
|
mkdir -p $(work_dir)
|
||||||
@ -20,14 +19,8 @@ root:
|
|||||||
sed 's,{0},$(current_dir),g;s,{1},64gc,g' config.ini > config64.ini
|
sed 's,{0},$(current_dir),g;s,{1},64gc,g' config.ini > config64.ini
|
||||||
sed 's,{0},$(current_dir),g;s,{1},32e,g' config.ini > config32e.ini
|
sed 's,{0},$(current_dir),g;s,{1},32e,g' config.ini > config32e.ini
|
||||||
|
|
||||||
fsd_fld_tempfix:
|
|
||||||
# this is a temporary fix, there's a typo on the rv64i_m/D/src/d_fsd-align-01.S and rv64i_m/D/src/d_fld-align-01.S tests
|
|
||||||
# https://github.com/riscv-non-isa/riscv-arch-test/issues/266
|
|
||||||
find ../../addins/riscv-arch-test/riscv-test-suite -type f -name "*d_fld-align*.S" | xargs -I{} sed -i 's,regex(\.\*32\.\*),regex(\.\*64\.\*),g' {}
|
|
||||||
find ../../addins/riscv-arch-test/riscv-test-suite -type f -name "*d_fsd-align*.S" | xargs -I{} sed -i 's,regex(\.\*32\.\*),regex(\.\*64\.\*),g' {}
|
|
||||||
|
|
||||||
arch32:
|
arch32:
|
||||||
riscof --verbose debug run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env --no-browser
|
riscof run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env --no-browser
|
||||||
rsync -a $(work_dir)/rv32i_m/ $(arch_workdir)/rv32i_m/ || echo "error suppressed"
|
rsync -a $(work_dir)/rv32i_m/ $(arch_workdir)/rv32i_m/ || echo "error suppressed"
|
||||||
|
|
||||||
arch64:
|
arch64:
|
||||||
|
Loading…
Reference in New Issue
Block a user