mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge upstream changes
This commit is contained in:
commit
c0ee17b6ac
47
wally-pipelined/bin/extractFunctionRadix.sh
Executable file
47
wally-pipelined/bin/extractFunctionRadix.sh
Executable file
@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
|
||||
allProgramRadixFile="FunctionRadix"
|
||||
|
||||
index=0
|
||||
|
||||
for objDumpFile in "$@";
|
||||
do
|
||||
# get the lines with named labels from the obj files.
|
||||
# 64 bit addresses
|
||||
listOfAddr16=`egrep -i '^[0-9]{16} <[0-9a-zA-Z_]+>' $objDumpFile`
|
||||
# 32 bit addresses
|
||||
listOfAddr8=`egrep -i '^[0-9]{8} <[0-9a-zA-Z_]+>' $objDumpFile`
|
||||
listOfAddr=`echo "$listOfAddr16" "$listOfAddr8"`
|
||||
|
||||
# parse out the addresses and the labels
|
||||
addresses=`echo "$listOfAddr" | awk '{print $1}'`
|
||||
labels=`echo "$listOfAddr" | awk '{print "\""$2"\"", "-color \"SpringGreen\","}' | tr -d '<>:'`
|
||||
|
||||
echo "$addresses" > $objDumpFile.addr
|
||||
|
||||
# need to add some formatting to each line
|
||||
numLines=`echo "$listOfAddr" | wc -l`
|
||||
prefix=`yes " 16#" | head -n $numLines`
|
||||
midfix=`yes "# " | head -n $numLines`
|
||||
|
||||
# paste echos each of the 4 parts on a per line basis.
|
||||
#-d'\0' sets no delimiter
|
||||
temp=`paste -d'\0' <(echo "$prefix") <(echo "$addresses") <(echo "$midfix") <(echo "$labels")`
|
||||
|
||||
# remove the last comma
|
||||
temp2=${temp::-1}
|
||||
|
||||
echo "radix define Functions {" > $objDumpFile.do
|
||||
echo "$temp2" >> $objDumpFile.do
|
||||
echo " -default hex -color green" >> $objDumpFile.do
|
||||
echo "}" >> $objDumpFile.do
|
||||
|
||||
# now create the all in one version
|
||||
# put the index at the begining of each line
|
||||
allAddresses=`paste -d'\0' <(printf "%04x" "$index") <(echo "$addresses")`
|
||||
|
||||
printf "%04x%s" "$index" "$addresses" >> $allProgramRadixFile.addr
|
||||
|
||||
index=$(($index+1))
|
||||
|
||||
done
|
1024
wally-pipelined/config/busybear/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/busybear/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
//////////////////////////////////////////
|
||||
// wally-config.vh
|
||||
// busybear-config.vh
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 4 January 2021
|
||||
// Modified:
|
||||
@ -24,6 +24,7 @@
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`define BUSYBEAR
|
||||
// RV32 or RV64: XLEN = 32 or 64
|
||||
`define XLEN 64
|
||||
|
||||
@ -61,14 +62,16 @@
|
||||
// Peripheral memory space extends from BASE to BASE+RANGE
|
||||
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
|
||||
|
||||
`define TIMBASE 64'h0000000080000000
|
||||
`define TIMRANGE 64'h000000000007FFFF
|
||||
`define CLINTBASE 64'h0000000002000000
|
||||
`define CLINTRANGE 64'h000000000000FFFF
|
||||
`define GPIOBASE 64'h0000000010012000
|
||||
`define GPIORANGE 64'h00000000000000FF
|
||||
`define UARTBASE 64'h0000000010000000
|
||||
`define UARTRANGE 64'h0000000000000007
|
||||
`define TIMBASE 32'h80000000
|
||||
`define TIMRANGE 32'h07FFFFFF
|
||||
`define BOOTTIMBASE 32'h00000000 //only needs to go from 0x1000 to 0x2FFF, extending to a power of 2
|
||||
`define BOOTTIMRANGE 32'h00003FFF
|
||||
`define CLINTBASE 32'h02000000
|
||||
`define CLINTRANGE 32'h0000BFFF
|
||||
//`define GPIOBASE 32'h10012000 // no GPIO in linux for now
|
||||
//`define GPIORANGE 32'h000000FF
|
||||
`define UARTBASE 32'h10000000
|
||||
`define UARTRANGE 32'h00000007
|
||||
// Bus Interface width
|
||||
`define AHBW 64
|
||||
|
||||
|
1024
wally-pipelined/config/coremark/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/coremark/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
1024
wally-pipelined/config/rv32ic/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/rv32ic/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
1024
wally-pipelined/config/rv64ic/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/rv64ic/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -27,8 +27,8 @@
|
||||
// RV32 or RV64: XLEN = 32 or 64
|
||||
`define XLEN 64
|
||||
|
||||
//`define MISA (32'h00000104)
|
||||
`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12)
|
||||
//`define MISA (32'h00000105)
|
||||
`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
|
||||
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
|
||||
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1)
|
||||
|
1024
wally-pipelined/config/rv64icfd/BTBPredictor.txt
Normal file
1024
wally-pipelined/config/rv64icfd/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,7 @@ def test_config(config, print_res=True):
|
||||
passed = search_log_for_text("no more .* to read", logname)
|
||||
else:
|
||||
cmd = "vsim -c >" + logname +" <<!\ndo wally-pipelined-batch-parallel.do ../config/" + config + " " + config + "\n!\n"
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
# check for success. grep returns 0 if found, 1 if not found
|
||||
passed = search_log_for_text("All tests ran without failures", logname)
|
||||
|
1
wally-pipelined/regression/sim-busybear
Executable file
1
wally-pipelined/regression/sim-busybear
Executable file
@ -0,0 +1 @@
|
||||
vsim -do wally-busybear.do
|
3
wally-pipelined/regression/sim-busybear-batch
Executable file
3
wally-pipelined/regression/sim-busybear-batch
Executable file
@ -0,0 +1,3 @@
|
||||
vsim -c <<!
|
||||
do wally-busybear-batch.do
|
||||
!
|
1024
wally-pipelined/regression/twoBitPredictor.txt
Normal file
1024
wally-pipelined/regression/twoBitPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
46
wally-pipelined/regression/wally-busybear-batch.do
Normal file
46
wally-pipelined/regression/wally-busybear-batch.do
Normal file
@ -0,0 +1,46 @@
|
||||
# wally-pipelined.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with testbench_busybear
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work-busybear] {
|
||||
vdel -all -lib work-busybear
|
||||
}
|
||||
vlib work-busybear
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
vlog +incdir+../config/busybear ../testbench/*.sv ../src/*/*.sv -suppress 2583
|
||||
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt +acc=+/testbench_busybear/dut/hart/ifu/bpred/DirPredictor/memory/memory +acc=+/testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/memory/memory work.testbench_busybear -o workopt
|
||||
|
||||
vsim workopt -suppress 8852,12070
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
run -all
|
||||
quit
|
@ -1,136 +1,171 @@
|
||||
# wally-pipelined.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with testbench_busybear
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work-busybear] {
|
||||
vdel -all -lib work-busybear
|
||||
}
|
||||
vlib work-busybear
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
# wally-pipelined.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with testbench_busybear
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work-busybear] {
|
||||
vdel -all -lib work-busybear
|
||||
}
|
||||
vlib work-busybear
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
vlog +incdir+../config/busybear ../testbench/*.sv ../src/*/*.sv -suppress 2583
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt +acc work.testbench_busybear -o workopt
|
||||
vsim workopt
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
add wave /testbench_busybear/clk
|
||||
add wave /testbench_busybear/reset
|
||||
add wave -divider
|
||||
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt +acc work.testbench_busybear -o workopt
|
||||
|
||||
vsim workopt -suppress 8852,12070
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
add wave /testbench_busybear/clk
|
||||
add wave /testbench_busybear/reset
|
||||
add wave -divider
|
||||
add wave -hex /testbench_busybear/PCtext
|
||||
add wave -hex /testbench_busybear/pcExpected
|
||||
add wave -hex /testbench_busybear/dut/ifu/PCF
|
||||
add wave -hex /testbench_busybear/dut/ifu/InstrF
|
||||
add wave /testbench_busybear/lastInstrF
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCF
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/InstrF
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/StallD
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/FlushD
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/InstrRawD
|
||||
add wave /testbench_busybear/CheckInstrF
|
||||
add wave /testbench_busybear/lastCheckInstrF
|
||||
add wave /testbench_busybear/speculative
|
||||
add wave /testbench_busybear/lastPC2
|
||||
add wave -divider
|
||||
# registers!
|
||||
add wave -divider
|
||||
add wave -divider
|
||||
add wave /testbench_busybear/dut/uncore/HSELBootTim
|
||||
add wave /testbench_busybear/dut/uncore/HSELTim
|
||||
add wave /testbench_busybear/dut/uncore/HREADTim
|
||||
add wave /testbench_busybear/dut/uncore/dtim/HREADTim0
|
||||
add wave /testbench_busybear/dut/uncore/HREADYTim
|
||||
add wave -divider
|
||||
add wave /testbench_busybear/dut/uncore/HREADBootTim
|
||||
add wave /testbench_busybear/dut/uncore/bootdtim/HREADTim0
|
||||
add wave /testbench_busybear/dut/uncore/HREADYBootTim
|
||||
add wave /testbench_busybear/dut/uncore/HADDR
|
||||
add wave /testbench_busybear/dut/uncore/HRESP
|
||||
add wave /testbench_busybear/dut/uncore/HREADY
|
||||
add wave /testbench_busybear/dut/uncore/HRDATA
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MTVEC_REG
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MSTATUS_REG
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/SCOUNTEREN_REG
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MIE_REG
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MIDELEG_REG
|
||||
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MEDELEG_REG
|
||||
add wave -divider
|
||||
# registers!
|
||||
add wave -hex /testbench_busybear/regExpected
|
||||
add wave -hex /testbench_busybear/regNumExpected
|
||||
add wave -hex /testbench_busybear/HWRITE
|
||||
add wave -hex /testbench_busybear/dut/MemRWM[1]
|
||||
add wave -hex /testbench_busybear/dut/hart/MemRWM[1]
|
||||
add wave -hex /testbench_busybear/HWDATA
|
||||
add wave -hex /testbench_busybear/HRDATA
|
||||
add wave -hex /testbench_busybear/HADDR
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[1]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[2]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[3]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[4]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[5]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[6]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[7]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[8]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[9]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[10]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[11]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[12]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[13]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[14]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[15]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[16]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[17]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[18]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[19]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[20]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[21]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[22]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[23]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[24]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[25]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[26]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[27]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[28]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[29]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[30]
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[31]
|
||||
add wave /testbench_busybear/InstrFName
|
||||
add wave -hex /testbench_busybear/dut/ifu/PCD
|
||||
#add wave -hex /testbench_busybear/dut/ifu/InstrD
|
||||
add wave /testbench_busybear/InstrDName
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/ifu/PCE
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrE
|
||||
add wave /testbench_busybear/InstrEName
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/SrcAE
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/SrcBE
|
||||
add wave -hex /testbench_busybear/dut/ieu/dp/ALUResultE
|
||||
#add wave /testbench_busybear/dut/ieu/dp/PCSrcE
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/ifu/PCM
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrM
|
||||
add wave /testbench_busybear/InstrMName
|
||||
#add wave /testbench_busybear/dut/dmem/dtim/memwrite
|
||||
#add wave -hex /testbench_busybear/dut/dmem/AdrM
|
||||
#add wave -hex /testbench_busybear/dut/dmem/WriteDataM
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/ifu/PCW
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrW
|
||||
add wave /testbench_busybear/InstrWName
|
||||
#add wave /testbench_busybear/dut/ieu/dp/RegWriteW
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/ResultW
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/RdW
|
||||
#add wave -divider
|
||||
##add ww
|
||||
#add wave -hex -r /testbench_busybear/*
|
||||
#
|
||||
#-- Set Wave Output Items
|
||||
#TreeUpdate [SetDefaultTree]
|
||||
#WaveRestoreZoom {0 ps} {100 ps}
|
||||
#configure wave -namecolwidth 250
|
||||
#configure wave -valuecolwidth 120
|
||||
#configure wave -justifyvalue left
|
||||
#configure wave -signalnamewidth 0
|
||||
#configure wave -snapdistance 10
|
||||
#configure wave -datasetprefix 0
|
||||
#configure wave -rowmargin 4
|
||||
#configure wave -childrowmargin 2
|
||||
#set DefaultRadix hexadecimal
|
||||
#
|
||||
#-- Run the Simulation
|
||||
run 1483850
|
||||
#run -all
|
||||
##quit
|
||||
add wave -hex /testbench_busybear/readAdrExpected
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[1]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[2]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[3]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[4]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[5]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[6]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[7]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[8]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[9]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[10]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[11]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[12]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[13]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[14]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[15]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[16]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[17]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[18]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[19]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[20]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[21]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[22]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[23]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[24]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[25]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[26]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[27]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[28]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[29]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[30]
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[31]
|
||||
add wave /testbench_busybear/InstrFName
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCD
|
||||
#add wave -hex /testbench_busybear/dut/hart/ifu/InstrD
|
||||
add wave /testbench_busybear/InstrDName
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCE
|
||||
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrE
|
||||
add wave /testbench_busybear/InstrEName
|
||||
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/SrcAE
|
||||
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/SrcBE
|
||||
add wave -hex /testbench_busybear/dut/hart/ieu/dp/ALUResultE
|
||||
#add wave /testbench_busybear/dut/hart/ieu/dp/PCSrcE
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCM
|
||||
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrM
|
||||
add wave /testbench_busybear/InstrMName
|
||||
#add wave /testbench_busybear/dut/hart/dmem/dtim/memwrite
|
||||
#add wave -hex /testbench_busybear/dut/hart/dmem/AdrM
|
||||
#add wave -hex /testbench_busybear/dut/hart/dmem/WriteDataM
|
||||
#add wave -divider
|
||||
add wave -hex /testbench_busybear/dut/hart/ifu/PCW
|
||||
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrW
|
||||
add wave /testbench_busybear/InstrWName
|
||||
#add wave /testbench_busybear/dut/hart/ieu/dp/RegWriteW
|
||||
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/ResultW
|
||||
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/RdW
|
||||
#add wave -divider
|
||||
##add ww
|
||||
add wave -hex -r /testbench_busybear/*
|
||||
#
|
||||
#-- Set Wave Output Items
|
||||
#TreeUpdate [SetDefaultTree]
|
||||
#WaveRestoreZoom {0 ps} {100 ps}
|
||||
#configure wave -namecolwidth 250
|
||||
#configure wave -valuecolwidth 120
|
||||
#configure wave -justifyvalue left
|
||||
#configure wave -signalnamewidth 0
|
||||
#configure wave -snapdistance 10
|
||||
#configure wave -datasetprefix 0
|
||||
#configure wave -rowmargin 4
|
||||
#configure wave -childrowmargin 2
|
||||
#set DefaultRadix hexadecimal
|
||||
#
|
||||
#-- Run the Simulation
|
||||
run -all
|
||||
##quit
|
||||
|
@ -35,6 +35,14 @@ vlog +incdir+../config/coremark ../testbench/testbench-coremark.sv ../src/*/*.sv
|
||||
vopt +acc work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
|
80
wally-pipelined/regression/wally-peripherals-signals.do
Normal file
80
wally-pipelined/regression/wally-peripherals-signals.do
Normal file
@ -0,0 +1,80 @@
|
||||
# wally-peripherals-signals.do
|
||||
#
|
||||
# Created by Ben Bracker (bbracker@hmc.edu) on 4 Mar. 2021
|
||||
#
|
||||
# I really didn't like having to relaunch and recompile an entire sim
|
||||
# just because some signal names have changed, so I thought this
|
||||
# would be good to factor out.
|
||||
|
||||
restart -f
|
||||
delete wave /*
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
add wave /testbench/clk
|
||||
add wave /testbench/reset
|
||||
add wave -divider
|
||||
add wave /testbench/dut/hart/DataStall
|
||||
add wave /testbench/dut/hart/InstrStall
|
||||
add wave /testbench/dut/hart/StallF
|
||||
add wave /testbench/dut/hart/StallD
|
||||
add wave /testbench/dut/hart/FlushD
|
||||
add wave /testbench/dut/hart/FlushE
|
||||
add wave /testbench/dut/hart/FlushM
|
||||
add wave /testbench/dut/hart/FlushW
|
||||
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCF
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrF
|
||||
add wave /testbench/InstrFName
|
||||
#add wave -hex /testbench/dut/hart/ifu/PCD
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrD
|
||||
add wave /testbench/InstrDName
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCE
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrE
|
||||
add wave /testbench/InstrEName
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcAE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCM
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrM
|
||||
add wave /testbench/InstrMName
|
||||
add wave /testbench/dut/uncore/dtim/memwrite
|
||||
add wave -hex /testbench/dut/uncore/HADDR
|
||||
add wave -hex /testbench/dut/uncore/HWDATA
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCW
|
||||
add wave /testbench/InstrWName
|
||||
add wave /testbench/dut/hart/ieu/dp/RegWriteW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ResultW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/RdW
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ebu/*
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/uncore/uart/u/*
|
||||
add wave -divider
|
||||
#add ww
|
||||
add wave -hex -r /testbench/*
|
||||
|
||||
-- Set Wave Output Items
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreZoom {0 ps} {100 ps}
|
||||
configure wave -namecolwidth 250
|
||||
configure wave -valuecolwidth 120
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
set DefaultRadix hexadecimal
|
||||
|
||||
-- Run the Simulation
|
||||
#run 5000
|
||||
run -all
|
||||
#quit
|
||||
noview ../testbench/testbench-peripherals.sv
|
||||
view wave
|
@ -38,71 +38,13 @@ switch $argc {
|
||||
vopt +acc work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
add wave /testbench/clk
|
||||
add wave /testbench/reset
|
||||
add wave -divider
|
||||
add wave /testbench/dut/hart/ebu/IReadF
|
||||
add wave /testbench/dut/hart/DataStall
|
||||
add wave /testbench/dut/hart/InstrStall
|
||||
add wave /testbench/dut/hart/StallF
|
||||
add wave /testbench/dut/hart/StallD
|
||||
add wave /testbench/dut/hart/FlushD
|
||||
add wave /testbench/dut/hart/FlushE
|
||||
add wave /testbench/dut/hart/FlushM
|
||||
add wave /testbench/dut/hart/FlushW
|
||||
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCF
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrF
|
||||
add wave /testbench/InstrFName
|
||||
#add wave -hex /testbench/dut/hart/ifu/PCD
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrD
|
||||
add wave /testbench/InstrDName
|
||||
add wave -divider
|
||||
#add wave -hex /testbench/dut/hart/ifu/PCE
|
||||
#add wave -hex /testbench/dut/hart/ifu/InstrE
|
||||
add wave /testbench/InstrEName
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcAE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
|
||||
add wave /testbench/dut/hart/ieu/dp/PCSrcE
|
||||
add wave -divider
|
||||
#add wave -hex /testbench/dut/hart/ifu/PCM
|
||||
#add wave -hex /testbench/dut/hart/ifu/InstrM
|
||||
add wave /testbench/InstrMName
|
||||
add wave /testbench/dut/uncore/dtim/memwrite
|
||||
add wave -hex /testbench/dut/uncore/HADDR
|
||||
add wave -hex /testbench/dut/uncore/HWDATA
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCW
|
||||
add wave /testbench/InstrWName
|
||||
add wave /testbench/dut/hart/ieu/dp/RegWriteW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ResultW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/RdW
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/uncore/uart/u/*
|
||||
add wave -divider
|
||||
#add ww
|
||||
add wave -hex -r /testbench/*
|
||||
|
||||
-- Set Wave Output Items
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreZoom {0 ps} {100 ps}
|
||||
configure wave -namecolwidth 250
|
||||
configure wave -valuecolwidth 120
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
set DefaultRadix hexadecimal
|
||||
|
||||
-- Run the Simulation
|
||||
run 5000
|
||||
#run -all
|
||||
#quit
|
||||
do wally-peripherals-signals.do
|
||||
|
@ -34,5 +34,10 @@ vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583
|
||||
vopt work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
mem load -infile BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory
|
||||
|
||||
run -all
|
||||
quit
|
||||
|
@ -6,13 +6,12 @@
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
# 11 seconds to run batch mode
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Use this wally-pipelined-batch.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do ../config/rv64ic
|
||||
# do wally-pipelined-batch.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -c -do wally-pipelined.do ../config/rv64ic
|
||||
# vsim -do wally-pipelined-batch.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
@ -27,12 +26,25 @@ vlib work
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583
|
||||
|
||||
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
|
||||
# do wally-pipelined-batch.do ../config/rv32ic
|
||||
switch $argc {
|
||||
0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||
1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||
}
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt work.testbench -o workopt
|
||||
vopt +acc=+/testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory +acc=+/testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
run -all
|
||||
quit
|
||||
|
55
wally-pipelined/regression/wally-pipelined-ross.do
Normal file
55
wally-pipelined/regression/wally-pipelined-ross.do
Normal file
@ -0,0 +1,55 @@
|
||||
# wally-pipelined.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
|
||||
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
|
||||
# do wally-pipelined.do ../config/rv32ic
|
||||
switch $argc {
|
||||
0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||
1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||
}
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt +acc work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
do wave.do
|
||||
add log -r /*
|
||||
|
||||
-- Run the Simulation
|
||||
#run 1000
|
||||
run -all
|
||||
#quit
|
@ -38,6 +38,14 @@ switch $argc {
|
||||
vopt +acc work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||
# is important for perventing pessimistic x propagation.
|
||||
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
switch $argc {
|
||||
0 {mem load -infile ../config/rv64ic/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
@ -107,6 +115,6 @@ configure wave -childrowmargin 2
|
||||
set DefaultRadix hexadecimal
|
||||
|
||||
-- Run the Simulation
|
||||
#run 2000
|
||||
#run 4100
|
||||
run -all
|
||||
#quit
|
||||
|
1622
wally-pipelined/regression/wave-all.do
Normal file
1622
wally-pipelined/regression/wave-all.do
Normal file
File diff suppressed because it is too large
Load Diff
134
wally-pipelined/regression/wave.do
Normal file
134
wally-pipelined/regression/wave.do
Normal file
@ -0,0 +1,134 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /testbench/clk
|
||||
add wave -noupdate /testbench/reset
|
||||
add wave -noupdate -radix ascii /testbench/memfilename
|
||||
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE
|
||||
add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName
|
||||
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/InstrE
|
||||
add wave -noupdate -divider <NULL>
|
||||
add wave -noupdate /testbench/dut/hart/ebu/IReadF
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/InstrStall
|
||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall
|
||||
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF
|
||||
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD
|
||||
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE
|
||||
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushM
|
||||
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushW
|
||||
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF
|
||||
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD
|
||||
add wave -noupdate -group Bpred -expand -group direction -divider Update
|
||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePC
|
||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdateEN
|
||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePCIndex
|
||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePrediction
|
||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassF
|
||||
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassD
|
||||
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassE
|
||||
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrF
|
||||
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD
|
||||
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE
|
||||
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrM
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/BPPredWrongE
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNextF
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCF
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCPlus2or4F
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/BPPredPCF
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNext0F
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNext1F
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/SelBPPredF
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/BPPredWrongE
|
||||
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PrivilegedChangePCM
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/ValidBits
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/BPPredF
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/BTBValidF
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/LookUpPCIndexQ
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePCIndexQ
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/LookUpPC
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/TargetWrongE
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/FallThroughWrongE
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionDirWrongE
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionPCWrongE
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/BPPredWrongE
|
||||
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/InstrClassE
|
||||
add wave -noupdate -group BTB -divider Update
|
||||
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateEN
|
||||
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePC
|
||||
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateTarget
|
||||
add wave -noupdate -group BTB -divider Lookup
|
||||
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
|
||||
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/Valid
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/BTBPredPCF
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/CorrectPCE
|
||||
add wave -noupdate /testbench/dut/hart/ifu/bpred/FlushF
|
||||
add wave -noupdate /testbench/dut/hart/FlushF
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rf
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a1
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a2
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a3
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd1
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd2
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/we3
|
||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/wd3
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ALUResultW
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ReadDataW
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/PCLinkW
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW
|
||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW
|
||||
add wave -noupdate /testbench/dut/hart/ieu/c/RegWriteE
|
||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ifu/InstrD
|
||||
add wave -noupdate -group {Decode Stage} /testbench/InstrDName
|
||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
|
||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
|
||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
|
||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
|
||||
add wave -noupdate /testbench/InstrFName
|
||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemAdrM
|
||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemPAdrM
|
||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/WriteDataM
|
||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/ReadDataM
|
||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/dmem/MemRWM
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2E
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdE
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdM
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdW
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/MemReadE
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RegWriteM
|
||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RegWriteW
|
||||
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/ForwardAE
|
||||
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/ForwardBE
|
||||
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/LoadStallD
|
||||
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/WriteDataE
|
||||
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/ALUResultE
|
||||
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcAE
|
||||
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcBE
|
||||
add wave -noupdate /testbench/dut/hart/ieu/dp/ALUResultM
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 2} {231033 ns} 0} {{Cursor 3} {1276117 ns} 0}
|
||||
quietly wave cursor active 2
|
||||
configure wave -namecolwidth 250
|
||||
configure wave -valuecolwidth 518
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
configure wave -timelineunits ns
|
||||
update
|
||||
WaveRestoreZoom {1276094 ns} {1276208 ns}
|
@ -100,7 +100,7 @@ module dmem (
|
||||
|
||||
assign lrM = MemReadM && AtomicM;
|
||||
assign scM = MemRWM[0] && AtomicM;
|
||||
assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM == ReservationPAdrW) && ReservationValidW;
|
||||
assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM[`XLEN-1:2] == ReservationPAdrW) && ReservationValidW;
|
||||
assign SquashSCM = scM && ~WriteAdrMatchM;
|
||||
always_comb begin // ReservationValidM (next valiue of valid reservation)
|
||||
if (lrM) ReservationValidM = 1; // set valid on load reserve
|
||||
|
@ -102,7 +102,7 @@ module ahblite (
|
||||
else NextBusState = IDLE;
|
||||
INSTRREAD: //if (~HREADY & (MemReadM | MemWriteM)) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete
|
||||
if (~HREADY) NextBusState = INSTRREAD;
|
||||
else NextBusState = IDLE;
|
||||
else NextBusState = IDLE; // if (InstrReadF still high)
|
||||
INSTRREADMEMPENDING: if (~HREADY) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete
|
||||
else if (MemReadM) NextBusState = MEMREAD;
|
||||
else NextBusState = MEMWRITE; // must be write if not a read. Don't return to idle.
|
||||
|
@ -35,14 +35,14 @@ module add(r[105:0], s[105:0], t[157:0], sum[157:0],
|
||||
wire [157:0] sum0; // sum of compound adder +0 mode
|
||||
wire [157:0] sum1; // sum of compound adder +1 mode
|
||||
|
||||
// Invert addend if necessary
|
||||
// Invert addend if z's sign is diffrent from the product's sign
|
||||
|
||||
assign t2 = invz ? -t : t;
|
||||
|
||||
// Zero out product if Z >> product or product really should be zero
|
||||
|
||||
assign r2 = ~proddenorm & killprod ? 106'b0 : r;
|
||||
assign s2 = ~proddenorm & killprod ? 106'b0 : s;
|
||||
assign r2 = killprod ? 106'b0 : r;
|
||||
assign s2 = killprod ? 106'b0 : s;
|
||||
|
||||
// Compound adder
|
||||
// Consists of 3:2 CSA followed by long compound CPA
|
||||
|
@ -15,17 +15,17 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
killprod, bypsel[1], bypplus1, byppostnorm);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
input [51:0] z; // Fraction of addend z;
|
||||
input [51:0] z; // Fraction of addend z;
|
||||
input [12:0] ae; // sign of exponent of addend z;
|
||||
input [11:0] aligncnt; // amount to shift
|
||||
input xzero; // Input X = 0
|
||||
input yzero; // Input Y = 0
|
||||
input zzero; // Input Z = 0
|
||||
input zdenorm; // Input Z = denorm
|
||||
input proddenorm;
|
||||
input [11:0] aligncnt; // amount to shift
|
||||
input xzero; // Input X = 0
|
||||
input yzero; // Input Y = 0
|
||||
input zzero; // Input Z = 0
|
||||
input zdenorm; // Input Z is denormalized
|
||||
input proddenorm; // product is denormalized
|
||||
input [1:1] bypsel; // Select bypass to X or Z
|
||||
input bypplus1; // Add one to bypassed result
|
||||
input byppostnorm; // Postnormalize bypassed result
|
||||
input bypplus1; // Add one to bypassed result
|
||||
input byppostnorm; // Postnormalize bypassed result
|
||||
output [157:0] t; // aligned addend (54 bits left of bpt)
|
||||
output bs; // sticky bit of addend
|
||||
output ps; // sticky bit of product
|
||||
@ -34,13 +34,13 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
// Internal nodes
|
||||
|
||||
reg [157:0] t; // aligned addend from shifter
|
||||
reg killprod; // Z >> product
|
||||
reg killprod; // Z >> product
|
||||
reg bs; // sticky bit of addend
|
||||
reg ps; // sticky bit of product
|
||||
reg [7:0] i; // temp storage for finding sticky bit
|
||||
wire [52:0] z1; // Z plus 1
|
||||
wire [51:0] z2; // Z selected after handling rounds
|
||||
wire [11:0] align104; // alignment count + 104
|
||||
wire [11:0] align104; // alignment count + 104
|
||||
|
||||
// Increment fraction of Z by one if necessary for prerounded bypass
|
||||
// This incrementor delay is masked by the alignment count computation
|
||||
@ -56,7 +56,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
// addend on right shifts. Handle special cases of shifting
|
||||
// by too much.
|
||||
|
||||
always @(z2 or aligncnt or align104 or zzero or xzero or yzero or zdenorm)
|
||||
always @(z2 or aligncnt or align104 or zzero or xzero or yzero or zdenorm or proddenorm)
|
||||
begin
|
||||
|
||||
// Default to clearing sticky bits
|
||||
@ -66,7 +66,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
// And to using product as primary operand in adder I exponent gen
|
||||
killprod = 0;
|
||||
|
||||
if(zzero) begin
|
||||
if(zzero) begin // if z = 0
|
||||
t = 158'b0;
|
||||
if (xzero || yzero) killprod = 1;
|
||||
end else if ((aligncnt > 53 && ~aligncnt[11]) || xzero || yzero) begin
|
||||
@ -75,8 +75,8 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
t = {53'b0, ~zzero, z2, 52'b0};
|
||||
killprod = 1;
|
||||
ps = ~xzero && ~yzero;
|
||||
end else if ((ae[12] && align104[11])) begin //***fix the if statement
|
||||
// KEP if the multiplier's exponent overflows
|
||||
end else if ((ae[12] && align104[11]) && ~proddenorm) begin //***fix the if statement
|
||||
// KEP if the multiplier's exponent overflows
|
||||
t = {53'b0, ~zzero, z2, 52'b0};
|
||||
killprod = 1;
|
||||
ps = ~xzero && ~yzero;
|
||||
@ -85,7 +85,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
||||
t = 0;
|
||||
end else if (~aligncnt[11]) begin // Left shift by reasonable amount
|
||||
t = {53'b0, ~zzero, z2, 52'b0} << aligncnt;
|
||||
end else begin // Otherwise right shift
|
||||
end else begin // Otherwise right shift
|
||||
t = {53'b0, ~zzero, z2, 52'b0} >> -aligncnt;
|
||||
|
||||
// use some behavioral code to find sticky bit. This is really
|
||||
|
@ -30,85 +30,85 @@ module array(x, y, xdenorm, ydenorm, r, s, bypsel, bypplus1);
|
||||
|
||||
assign xnorm = xdenorm ? {x[50:0], 1'b0} : x; // normalization of denormalized numbers
|
||||
assign ynorm = ydenorm ? {y[50:0], 1'b0} : y;
|
||||
assign yExt = {2'b01,ynorm,1'b0}; // y extended and added assumed 1
|
||||
assign xExt = {2'b01,xnorm}; // x with added assumed 1
|
||||
//assign yExt = {2'b01,ynorm,1'b0}; // y extended and added assumed 1
|
||||
//assign xExt = {2'b01,xnorm}; // x with added assumed 1
|
||||
|
||||
|
||||
//booth encoding
|
||||
|
||||
generate
|
||||
for(i=0; i<27; i=i+1) begin
|
||||
booth booth(.xExt(xExt), .choose(yExt[(i*2)+2:i*2]), .add1(add1[i]), .e(e[i]), .pp(pp[i]));
|
||||
end
|
||||
endgenerate
|
||||
// generate
|
||||
// for(i=0; i<27; i=i+1) begin
|
||||
// booth booth(.xExt(xExt), .choose(yExt[(i*2)+2:i*2]), .add1(add1[i]), .e(e[i]), .pp(pp[i]));
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
assign acc[0] = {49'b0,~e[0],e[0],e[0],pp[0]};
|
||||
assign acc[1] = {50'b01,~e[1],pp[1],add1[0]};
|
||||
assign acc[2] = {48'b01,~e[2],pp[2],add1[1], 2'b0};
|
||||
assign acc[3] = {46'b01,~e[3],pp[3],add1[2], 4'b0};
|
||||
assign acc[4] = {44'b01,~e[4],pp[4],add1[3], 6'b0};
|
||||
assign acc[5] = {42'b01,~e[5],pp[5],add1[4], 8'b0};
|
||||
assign acc[6] = {40'b01,~e[6],pp[6],add1[5], 10'b0};
|
||||
assign acc[7] = {38'b01,~e[7],pp[7],add1[6], 12'b0};
|
||||
assign acc[8] = {36'b01,~e[8],pp[8],add1[7], 14'b0};
|
||||
assign acc[9] = {34'b01,~e[9],pp[9],add1[8], 16'b0};
|
||||
assign acc[10] = {32'b01,~e[10],pp[10],add1[9], 18'b0};
|
||||
assign acc[11] = {30'b01,~e[11],pp[11],add1[10], 20'b0};
|
||||
assign acc[12] = {28'b01,~e[12],pp[12],add1[11], 22'b0};
|
||||
assign acc[13] = {26'b01,~e[13],pp[13],add1[12], 24'b0};
|
||||
assign acc[14] = {24'b01,~e[14],pp[14],add1[13], 26'b0};
|
||||
assign acc[15] = {22'b01,~e[15],pp[15],add1[14], 28'b0};
|
||||
assign acc[16] = {20'b01,~e[16],pp[16],add1[15], 30'b0};
|
||||
assign acc[17] = {18'b01,~e[17],pp[17],add1[16], 32'b0};
|
||||
assign acc[18] = {16'b01,~e[18],pp[18],add1[17], 34'b0};
|
||||
assign acc[19] = {14'b01,~e[19],pp[19],add1[18], 36'b0};
|
||||
assign acc[20] = {12'b01,~e[20],pp[20],add1[19], 38'b0};
|
||||
assign acc[21] = {10'b01,~e[21],pp[21],add1[20], 40'b0};
|
||||
assign acc[22] = {8'b01,~e[22],pp[22],add1[21], 42'b0};
|
||||
assign acc[23] = {6'b01,~e[23],pp[23],add1[22], 44'b0};
|
||||
assign acc[24] = {4'b01,~e[24],pp[24],add1[23], 46'b0};
|
||||
assign acc[25] = {~e[25],pp[25],add1[24], 48'b0};
|
||||
assign acc[26] = {pp[26],add1[25], 50'b0};
|
||||
// assign acc[0] = {49'b0,~e[0],e[0],e[0],pp[0]};
|
||||
// assign acc[1] = {50'b01,~e[1],pp[1],add1[0]};
|
||||
// assign acc[2] = {48'b01,~e[2],pp[2],add1[1], 2'b0};
|
||||
// assign acc[3] = {46'b01,~e[3],pp[3],add1[2], 4'b0};
|
||||
// assign acc[4] = {44'b01,~e[4],pp[4],add1[3], 6'b0};
|
||||
// assign acc[5] = {42'b01,~e[5],pp[5],add1[4], 8'b0};
|
||||
// assign acc[6] = {40'b01,~e[6],pp[6],add1[5], 10'b0};
|
||||
// assign acc[7] = {38'b01,~e[7],pp[7],add1[6], 12'b0};
|
||||
// assign acc[8] = {36'b01,~e[8],pp[8],add1[7], 14'b0};
|
||||
// assign acc[9] = {34'b01,~e[9],pp[9],add1[8], 16'b0};
|
||||
// assign acc[10] = {32'b01,~e[10],pp[10],add1[9], 18'b0};
|
||||
// assign acc[11] = {30'b01,~e[11],pp[11],add1[10], 20'b0};
|
||||
// assign acc[12] = {28'b01,~e[12],pp[12],add1[11], 22'b0};
|
||||
// assign acc[13] = {26'b01,~e[13],pp[13],add1[12], 24'b0};
|
||||
// assign acc[14] = {24'b01,~e[14],pp[14],add1[13], 26'b0};
|
||||
// assign acc[15] = {22'b01,~e[15],pp[15],add1[14], 28'b0};
|
||||
// assign acc[16] = {20'b01,~e[16],pp[16],add1[15], 30'b0};
|
||||
// assign acc[17] = {18'b01,~e[17],pp[17],add1[16], 32'b0};
|
||||
// assign acc[18] = {16'b01,~e[18],pp[18],add1[17], 34'b0};
|
||||
// assign acc[19] = {14'b01,~e[19],pp[19],add1[18], 36'b0};
|
||||
// assign acc[20] = {12'b01,~e[20],pp[20],add1[19], 38'b0};
|
||||
// assign acc[21] = {10'b01,~e[21],pp[21],add1[20], 40'b0};
|
||||
// assign acc[22] = {8'b01,~e[22],pp[22],add1[21], 42'b0};
|
||||
// assign acc[23] = {6'b01,~e[23],pp[23],add1[22], 44'b0};
|
||||
// assign acc[24] = {4'b01,~e[24],pp[24],add1[23], 46'b0};
|
||||
// assign acc[25] = {~e[25],pp[25],add1[24], 48'b0};
|
||||
// assign acc[26] = {pp[26],add1[25], 50'b0};
|
||||
|
||||
//*** resize adders
|
||||
generate
|
||||
for(i=0; i<9; i=i+1) begin
|
||||
add3comp2 #(.BITS(106)) add1(.a(acc[i*3]), .b(acc[i*3+1]), .c(acc[i*3+2]),
|
||||
.carry(carryTmp[i][105:0]), .sum(lv1add[i*2+1]));
|
||||
assign lv1add[i*2] = {carryTmp[i][104:0], 1'b0};
|
||||
end
|
||||
endgenerate
|
||||
// //*** resize adders
|
||||
// generate
|
||||
// for(i=0; i<9; i=i+1) begin
|
||||
// add3comp2 #(.BITS(106)) add1(.a(acc[i*3]), .b(acc[i*3+1]), .c(acc[i*3+2]),
|
||||
// .carry(carryTmp[i][105:0]), .sum(lv1add[i*2+1]));
|
||||
// assign lv1add[i*2] = {carryTmp[i][104:0], 1'b0};
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
generate
|
||||
for(i=0; i<6; i=i+1) begin
|
||||
add3comp2 #(.BITS(106)) add2(.a(lv1add[i*3]), .b(lv1add[i*3+1]), .c(lv1add[i*3+2]),
|
||||
.carry(carryTmp[i+9][105:0]), .sum(lv2add[i*2+1]));
|
||||
assign lv2add[i*2] = {carryTmp[i+9][104:0], 1'b0};
|
||||
end
|
||||
endgenerate
|
||||
// generate
|
||||
// for(i=0; i<6; i=i+1) begin
|
||||
// add3comp2 #(.BITS(106)) add2(.a(lv1add[i*3]), .b(lv1add[i*3+1]), .c(lv1add[i*3+2]),
|
||||
// .carry(carryTmp[i+9][105:0]), .sum(lv2add[i*2+1]));
|
||||
// assign lv2add[i*2] = {carryTmp[i+9][104:0], 1'b0};
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
generate
|
||||
for(i=0; i<4; i=i+1) begin
|
||||
add3comp2 #(.BITS(106)) add3(.a(lv2add[i*3]), .b(lv2add[i*3+1]), .c(lv2add[i*3+2]),
|
||||
.carry(carryTmp[i+15][105:0]), .sum(lv3add[i*2+1]));
|
||||
assign lv3add[i*2] = {carryTmp[i+15][104:0], 1'b0};
|
||||
end
|
||||
endgenerate
|
||||
// generate
|
||||
// for(i=0; i<4; i=i+1) begin
|
||||
// add3comp2 #(.BITS(106)) add3(.a(lv2add[i*3]), .b(lv2add[i*3+1]), .c(lv2add[i*3+2]),
|
||||
// .carry(carryTmp[i+15][105:0]), .sum(lv3add[i*2+1]));
|
||||
// assign lv3add[i*2] = {carryTmp[i+15][104:0], 1'b0};
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
|
||||
generate
|
||||
for(i=0; i<2; i=i+1) begin
|
||||
add4comp2 #(.BITS(106)) add4(.a(lv3add[i*4]), .b(lv3add[i*4+1]), .c(lv3add[i*4+2]), .d(lv3add[i*4+3]),
|
||||
.carry(carryTmp[i+19]), .sum(lv4add[i*2+1]));
|
||||
assign lv4add[i*2] = {carryTmp[i+19][104:0], 1'b0};
|
||||
end
|
||||
endgenerate
|
||||
// generate
|
||||
// for(i=0; i<2; i=i+1) begin
|
||||
// add4comp2 #(.BITS(106)) add4(.a(lv3add[i*4]), .b(lv3add[i*4+1]), .c(lv3add[i*4+2]), .d(lv3add[i*4+3]),
|
||||
// .carry(carryTmp[i+19]), .sum(lv4add[i*2+1]));
|
||||
// assign lv4add[i*2] = {carryTmp[i+19][104:0], 1'b0};
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
add4comp2 #(.BITS(106)) add5(.a(lv4add[0]), .b(lv4add[1]), .c(lv4add[2]), .d(lv4add[3]) ,
|
||||
.carry(carryTmp[21]), .sum(s));
|
||||
assign r = {carryTmp[21][104:0], 1'b0};
|
||||
// add4comp2 #(.BITS(106)) add5(.a(lv4add[0]), .b(lv4add[1]), .c(lv4add[2]), .d(lv4add[3]) ,
|
||||
// .carry(carryTmp[21]), .sum(s));
|
||||
// assign r = {carryTmp[21][104:0], 1'b0};
|
||||
|
||||
// assign r = 106'b0;
|
||||
// assign s = ({54'b1,xnorm} + (bypsel && bypplus1)) * {54'b1,ynorm};
|
||||
assign r = 106'b0;
|
||||
assign s = ({54'b1,xnorm} + (bypsel && bypplus1)) * {54'b1,ynorm};
|
||||
|
||||
endmodule
|
||||
|
@ -19,7 +19,7 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
||||
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
||||
killprod, sumzero, postnormalize, normcnt, infinity,
|
||||
invalid, overflow, underflow, inf,
|
||||
nan, xnan, ynan, znan, zdenorm, specialsel,
|
||||
nan, xnan, ynan, znan, zdenorm, proddenorm, specialsel,
|
||||
aligncnt, w[62:52], wbypass[62:52],
|
||||
prodof, sumof, sumuf, denorm0, ae[12:0]);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@ -28,36 +28,37 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
||||
input [62:52] y; // Exponent of multiplicand y
|
||||
input [62:52] z; // Exponent of addend z
|
||||
input [62:52] earlyres; // Result from other FPU block
|
||||
input earlyressel; // Select result from other block
|
||||
input earlyressel; // Select result from other block
|
||||
input [1:1] bypsel; // Bypass X or Z
|
||||
input byppostnorm; // Postnormalize bypassed result
|
||||
input killprod; // Z >> product
|
||||
input sumzero; // sum exactly equals zero
|
||||
input postnormalize; // postnormalize rounded result
|
||||
input byppostnorm; // Postnormalize bypassed result
|
||||
input killprod; // Z >> product
|
||||
input sumzero; // sum exactly equals zero
|
||||
input postnormalize; // postnormalize rounded result
|
||||
input [8:0] normcnt; // normalization shift count
|
||||
input infinity; // generate infinity on overflow
|
||||
input invalid; // Result invalid
|
||||
input overflow; // Result overflowed
|
||||
input underflow; // Result underflowed
|
||||
input inf; // Some input is infinity
|
||||
input nan; // Some input is NaN
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input zdenorm; // Z is denorm
|
||||
input specialsel; // Select special result
|
||||
input infinity; // generate infinity on overflow
|
||||
input invalid; // Result invalid
|
||||
input overflow; // Result overflowed
|
||||
input underflow; // Result underflowed
|
||||
input inf; // Some input is infinity
|
||||
input nan; // Some input is NaN
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input zdenorm; // Z is denorm
|
||||
input proddenorm; // product is denorm
|
||||
input specialsel; // Select special result
|
||||
output [11:0] aligncnt; // shift count for alignment shifter
|
||||
output [62:52] w; // Exponent of result
|
||||
output [62:52] wbypass; // Prerounded exponent for bypass
|
||||
output prodof; // X*Y exponent out of bounds
|
||||
output sumof; // X*Y+Z exponent out of bounds
|
||||
output sumuf; // X*Y+Z exponent underflows
|
||||
output denorm0; // exponent = 0 for denorm
|
||||
output [62:52] w; // Exponent of result
|
||||
output [62:52] wbypass; // Prerounded exponent for bypass
|
||||
output prodof; // X*Y exponent out of bounds
|
||||
output sumof; // X*Y+Z exponent out of bounds
|
||||
output sumuf; // X*Y+Z exponent underflows
|
||||
output denorm0; // exponent = 0 for denorm
|
||||
output [12:0] ae; //exponent of multiply
|
||||
|
||||
// Internal nodes
|
||||
|
||||
wire [12:0] aetmp; // Exponent of Multiply
|
||||
|
||||
wire [12:0] aligncnt0; // Shift count for alignment
|
||||
wire [12:0] aligncnt1; // Shift count for alignment
|
||||
wire [12:0] be; // Exponent of multiply
|
||||
@ -72,9 +73,11 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
||||
// Note that the exponent does not have to be incremented on a postrounding
|
||||
// normalization of X because the mantissa was already increased. Report
|
||||
// if exponent is out of bounds
|
||||
assign ae = x + y - 1023;
|
||||
|
||||
assign prodof = (ae > 2046 && ~ae[12] && ~killprod);
|
||||
|
||||
assign ae = x + y - 1023;
|
||||
|
||||
assign prodof = (ae > 2046 && ~ae[12]);
|
||||
|
||||
// Compute alignment shift count
|
||||
// Adjust for postrounding normalization of Z.
|
||||
@ -82,8 +85,10 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
||||
// check if a round overflows is shorter than the actual round and
|
||||
// is masked by the bypass mux and two 10 bit adder delays.
|
||||
|
||||
assign aligncnt0 = z - ae[10:0] + 13'b0;
|
||||
assign aligncnt1 = z - ae[10:0] + 13'b1;
|
||||
assign aligncnt0 = z - ae + 13'b0;// KEP use all of ae
|
||||
assign aligncnt1 = z - ae + 13'b1;
|
||||
//assign aligncnt0 = z - ae[10:0] + 13'b0;//original
|
||||
//assign aligncnt1 = z - ae[10:0] + 13'b1;
|
||||
assign aligncnt = bypsel[1] && byppostnorm ? aligncnt1 : aligncnt0;
|
||||
|
||||
// Select exponent (usually from product except in case of huge addend)
|
||||
@ -118,13 +123,17 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
||||
// rounding mode. NaNs are propagated or generated.
|
||||
|
||||
assign specialres = earlyressel ? earlyres :
|
||||
invalid ? nanres :
|
||||
invalid | nan ? nanres : // KEP added nan
|
||||
overflow ? infinityres :
|
||||
inf ? 11'b11111111111 :
|
||||
underflow ? 11'b0 : 11'bx;
|
||||
|
||||
assign infinityres = infinity ? 11'b11111111111 : 11'b11111111110;
|
||||
|
||||
// IEEE 754-2008 section 6.2.3 states:
|
||||
// "If two or more inputs are NaN, then the payload of the resulting NaN should be
|
||||
// identical to the payload of one of the input NaNs if representable in the destination
|
||||
// format. This standard does not specify which of the input NaNs will provide the payload."
|
||||
assign nanres = xnan ? x : (ynan ? y : (znan? z : 11'b11111111111));
|
||||
|
||||
// A mux selects the early result from other FPU blocks or the
|
||||
|
@ -13,31 +13,31 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
||||
inf, nan, invalid, overflow, underflow, inexact);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input xinf; // X is Inf
|
||||
input yinf; // Y is Inf
|
||||
input zinf; // Z is Inf
|
||||
input prodof; // X*Y overflows exponent
|
||||
input sumof; // X*Y + z underflows exponent
|
||||
input sumuf; // X*Y + z underflows exponent
|
||||
input psign; // Sign of product
|
||||
input zsign; // Sign of z
|
||||
input xzero; // x = 0
|
||||
input yzero; // y = 0
|
||||
input [1:0] v; // R and S bits of result
|
||||
output inf; // Some source is Inf
|
||||
output nan; // Some source is NaN
|
||||
output invalid; // Result is invalid
|
||||
output overflow; // Result overflowed
|
||||
output underflow; // Result underflowed
|
||||
output inexact; // Result is not an exact number
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input xinf; // X is Inf
|
||||
input yinf; // Y is Inf
|
||||
input zinf; // Z is Inf
|
||||
input prodof; // X*Y overflows exponent
|
||||
input sumof; // X*Y + z underflows exponent
|
||||
input sumuf; // X*Y + z underflows exponent
|
||||
input psign; // Sign of product
|
||||
input zsign; // Sign of z
|
||||
input xzero; // x = 0
|
||||
input yzero; // y = 0
|
||||
input [1:0] v; // R and S bits of result
|
||||
output inf; // Some source is Inf
|
||||
output nan; // Some source is NaN
|
||||
output invalid; // Result is invalid
|
||||
output overflow; // Result overflowed
|
||||
output underflow; // Result underflowed
|
||||
output inexact; // Result is not an exact number
|
||||
|
||||
// Internal nodes
|
||||
|
||||
wire prodinf; // X*Y larger than max possible
|
||||
wire suminf; // X*Y+Z larger than max possible
|
||||
wire prodinf; // X*Y larger than max possible
|
||||
wire suminf; // X*Y+Z larger than max possible
|
||||
|
||||
// If any input is NaN, propagate the NaN
|
||||
|
||||
@ -46,12 +46,14 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
||||
// Same with infinity (inf - inf and O * inf don't propagate inf
|
||||
// but it's ok becaue illegal op takes higher precidence)
|
||||
|
||||
assign inf= xinf || yinf || zinf;
|
||||
assign inf= xinf || yinf || zinf || suminf;//KEP added suminf
|
||||
//assign inf= xinf || yinf || zinf;//original
|
||||
|
||||
// Generate infinity checks
|
||||
|
||||
assign prodinf = prodof && ~xnan && ~ynan;
|
||||
assign suminf = sumof && ~xnan && ~ynan && ~znan;
|
||||
//KEP added if the product is infinity then sum is infinity
|
||||
assign suminf = prodinf | sumof && ~xnan && ~ynan && ~znan;
|
||||
|
||||
// Set invalid flag for following cases:
|
||||
// 1) Inf - Inf
|
||||
@ -59,8 +61,7 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
||||
// 3) Output = NaN (this is not part of the IEEE spec, only 486 proj)
|
||||
|
||||
assign invalid = (xinf || yinf || prodinf) && zinf && (psign ^ zsign) ||
|
||||
xzero && yinf || yzero && xinf ||
|
||||
nan;
|
||||
xzero && yinf || yzero && xinf;// KEP remove case 3) above
|
||||
|
||||
// Set the overflow flag for the following cases:
|
||||
// 1) Rounded multiply result would be out of bounds
|
||||
|
@ -103,7 +103,7 @@ module fmac(xrf, y, zrf, rn, rz, rp, rm,
|
||||
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
||||
killprod, sumzero, postnorrnalize, normcnt,
|
||||
infinity, invalid, overflow, underflow,
|
||||
inf, nan, xnan, ynan, znan, zdenorm, specialsel,
|
||||
inf, nan, xnan, ynan, znan, zdenorm, proddenorm, specialsel,
|
||||
aligncnt, w[62:52], wbypass[62:52],
|
||||
prodof, sumof, sumuf, denorm0, ae);
|
||||
// Instantiate special case detection across datapath & exponent path
|
||||
@ -120,7 +120,7 @@ assign wbypass[63] = w[63];
|
||||
// Instantiate control logic
|
||||
|
||||
sign sign(x[63], y[63], z[63], negsum0, negsum1, bs, ps,
|
||||
killprod, rm, sumzero, nan, invalid, xinf, yinf, inf,
|
||||
killprod, rm, overflow, sumzero, nan, invalid, xinf, yinf, zinf, inf,
|
||||
w[63], invz, negsum, selsum1, psign);
|
||||
flag flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
||||
psign, z[63], xzero, yzero, v[1:0],
|
||||
|
@ -18,12 +18,12 @@ module normalize(sum[157:0], normcnt, sumzero, bs, ps, denorm0, zdenorm, v[53:0]
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
input [157:0] sum; // sum
|
||||
input [8:0] normcnt; // normalization shift count
|
||||
input sumzero; // sum is zero
|
||||
input bs; // sticky bit for addend
|
||||
input ps; // sticky bit for product
|
||||
input denorm0; // exponent = -1023
|
||||
input zdenorm; // Input Z is denormalized
|
||||
output [53:0] v; // normalized sum, R, S bits
|
||||
input sumzero; // sum is zero
|
||||
input bs; // sticky bit for addend
|
||||
input ps; // sticky bit for product
|
||||
input denorm0; // exponent = -1023
|
||||
input zdenorm; // Input Z is denormalized
|
||||
output [53:0] v; // normalized sum, R, S bits
|
||||
|
||||
// Internal nodes
|
||||
|
||||
|
@ -19,37 +19,37 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
||||
w[51:0], postnormalize, infinity, specialsel);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
input [53:0] v; // normalized sum, R, S bits
|
||||
input [51:0] earlyres; // result from other FPU blocks
|
||||
input earlyressel; // use result from other FPU blocks
|
||||
input rz; // Round toward zero
|
||||
input rn; // Round toward nearest
|
||||
input rp; // Round toward plus infinity
|
||||
input rm; // Round toward minus infinity
|
||||
input wsign; // Sign of result
|
||||
input invalid; // Trap on infinity, NaN, denorm
|
||||
input overflow; // Result overflowed
|
||||
input underflow; // Result underflowed
|
||||
input inf; // Some input is infinity
|
||||
input nan; // Some input is NaN
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input [51:0] x; // Input X
|
||||
input [51:0] y; // Input Y
|
||||
input [51:0] z; // Input Z
|
||||
output [51:0] w; // rounded result of FMAC
|
||||
output postnormalize; // Right shift 1 for post-rounding norm
|
||||
output infinity; // Generate infinity on overflow
|
||||
output specialsel; // Select special result
|
||||
input [53:0] v; // normalized sum, R, S bits
|
||||
input [51:0] earlyres; // result from other FPU blocks
|
||||
input earlyressel; // use result from other FPU blocks
|
||||
input rz; // Round toward zero
|
||||
input rn; // Round toward nearest
|
||||
input rp; // Round toward plus infinity
|
||||
input rm; // Round toward minus infinity
|
||||
input wsign; // Sign of result
|
||||
input invalid; // Trap on infinity, NaN, denorm
|
||||
input overflow; // Result overflowed
|
||||
input underflow; // Result underflowed
|
||||
input inf; // Some input is infinity
|
||||
input nan; // Some input is NaN
|
||||
input xnan; // X is NaN
|
||||
input ynan; // Y is NaN
|
||||
input znan; // Z is NaN
|
||||
input [51:0] x; // Input X
|
||||
input [51:0] y; // Input Y
|
||||
input [51:0] z; // Input Z
|
||||
output [51:0] w; // rounded result of FMAC
|
||||
output postnormalize; // Right shift 1 for post-rounding norm
|
||||
output infinity; // Generate infinity on overflow
|
||||
output specialsel; // Select special result
|
||||
|
||||
// Internal nodes
|
||||
|
||||
wire plus1; // Round by adding one
|
||||
wire [52:0] v1; // Result + 1 (for rounding)
|
||||
wire [51:0] specialres; // Result of exceptional case
|
||||
wire plus1; // Round by adding one
|
||||
wire [52:0] v1; // Result + 1 (for rounding)
|
||||
wire [51:0] specialres; // Result of exceptional case
|
||||
wire [51:0] infinityres; // Infinity or largest real number
|
||||
wire [51:0] nanres; // Propagated or generated NaN
|
||||
wire [51:0] nanres; // Propagated or generated NaN
|
||||
|
||||
// Compute if round should occur. This equation is derived from
|
||||
// the rounding tables.
|
||||
@ -77,7 +77,7 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
||||
assign specialsel = earlyressel || overflow || underflow || invalid ||
|
||||
nan || inf;
|
||||
assign specialres = earlyressel ? earlyres :
|
||||
invalid ? nanres :
|
||||
invalid | nan ? nanres : //KEP added nan
|
||||
overflow ? infinityres :
|
||||
inf ? 52'b0 :
|
||||
underflow ? 52'b0 : 52'bx; // default to undefined
|
||||
@ -93,6 +93,11 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
||||
// NaN inputs are already quiet, we don't have to force them quiet.
|
||||
|
||||
// assign nanres = xnan ? x: (ynan ? y : (znan ? z : {1'b1, 51'b0})); // original
|
||||
|
||||
// IEEE 754-2008 section 6.2.3 states:
|
||||
// "If two or more inputs are NaN, then the payload of the resulting NaN should be
|
||||
// identical to the payload of one of the input NaNs if representable in the destination
|
||||
// format. This standard does not specify which of the input NaNs will provide the payload."
|
||||
assign nanres = xnan ? {1'b1, x[50:0]}: (ynan ? {1'b1, y[50:0]} : (znan ? {1'b1, z[50:0]} : {1'b1, 51'b0}));// KEP 210112 add the 1 to make NaNs quiet
|
||||
|
||||
// Select result with 4:1 mux
|
||||
|
@ -10,8 +10,8 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
||||
sumzero, nan, invalid, xinf, yinf, inf, wsign, invz, negsum, selsum1, psign);
|
||||
module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm, overflow,
|
||||
sumzero, nan, invalid, xinf, yinf, zinf, inf, wsign, invz, negsum, selsum1, psign);
|
||||
////////////////////////////////////////////////////////////////////////////I
|
||||
|
||||
input xsign; // Sign of X
|
||||
@ -23,11 +23,13 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
||||
input ps; // sticky bit from product
|
||||
input killprod; // Product forced to zero
|
||||
input rm; // Round toward minus infinity
|
||||
input overflow; // Round toward minus infinity
|
||||
input sumzero; // Sum = O
|
||||
input nan; // Some input is NaN
|
||||
input invalid; // Result invalid
|
||||
input xinf; // X = Inf
|
||||
input yinf; // Y = Inf
|
||||
input zinf; // Y = Inf
|
||||
input inf; // Some input = Inf
|
||||
output wsign; // Sign of W
|
||||
output invz; // Invert addend into adder
|
||||
@ -47,13 +49,13 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
||||
assign psign = xsign ^ ysign;
|
||||
|
||||
// Invert addend if sign of Z is different from sign of product assign invz = zsign ^ psign;
|
||||
assign invz = zsign ^ psign;
|
||||
assign invz = (zsign ^ psign);
|
||||
// Select +l mode for adder and compute if result must be negated
|
||||
// This is done according to cases based on the sticky bit.
|
||||
|
||||
always @(invz or negsum0 or negsum1 or bs or ps)
|
||||
begin
|
||||
if (~invz) begin // both inputs have same sign
|
||||
if (~invz) begin // both inputs have same sign //KEP if overflow
|
||||
negsum = 0;
|
||||
selsum1 = 0;
|
||||
end else if (bs) begin // sticky bit set on addend
|
||||
@ -85,9 +87,8 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
||||
// sum/difference shall be -0. However, x+x = x-(-X) retains the same sign as x even when x is zero."
|
||||
|
||||
assign zerosign = (~invz && killprod) ? zsign : rm;
|
||||
assign infsign = psign; //KEP 210112 keep the correct sign when result is infinity
|
||||
// assign infsign = xinf ? (yinf ? psign : xsign) : yinf ? ysign : zsign;//original
|
||||
assign wsign =invalid? 0 : (inf ? infsign:
|
||||
(sumzero ? zerosign : psign ^ negsum));
|
||||
assign infsign = zinf ? zsign : psign; //KEP 210112 keep the correct sign when result is infinity
|
||||
//assign infsign = xinf ? (yinf ? psign : xsign) : yinf ? ysign : zsign;//original
|
||||
assign wsign = invalid ? 0 : (inf ? infsign :(sumzero ? zerosign : psign ^ negsum));
|
||||
|
||||
endmodule
|
||||
|
@ -14,23 +14,23 @@ module special(x[63:0], y[63:0], z[63:0], ae, xzero, yzero, zzero,
|
||||
xnan, ynan, znan, xdenorm, ydenorm, zdenorm, proddenorm, xinf, yinf, zinf);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
input [63:0] x; // Input x
|
||||
input [63:0] x; // Input x
|
||||
input [63:0] y; // Input Y
|
||||
input [63:0] z; // Input z
|
||||
input [12:0] ae; // exponent of product
|
||||
output xzero; // Input x = 0
|
||||
output yzero; // Input y = 0
|
||||
output zzero; // Input z = 0
|
||||
output xnan; // x is NaN
|
||||
output ynan; // y is NaN
|
||||
output znan; // z is NaN
|
||||
output xdenorm; // x is denormalized
|
||||
output ydenorm; // y is denormalized
|
||||
output zdenorm; // z is denormalized
|
||||
output proddenorm; // product is denormalized
|
||||
output xinf; // x is infinity
|
||||
output yinf; // y is infinity
|
||||
output zinf; // z is infinity
|
||||
input [12:0] ae; // exponent of product
|
||||
output xzero; // Input x = 0
|
||||
output yzero; // Input y = 0
|
||||
output zzero; // Input z = 0
|
||||
output xnan; // x is NaN
|
||||
output ynan; // y is NaN
|
||||
output znan; // z is NaN
|
||||
output xdenorm; // x is denormalized
|
||||
output ydenorm; // y is denormalized
|
||||
output zdenorm; // z is denormalized
|
||||
output proddenorm; // product is denormalized
|
||||
output xinf; // x is infinity
|
||||
output yinf; // y is infinity
|
||||
output zinf; // z is infinity
|
||||
|
||||
// In the actual circuit design, the gates looking at bits
|
||||
// 51:0 and at bits 62:52 should be shared among the various detectors.
|
||||
|
@ -1 +1,130 @@
|
||||
0020000803ffffff bfcb4181a9468e24 000fffffffffffff 7fe2f9c2bca0f33c 00092f9c2bca0f33 Wrong zdenorm 18
|
||||
0000000000000001 7fdffffeffffffbf 4000000000080004 4007ffffc007fff5 4000000000080005 Wrong xdenorm 85959
|
||||
0000000000000001 c3ded4d0b02cd6aa 000c158ac12ac439 83eed4d0b02cd6ae 80bed1cb4d7c8bf9 Wrong xdenorm zdenorm 91485
|
||||
c15000000010001f 434ffffffffffffe 47f55792228596a0 c7e550dbbaf4d2c2 47f557922285969f Wrong 97625
|
||||
0000000000000001 7fe0000000000001 4340000000000001 4340000000000002 4340000000000001 Wrong xdenorm 99467
|
||||
0000000000000001 bfdffffffffffffe 801fffffffffbfc0 8021ffffffffdfe0 801fffffffffbfc0 Wrong xdenorm 117273
|
||||
0000000000000001 ffe0000000000000 40d4000040000000 40d3ffc040000000 40d4000040000000 Wrong xdenorm 133851
|
||||
000fffffffffffff 3fcffc007fffffff 800fffffffffffff 800800ffe0000000 800c007fefffffff Wrong xdenorm zdenorm 147973
|
||||
000fffffffffffff 3feffffffffffffe 000ffffffffffffe 001ffffffffffffd 001ffffffffffffc Wrong xdenorm zdenorm 154727
|
||||
000ffffffffffffe 41dffffffffff900 0000000000000001 02000000000ffc7e 01fffffffffff8fc Wrong xdenorm zdenorm 230863
|
||||
0010000000000000 bf4fdffffff7fffe 800ffffffffffffe 801003fbfffffeff 801003fbfffffefe Wrong zdenorm 308227
|
||||
0010000000000000 be6fffffbffffff7 8000000000000000 8000000000000000 800000000fffffe0 Wrong w=-zero unflw 313753
|
||||
0010000000000001 bcafffffffffffff 801fffffffffffff 8000000000000000 8020000000000000 Wrong w=-zero unflw 392345
|
||||
0010000000000001 bfe0000000000001 800ffffffffffffe 8018000000000000 8017ffffffffffff Wrong zdenorm 397871
|
||||
802000003ffffbff c3cfffffffffffd7 0000000000000001 040000003ffffbeb 040000003ffffbea Wrong zdenorm 448219
|
||||
dc10000000001eff 0000000000000001 802d63f274ada691 9c20000000001f01 98f0000000001eff Wrong ydenorm 489971
|
||||
001ffffffffffffe 3fddfbffffffffff 000ffffffffffffe 001efdfffffffffe 001efdfffffffffd Wrong zdenorm 551371
|
||||
3ca0000000000000 0000000000000001 000e8d6ac606e59d 000e8d6ac606e59e 000e8d6ac606e59d Wrong ydenorm zdenorm 559353
|
||||
3ca0000000000000 434ffffffffffffe c019cab46f8c90a7 c011cab46f8c90a7 c011cab46f8c90a8 Wrong 586983
|
||||
3ca0000000000001 bfe000000fffdfff 3fee60af9e2e4b00 bfa9f5061d1b5008 3fee60af9e2e4aff Wrong 649611
|
||||
3ca0000000000001 7fe0000000000000 ffefffffffffffff 7ca8000000000000 ffeffffffffffffe Wrong 657593
|
||||
44f0000000000dff 000000007fbffffe 801ffffffffffffe 05000000ff800dfb 03bfefffff801bf0 Wrong ydenorm 680311
|
||||
3ca0000000000001 bfffffffffffffff 3ff0007ffffffc00 bfefff0000000802 3ff0007ffffffbff Wrong 680925
|
||||
3cafffffffffffff 3caffffffffffffe bcaffffffffffffe 397fffffffffffff bcaffffffffffffc Wrong 707327
|
||||
3cafffffffffffff c01ffffffffffffe c02cbe486a2b0809 c02cbe486a2b0809 c02cbe486a2b080a Wrong 758289
|
||||
000667c5d67e1d85 3fdfeffffdffffff 001fffffffffffff 002398247cab1886 002199247ccb1886 Wrong xdenorm 763201
|
||||
000007fffffffffe 3f6ffffffe01fffe 000ffffffffffffe 00100807ffff7fff 00100007ffffff7e Wrong xdenorm zdenorm 768727
|
||||
3caffffffffffffe 4060000001000006 4070001fffff7ffe 4070001fffff7ffe 4070001fffff7fff Wrong 771183
|
||||
3caffffffffffffe 3fdfffffffffffff 3fe0000000000000 3fe0000000000000 3fe0000000000001 Wrong 779165
|
||||
bfd7ffffffbfffff 4000000000000000 3fffffffffffffff 3ff40000001fffff 3ff4000000200000 Wrong 787147
|
||||
3caffffffffffffe c00ffffffffffffe c01000000020007f c01000000020007f c010000000200080 Wrong 824601
|
||||
3caffffffffffffe c00fffffffffff08 4010000000000001 4010000000000001 4010000000000000 Wrong 827671
|
||||
800000000000007e ffd26a0f710537a9 c01b3b74de550046 c018ee32f034592d c01b3b74de550022 Wrong xdenorm 861441
|
||||
47f9aa99d39dd7d8 0000000000000001 8000000000000000 0809aa99d39dd7db 04d9aa99d39dd7d8 Wrong ydenorm 908719
|
||||
bfef000004000000 c000000000000000 c34ff80000000006 42afffffffffebe0 c34ff80000000005 Wrong 1031519
|
||||
bfe0010000007fff 3ff00003ffffff7f 4340000000000000 4340000000000000 433fffffffffffff Wrong 1039501
|
||||
3fdffffffffffffe 000ffffffffffffe 8000000000000001 fcdfffffffffffff 0007fffffffffffe Wrong ydenorm zdenorm 1049939
|
||||
802000007fffffbf 400ffffffffffffe 8000000000000001 804100007fffffbe 804000007fffffbe Wrong zdenorm 1068973
|
||||
3fdffffffffffffe bfffffffffffffff 3fefffffffffffff 3caffffffffffffe 3cafffffffffffff Wrong 1099673
|
||||
c7fffffffb7fffff 37efffffffdffbff c34000003ffffffc c34000003ffffffc c34000003ffffffd Wrong 1104585
|
||||
3fe0000000000001 3ca0000000000000 bcaffffffffffffe bca7fffffffffffd bca7fffffffffffe Wrong 1193615
|
||||
bfe00000000effff 800fffffffffffff 8010000000000001 8000000000000000 8007fffffff88002 Wrong w=-zero ydenorm unflw 1223701
|
||||
3feffffffffffffe 3ff0000000000000 bfefffffffffffff bc9ffffffffffffc bca0000000000000 Wrong 1342817
|
||||
3feffffffffffffe 801fffffffffffff 800007fffffbfffe 802401fffffefffe 802003fffffdfffe Wrong zdenorm 1366149
|
||||
bfd0002000007fff 0000000000000001 0010000000000001 0000000000000000 0010000000000001 Wrong ydenorm unflw 1466845
|
||||
0003476357ebf517 7fe000004000003f 8000000000000000 3ff68ec70a130546 3fda3b1b284c141d Wrong xdenorm 1503685
|
||||
4000002003fffffe bc4fffffbffffffe bfbfffffffffe3ff bfbfffffffffe3ff bfbfffffffffe400 Wrong 1635081
|
||||
3ca00ffdffffffff 3fdffffffffffffe bfe0000000000001 bfe0000000000001 bfe0000000000000 Wrong 1687885
|
||||
801fffffbf000000 4012b6da70c3decc 0000000000000006 8041b6da4ac07317 8042b6da4ac07316 Wrong zdenorm 1753583
|
||||
b7ff7ffffffff000 7fe0000000000000 78b01fffefffffff 78b01f03efffffff 78b01f03f0000000 Wrong 1843841
|
||||
400fffffffffffff 8000000000000001 801fffffffffffff 8030000000000000 8020000000000001 Wrong ydenorm 1851209
|
||||
00003fefffffffff ffeffffffffffffe 8000000000000000 c0007fdffffffffd bfaff7ffffffff7e Wrong xdenorm 1881295
|
||||
800000000003fffe 578284b14dfcc6e4 8000000000000000 979284b14e060938 958284a80ba41fe6 Wrong xdenorm 1989973
|
||||
bfdeffffff000000 002ffffffffc3ffe 0000002003fffffe 8016ffeffcfc5dff 801effdffafc5e00 Wrong zdenorm 2018831
|
||||
401fffffffffffff 3fdffffffffffffe c340000000400002 433fffffff800000 c340000000400000 Wrong 2106633
|
||||
401fffffffffffff 4010000000000001 c050ffffffff0000 c041fffffffdffff c041fffffffe0000 Wrong 2117685
|
||||
4340000000000000 3fd0000000000000 3fd0000000000001 4320000000000000 4320000000000001 Wrong 2243555
|
||||
bcb58ba32df145e0 3fbe0000003fffff 3fe0000000000000 3fe0000000000000 3fdfffffffffffff Wrong 2365741
|
||||
bfed82e3c6c037db 3ff0000000000000 4340000000000000 4340000000000000 433fffffffffffff Wrong 2389687
|
||||
3fdfffffffff7000 bcaffffffffffffe 3fe0000000000001 3fe0000000000001 3fe0000000000000 Wrong 2417317
|
||||
8000000002000000 ff100001efffffff 8d261bb2da873976 3f200001f400007b 3d800001efffffff Wrong xdenorm 2422229
|
||||
bb0fb893e0decb72 c1cffff7ffbfffff c03ffc0000003fff c03ffc0000003fff c03ffc0000003ffe Wrong 2546871
|
||||
800000000e000000 3fffffffffffffff 034ffff80ffffffe 034ffff80ffffffc 034ffff80ffffffe Wrong xdenorm 2600903
|
||||
7fe0000000000001 4000000000000000 ffefffffffffffff 7ff0000000000000 7cb8000000000000 Wrong w=+inf 2602745
|
||||
7fe0000000000001 8000000000000001 c010000000000001 c014000000000002 c010000000000002 Wrong ydenorm 2619323
|
||||
7fe0000000000001 bcafffffffffffff 7fefffffdffffffc fe70000002800000 7fefffffdffffffb Wrong 2626077
|
||||
7fefffffffffffff 0000000000000001 37ffffff7ffffeff 4000000000000001 3ccfffffffffffff Wrong ydenorm 2653707
|
||||
3feffffffffbfffd 3ca0000000000001 bfe0000000000001 3fe0000000000000 bfe0000000000000 Wrong 2660461
|
||||
000ffffffff00006 bfe0000000000001 0000000000000001 7dfffff400000002 8007fffffff80002 Wrong xdenorm zdenorm 2770981
|
||||
fd61dd32fb8e3b2c 0000000000000001 801ffffffffffffe bd71dd32fb8e3b2e ba41dd32fb8e3b2c Wrong ydenorm 3003073
|
||||
000fff000000000f 3ff00800001fffff 8010000000000000 0000000000000000 000006ff801ffe0e Wrong xdenorm unflw 3117277
|
||||
8000000000000001 400effffff000000 0010000000000000 8000000000000000 000ffffffffffffc Wrong w=-zero xdenorm unflw 3143065
|
||||
8000000000000001 40211275ffe5ee3c 0000000000000001 802e24ebffcbdc7c 8000000000000008 Wrong xdenorm zdenorm 3148591
|
||||
8000000000000001 c1c01ffffffffefe 03100007fe000000 0310000900000000 03100007fe000000 Wrong xdenorm 3152889
|
||||
8000000000000001 3fe0000000000001 800fffffffffffff 8014000000000000 8010000000000000 Wrong xdenorm zdenorm 3155345
|
||||
8000000000000001 7fef848cc01517b4 c340000000000001 c340000000000002 c340000000000001 Wrong xdenorm 3170695
|
||||
8000000000000001 7feffffffffffffe 410ffffffc007ffe 410fffeffc007ffe 410ffffffc007ffe Wrong xdenorm 3173151
|
||||
8000000000000001 bffffffffffffffe 002e000000100000 0033000000080000 002e000000100001 Wrong xdenorm 3195255
|
||||
8000000000000001 ffe0000000000000 3feffffffffffffe 4000000000000000 3ff0000000000001 Wrong xdenorm 3205079
|
||||
8000000000000001 ffe0000000000001 c1ffbfffdffffffe c1ffbfffdfeffffe c1ffbfffdffffffe Wrong xdenorm 3206307
|
||||
800fffffffffffff 3ff0000000000000 001ffffffffffffe 0000000000000000 000fffffffffffff Wrong xdenorm unflw 3227183
|
||||
3e7ffffffefc0000 bfffffffffffffff 41c0ea1ad0c683e5 c1be2bca5e72f83a 41c0ea1ad0c683e3 Wrong 3264023
|
||||
3fffa9456a66b8c6 3caffffffffffffe c00ffffffffffffe c00ffffffffffffe c00ffffffffffffd Wrong 3290425
|
||||
800ffffffffffffe 3fe0000000000001 0010000400000010 0000000000000000 0008000400000011 Wrong xdenorm unflw 3294723
|
||||
800ffffffffffffe 3fd0000000007ffe 000fffffffffffff 0007ffffffffc001 000bffffffffe000 Wrong xdenorm zdenorm 3308845
|
||||
800ffffffffffffe c010000000000000 800dfede47fbc1e2 002880486e010f84 00290090dc021f0b Wrong xdenorm zdenorm 3338931
|
||||
bfdffc90d6e1fc1f 3ca1ffffffffeffe bfe66ad464a87aac bfe66ad464a87aac bfe66ad464a87aad Wrong 3367175
|
||||
8010000000000000 bfe0000000000000 000fffffffffffff 0018000000000000 0017ffffffffffff Wrong zdenorm 3398489
|
||||
7fe800000000003e 8004de935d68d1e8 801fffffffffffff c0034ddd0c1d3b0e bfed37743074ebbb Wrong ydenorm 3437785
|
||||
8010000000000001 bfefffffffffffff 801ffffffffffffe 8000000000000000 800ffffffffffffe Wrong w=-zero unflw 3470327
|
||||
801fffffffffffff bfdffffffffffffe 0000000000021fff 0018000000010ffe 0010000000021ffe Wrong zdenorm 3537867
|
||||
0005e0458a43fbdb 7fdfffbfffffffff 0000000000000000 3ffbc0539371cea5 3fe780e726e39d4b Wrong xdenorm 3691981
|
||||
bca0000000000001 3cafffffffffffff 3cafffffffffffff b970000000000000 3caffffffffffffe Wrong 3707945
|
||||
bca0000000000001 3fefffffffffffff bff0400000000400 bff0400000000400 bff0400000000401 Wrong 3714699
|
||||
bca0000000000001 c34ffffffffffffe c000000000000000 0000000000000000 b980000000000000 Wrong 3763205
|
||||
bcafffffffffffff 3fc200001fffffff 3fdffff00000ffff 3fdffff00000ffff 3fdffff00000fffe Wrong 3788379
|
||||
bcafffffffffffff 800ffffffffffffe 8000000000000000 0000000000000000 0000000000000001 Wrong ydenorm unflw 3807413
|
||||
bcaffffffffffffe 3fdffffffffffffe 3ff0000000000000 3ff0000000000000 3fefffffffffffff Wrong 3851621
|
||||
bcaffffffffffffe 001ffffffffc0000 8000000000000001 8000000000000005 8000000000000003 Wrong zdenorm 3878023
|
||||
7fec5fed92358a74 400000001bffffff ffefc0003ffffffe 7ff0000000000000 7fe8ffdb47bad466 Wrong w=+inf 3889689
|
||||
bfdfffffffffffff 000fffffffffffff 0000000000000000 8000000000000000 8007ffffffffffff Wrong w=-zero ydenorm unflw 4050557
|
||||
bfdfffffffffffff 8000000000000001 8010000000800400 8000000000000000 8010000000800400 Wrong w=-zero ydenorm unflw 4084941
|
||||
bfdfffffffffffff bff0000000000000 bfe0000000000001 bca7ffffffffffff bca8000000000000 Wrong 4100291
|
||||
bff400003ffffffe bfeffffffffffffe 434fffffffffffff 434fffffffffffff 4350000000000000 Wrong 4169059
|
||||
43f00002003ffffe 8000000000000001 0010000000000000 8400000200400000 80cffe04007ffffc Wrong ydenorm 4224319
|
||||
bfe0000000000000 801fffffffffffff 00000007fff80000 00180003fffc0000 00100007fff80000 Wrong zdenorm 4228617
|
||||
bfe0000000000000 c000000000000001 c00ffffffffffffe c007fffffffffffd c007fffffffffffe Wrong 4243967
|
||||
bfcfdffffeffffff 8000000000000001 000fffffffffe080 0011fdffffeff040 000fffffffffe080 Wrong ydenorm zdenorm 4573685
|
||||
bfffffffffffffff 0000000000000001 8010000000000001 8020000000000001 8010000000000003 Wrong ydenorm 4608683
|
||||
bfffffffffffffff 3cafffffffffffff 3ff00000040001ff bfeffffff7fffc06 3ff00000040001fd Wrong 4615437
|
||||
d2b6d8b0e4fde949 0000000000000001 0011fffffffffeff 92c6d8b0e4fde94c 8f96d8b0e4fde949 Wrong ydenorm 4678679
|
||||
3fd07dfffffffffe 8010000000000001 0000000000000001 7fef040000000006 80041f7fffffffff Wrong zdenorm 4716133
|
||||
bffffffffffffffe bfffffffffffffff c00ffffffffffffe bcbffffffffffffc bcbffffffffffffe Wrong 4730255
|
||||
c000000000000001 00000000004fffff 801ffffffffffffe 80280000004fffff 80200000004ffffe Wrong ydenorm 4839547
|
||||
c00982d68cfe066b 000ffffffffffffe 8000000000000001 802d82d68cfe0668 802982d68cfe0668 Wrong ydenorm zdenorm 4959277
|
||||
346ffffffffffeef 480ffffeffffffe0 3fdfffffffffffff 3fdfffffffffffff 3fe0000000000000 Wrong 4962961
|
||||
c01fffffffffffff 0007ffffffff0000 8000000000000000 803ffffffffdffff 802ffffffffbffff Wrong ydenorm 5176633
|
||||
c01fffffffffffff bfc08000000fffff 434ffffffffffffe 434ffffffffffffe 434fffffffffffff Wrong 5193211
|
||||
c3a000000fffff7f 80000000000005fe 001000003ffffbff 03b0000010000b7b 0127f80817f81f3f Wrong ydenorm 5450477
|
||||
0012000000000001 4000000000000001 000909a97b1f06a1 0028426a5ec7c1aa 002684d4bd8f8353 Wrong zdenorm 5535209
|
||||
ffe0000000000000 8000000000000001 c03000000000003f c02e00000000007e c03000000000003f Wrong ydenorm 5621169
|
||||
ffe0000000000001 3ca0c6fe6997e5e2 7fefffffffffffff fca8637f34cbf2f2 7feffffffffffffe Wrong 5673973
|
||||
ffe0000000000001 800fffffffffffff c340000000000001 4340000000000000 c340000000000000 Wrong ydenorm 5691779
|
||||
43f4595959dece4b 8000000000000001 801fffffffffffff 8404595959dece4e 80d45b5959dece4b Wrong ydenorm 5760547
|
||||
ffefffffffffffff 3ca14e19e3a06f13 7fe00000000ff7fe ffdfffffffe01006 7fe00000000ff7fd Wrong 5783265
|
||||
ffeffffffffffffe 8000000000000001 000fffffffffffff 4000000000000001 3ccffffffffffffe Wrong ydenorm zdenorm 5829929
|
||||
ffeffffffffffffe 800001fffbffffff bac0000ffeffffff 400003fff7fffffd 3f5fffbfffffeffe Wrong ydenorm 5832999
|
||||
bca0000004000080 bff0000000000009 bff0000000000001 3fefffffffffffff bff0000000000000 Wrong 5841595
|
||||
3fffffffff9ffffe 800000000f7ffffe 800ffdffbffffffe 801ffefffecffffa 800ffdffdefffffa Wrong ydenorm zdenorm 5887031
|
||||
41ccc32b421f1ac0 8000000000000001 802ffffc0000001e 81dcc32b461f1a44 802ffffc1cc32b60 Wrong ydenorm 5899925
|
||||
41ffffffffffff87 8000000000000001 0000000000000000 820fffffffffff8b 8000000200000000 Wrong ydenorm 6039335
|
||||
|
Binary file not shown.
@ -14,24 +14,31 @@ void main() {
|
||||
fp = fopen("testFloat","r");
|
||||
fq = fopen("tb.v","a");
|
||||
system("cp tbhead.v tb.v");
|
||||
int k=0;
|
||||
for(k=0; k<91 && !feof(fp); k++) {
|
||||
long k=0L;
|
||||
for(; !feof(fp); k++) {
|
||||
//3FDBFFFFFFFFFF7F DE608000000001FF 43CFED83C17EDBD0 DE4CE000000002F9 01
|
||||
// b68ffff8000000ff_3f9080000007ffff_b6307ffbe0080080_00001
|
||||
char ch;
|
||||
int i,j;
|
||||
char *ln;
|
||||
char ch;
|
||||
int i,j,n;
|
||||
char xrf[17];
|
||||
char y[17];
|
||||
char zrf[17];
|
||||
char ans[81];
|
||||
char flags[3];
|
||||
int rn,rz,rm,rp;
|
||||
{
|
||||
//my_string = (char *) malloc (nbytes + 1);
|
||||
//bytes_read = getline (&my_string, &nbytes, stdin);
|
||||
if(getline(&ln,&nbytes,fp) < 0) break;
|
||||
//fprintf(stderr,"%s\n", ln);
|
||||
long stop = 6039335;
|
||||
int debug = 0;
|
||||
//my_string = (char *) malloc (nbytes + 1);
|
||||
//bytes_read = getline (&my_string, &nbytes, stdin);
|
||||
|
||||
for(n=0; n < 613; n++) {//613 for 10000
|
||||
if(getline(&ln,&nbytes,fp) < 0 || feof(fp)) break;
|
||||
if(k == stop && debug == 1) break;
|
||||
k++;
|
||||
}
|
||||
//fprintf(stderr,"%s\n", ln);
|
||||
|
||||
if(!feof(fp)) {
|
||||
|
||||
strncpy(xrf, ln, 16); xrf[16]=0;
|
||||
strncpy(y, &ln[17], 16); y[16]=0;
|
||||
@ -46,71 +53,80 @@ void main() {
|
||||
fprintf(fq," zrf = 64'h%s;\n",zrf);
|
||||
fprintf(fq," ans = 64'h%s;\n", ans);
|
||||
// fprintf(fq," flags = 5'h%s;\n", flags);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//rn=1; rz=0; rm=0; rp=0;
|
||||
fprintf(fq," rn = %d;\n",1);
|
||||
fprintf(fq," rz = %d;\n", 0);
|
||||
fprintf(fq," rm = %d;\n", 0);
|
||||
fprintf(fq," rp = %d;\n", 0);
|
||||
}
|
||||
{
|
||||
fprintf(fq," earlyres = 64'b0;\n");
|
||||
fprintf(fq," earlyressel = 0;\n");
|
||||
}
|
||||
{
|
||||
{
|
||||
//rn=1; rz=0; rm=0; rp=0;
|
||||
fprintf(fq," rn = %d;\n",1);
|
||||
fprintf(fq," rz = %d;\n", 0);
|
||||
fprintf(fq," rm = %d;\n", 0);
|
||||
fprintf(fq," rp = %d;\n", 0);
|
||||
}
|
||||
{
|
||||
fprintf(fq," earlyres = 64'b0;\n");
|
||||
fprintf(fq," earlyressel = 0;\n");
|
||||
}
|
||||
{
|
||||
|
||||
fprintf(fq," bypsel= 2'b0;\n"); //, bysel);
|
||||
fprintf(fq," bypplus1 = 0;\n"); //, byp1);
|
||||
fprintf(fq," byppostnorm = 0;\n"); //, bypnorm);
|
||||
}
|
||||
fprintf(fq,"#10\n");
|
||||
// IEEE 754-2008 section 6.3 states "When ether an input or result is NaN, this standard does not interpret the sign of a NaN."
|
||||
//fprintf(fq," $fwrite(fp, \"%%h %%h %%h %%h \",xrf,y,w, ans);\n");
|
||||
fprintf(fq," // IEEE 754-2008 section 6.3 states: \"When ether an input or result is NaN, this\n");
|
||||
fprintf(fq," // standard does not interpret the sign of a NaN.\"\n");
|
||||
fprintf(fq," nan = (w > 64'h7FF0000000000000 && w < 64'h7FF8000000000000) ||\n");
|
||||
fprintf(fq," (w > 64'hFFF8000000000000 && w < 64'hFFF8000000000000 ) ||\n");
|
||||
fprintf(fq," (w >= 64'h7FF8000000000000 && w <= 64'h7FFfffffffffffff ) ||\n");
|
||||
fprintf(fq," (w >= 64'hFFF8000000000000 && w <= 64'hFFFfffffffffffff );\n");
|
||||
// fprintf(fq," if(!(~(|xrf[62:52]) && |xrf[51:0] || ~(|y[62:52]) && |y[51:0])) begin\n");
|
||||
// not looknig at negative zero results right now
|
||||
//fprintf(fq," if( (nan && (w[62:0] != ans[62:0])) || (!nan && (w != ans)) && !(w == 64'h8000000000000000 && ans == 64'b0)) begin\n");
|
||||
fprintf(fq," if( (nan && (w[62:0] != ans[62:0])) || (!nan && (w != ans)) ) begin\n");
|
||||
fprintf(fq," $fwrite(fp, \"%%h %%h %%h %%h %%h Wrong \",xrf,y, zrf, w, ans);\n");
|
||||
fprintf(fq," if(w == 64'h8000000000000000) $fwrite(fp, \"w=-zero \");\n");
|
||||
fprintf(fq," if(~(|xrf[62:52]) && |xrf[51:0]) $fwrite(fp, \"xdenorm \");\n");
|
||||
fprintf(fq," if(~(|y[62:52]) && |y[51:0]) $fwrite(fp, \"ydenorm \");\n");
|
||||
fprintf(fq," if(~(|zrf[62:52]) && |zrf[51:0]) $fwrite(fp, \"zdenorm \");\n");
|
||||
fprintf(fq," if(invalid != 0) $fwrite(fp, \"invld \");\n");
|
||||
fprintf(fq," if(overflow != 0) $fwrite(fp, \"ovrflw \");\n");
|
||||
fprintf(fq," if(underflow != 0) $fwrite(fp, \"unflw \");\n");
|
||||
fprintf(fq," if(w == 64'hFFF0000000000000) $fwrite(fp, \"w=-inf \");\n");
|
||||
fprintf(fq," if(w == 64'h7FF0000000000000) $fwrite(fp, \"w=+inf \");\n");
|
||||
fprintf(fq," if(w > 64'h7FF0000000000000 && w < 64'h7FF8000000000000 ) $fwrite(fp, \"w=sigNaN \");\n");
|
||||
fprintf(fq," if(w > 64'hFFF8000000000000 && w < 64'hFFF8000000000000 ) $fwrite(fp, \"w=sigNaN \");\n");
|
||||
fprintf(fq," if(w >= 64'h7FF8000000000000 && w <= 64'h7FFfffffffffffff ) $fwrite(fp, \"w=qutNaN \");\n");
|
||||
fprintf(fq," if(w >= 64'hFFF8000000000000 && w <= 64'hFFFfffffffffffff ) $fwrite(fp, \"w=qutNaN \");\n");
|
||||
fprintf(fq," bypsel= 2'b0;\n"); //, bysel);
|
||||
fprintf(fq," bypplus1 = 0;\n"); //, byp1);
|
||||
fprintf(fq," byppostnorm = 0;\n"); //, bypnorm);
|
||||
}
|
||||
fprintf(fq,"#10\n");
|
||||
// IEEE 754-2008 section 6.3 states "When ether an input or result is NaN, this standard does not interpret the sign of a NaN."
|
||||
//fprintf(fq," $fwrite(fp, \"%%h %%h %%h %%h \",xrf,y,w, ans);\n");
|
||||
fprintf(fq," // IEEE 754-2008 section 6.3 states: \"When ether an input or result is NaN, this\n");
|
||||
fprintf(fq," // standard does not interpret the sign of a NaN.\"\n");
|
||||
fprintf(fq," wnan = &w[62:52] && |w[51:0]; \n");
|
||||
fprintf(fq," xnan = &xrf[62:52] && |xrf[51:0]; \n");
|
||||
fprintf(fq," ynan = &y[62:52] && |y[51:0]; \n");
|
||||
fprintf(fq," znan = &zrf[62:52] && |zrf[51:0]; \n");
|
||||
fprintf(fq," ansnan = &ans[62:52] && |ans[51:0]; \n");
|
||||
fprintf(fq," xnorm = ~(|xrf[62:52]) && |xrf[51:0] ? {xrf[50:0], 1'b0} : xrf; \n");
|
||||
fprintf(fq," ynorm = ~(|y[62:52]) && |y[51:0] ? {y[50:0], 1'b0} : y;\n");
|
||||
fprintf(fq," s = ({54'b1,xnorm} + (bypsel && bypplus1)) * {54'b1,ynorm}; \n");
|
||||
// fprintf(fq," if(!(~(|xrf[62:52]) && |xrf[51:0] || ~(|y[62:52]) && |y[51:0])) begin\n");
|
||||
// not looknig at negative zero results right now
|
||||
//fprintf(fq," if( (nan && (w[62:0] != ans[62:0])) || (!nan && (w != ans)) && !(w == 64'h8000000000000000 && ans == 64'b0)) begin\n");
|
||||
// fprintf(fq," if( (nan && (w[62:0] != ans[62:0])) || (!nan && (w != ans)) ) begin\n");
|
||||
fprintf(fq," if((!wnan && (w != ans)) || (wnan && ansnan && ~(((xnan && (w[62:0] == {xrf[62:52],1'b1,xrf[50:0]})) || (ynan && (w[62:0] == {y[62:52],1'b1,y[50:0]})) || (znan && (w[62:0] == {zrf[62:52],1'b1,zrf[50:0]})) || (w[62:0] == ans[62:0])) ))) begin\n");
|
||||
fprintf(fq," $fwrite(fp, \"%%h %%h %%h %%h %%h Wrong \",xrf,y, zrf, w, ans);\n");
|
||||
//fprintf(fq," $fwrite(fp, \"%%h \",s);\n");
|
||||
fprintf(fq," if(w == 64'h8000000000000000) $fwrite(fp, \"w=-zero \");\n");
|
||||
fprintf(fq," if(~(|xrf[62:52]) && |xrf[51:0]) $fwrite(fp, \"xdenorm \");\n");
|
||||
fprintf(fq," if(~(|y[62:52]) && |y[51:0]) $fwrite(fp, \"ydenorm \");\n");
|
||||
fprintf(fq," if(~(|zrf[62:52]) && |zrf[51:0]) $fwrite(fp, \"zdenorm \");\n");
|
||||
fprintf(fq," if(invalid != 0) $fwrite(fp, \"invld \");\n");
|
||||
fprintf(fq," if(overflow != 0) $fwrite(fp, \"ovrflw \");\n");
|
||||
fprintf(fq," if(underflow != 0) $fwrite(fp, \"unflw \");\n");
|
||||
fprintf(fq," if(w == 64'hFFF0000000000000) $fwrite(fp, \"w=-inf \");\n");
|
||||
fprintf(fq," if(w == 64'h7FF0000000000000) $fwrite(fp, \"w=+inf \");\n");
|
||||
fprintf(fq," if(w > 64'h7FF0000000000000 && w < 64'h7FF8000000000000 ) $fwrite(fp, \"w=sigNaN \");\n");
|
||||
fprintf(fq," if(w > 64'hFFF8000000000000 && w < 64'hFFF8000000000000 ) $fwrite(fp, \"w=sigNaN \");\n");
|
||||
fprintf(fq," if(w >= 64'h7FF8000000000000 && w <= 64'h7FFfffffffffffff ) $fwrite(fp, \"w=qutNaN \");\n");
|
||||
fprintf(fq," if(w >= 64'hFFF8000000000000 && w <= 64'hFFFfffffffffffff ) $fwrite(fp, \"w=qutNaN \");\n");
|
||||
|
||||
fprintf(fq," if(ans == 64'hFFF0000000000000) $fwrite(fp, \"ans=-inf \");\n");
|
||||
fprintf(fq," if(ans == 64'h7FF0000000000000) $fwrite(fp, \"ans=+inf \");\n");
|
||||
fprintf(fq," if(ans > 64'h7FF0000000000000 && ans < 64'h7FF8000000000000 ) $fwrite(fp, \"ans=sigNaN \");\n");
|
||||
fprintf(fq," if(ans > 64'hFFF8000000000000 && ans < 64'hFFF8000000000000 ) $fwrite(fp, \"ans=sigNaN \");\n");
|
||||
fprintf(fq," if(ans >= 64'h7FF8000000000000 && ans <= 64'h7FFfffffffffffff ) $fwrite(fp, \"ans=qutNaN \");\n");
|
||||
fprintf(fq," if(ans >= 64'hFFF8000000000000 && ans <= 64'hFFFfffffffffffff ) $fwrite(fp, \"ans=qutNaN \");\n");
|
||||
fprintf(fq," $fwrite(fp,\"%d\\n\");\n",cnt);
|
||||
if(cnt == 358)fprintf(fq," $stop;\n");
|
||||
// fprintf(fq," end\n");
|
||||
fprintf(fq," end\n");
|
||||
cnt++;
|
||||
fprintf(fq," if(ans == 64'hFFF0000000000000) $fwrite(fp, \"ans=-inf \");\n");
|
||||
fprintf(fq," if(ans == 64'h7FF0000000000000) $fwrite(fp, \"ans=+inf \");\n");
|
||||
fprintf(fq," if(ans > 64'h7FF0000000000000 && ans < 64'h7FF8000000000000 ) $fwrite(fp, \"ans=sigNaN \");\n");
|
||||
fprintf(fq," if(ans > 64'hFFF8000000000000 && ans < 64'hFFF8000000000000 ) $fwrite(fp, \"ans=sigNaN \");\n");
|
||||
fprintf(fq," if(ans >= 64'h7FF8000000000000 && ans <= 64'h7FFfffffffffffff ) $fwrite(fp, \"ans=qutNaN \");\n");
|
||||
fprintf(fq," if(ans >= 64'hFFF8000000000000 && ans <= 64'hFFFfffffffffffff ) $fwrite(fp, \"ans=qutNaN \");\n");
|
||||
fprintf(fq," $fwrite(fp,\"%ld\\n\");\n",k);
|
||||
//fprintf(fq," $stop;\n");
|
||||
// fprintf(fq," end\n");
|
||||
fprintf(fq," end\n");
|
||||
cnt++;
|
||||
|
||||
//if(cnt > 100) break;
|
||||
fflush(fq);
|
||||
}
|
||||
//if(cnt > 100) break;
|
||||
fflush(fq);
|
||||
} // if(!feof(fp))
|
||||
if(k == stop && debug == 1) break;
|
||||
} // for(k)
|
||||
|
||||
fprintf(fq, "\t$stop;\n\tend\nendmodule");
|
||||
fclose(fq);
|
||||
fclose(fp);
|
||||
fprintf(stdout,"cnt = %d\n",cnt);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,14 @@ module tb;
|
||||
wire inexact;
|
||||
|
||||
integer fp;
|
||||
reg nan;
|
||||
reg wnan;
|
||||
reg xnan;
|
||||
reg ynan;
|
||||
reg znan;
|
||||
reg ansnan;
|
||||
reg [105:0] s; // partial product 2
|
||||
reg [51:0] xnorm;
|
||||
reg [51:0] ynorm;
|
||||
|
||||
localparam period = 20;
|
||||
fmac UUT(.xrf(xrf), .y(y), .zrf(zrf), .rn(rn), .rz(rz), .rp(rp), .rm(rm),
|
||||
@ -33,4 +40,4 @@ fmac UUT(.xrf(xrf), .y(y), .zrf(zrf), .rn(rn), .rz(rz), .rp(rp), .rm(rm),
|
||||
|
||||
initial
|
||||
begin
|
||||
fp = $fopen("/home/kparry/code/FMAC/tbgen/results.dat","w");
|
||||
fp = $fopen("/home/kparry/riscv-wally/wally-pipelined/src/fpu/FMA/tbgen/results.dat","w");
|
||||
|
@ -27,12 +27,12 @@
|
||||
|
||||
module hazard(
|
||||
// Detect hazards
|
||||
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
|
||||
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
|
||||
input logic LoadStallD, MulDivStallD, CSRRdStallD,
|
||||
input logic InstrStall, DataStall, ICacheStallF,
|
||||
// Stall & flush outputs
|
||||
output logic StallF, StallD, StallE, StallM, StallW,
|
||||
output logic FlushD, FlushE, FlushM, FlushW
|
||||
output logic FlushF, FlushD, FlushE, FlushM, FlushW
|
||||
);
|
||||
|
||||
logic BranchFlushDE;
|
||||
@ -51,7 +51,7 @@ module hazard(
|
||||
// A stage must stall if the next stage is stalled
|
||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||
|
||||
assign BranchFlushDE = PCSrcE | RetM | TrapM;
|
||||
assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
|
||||
|
||||
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
|
||||
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
|
||||
@ -62,6 +62,7 @@ module hazard(
|
||||
|
||||
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
|
||||
assign StallF = StallD | StallFCause;
|
||||
|
||||
assign StallD = StallE | StallDCause;
|
||||
assign StallE = StallM | StallECause;
|
||||
assign StallM = StallW | StallMCause;
|
||||
@ -73,6 +74,7 @@ module hazard(
|
||||
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
|
||||
assign FlushF = BPPredWrongE;
|
||||
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
|
||||
assign FlushE = FirstUnstalledE || BranchFlushDE; //LoadStallD | PCSrcE | RetM | TrapM;
|
||||
assign FlushM = FirstUnstalledM || RetM || TrapM;
|
||||
|
@ -43,6 +43,7 @@ module controller(
|
||||
output logic MemReadE, CSRReadE, // for Hazard Unit
|
||||
output logic [2:0] Funct3E,
|
||||
output logic MulDivE, W64E,
|
||||
output logic JumpE,
|
||||
// Memory stage control signals
|
||||
input logic StallM, FlushM,
|
||||
output logic [1:0] MemRWM,
|
||||
@ -68,7 +69,7 @@ module controller(
|
||||
logic RegWriteD, RegWriteE;
|
||||
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
|
||||
logic [1:0] MemRWD, MemRWE;
|
||||
logic JumpD, JumpE;
|
||||
logic JumpD;
|
||||
logic BranchD, BranchE;
|
||||
logic [1:0] ALUOpD;
|
||||
logic [4:0] ALUControlD;
|
||||
@ -115,7 +116,7 @@ module controller(
|
||||
if (InstrD[31:27] == 5'b00010)
|
||||
ControlsD = 22'b1_000_00_10_001_0_00_0_0_0_0_0_0_1_0; // lr
|
||||
else if (InstrD[31:27] == 5'b00011)
|
||||
ControlsD = 22'b1_101_01_01_110_0_00_0_0_0_0_0_0_1_0; // sc
|
||||
ControlsD = 22'b1_101_01_01_101_0_00_0_0_0_0_0_0_1_0; // sc
|
||||
else
|
||||
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_1_0; // other atomic; decode later
|
||||
end else
|
||||
|
@ -36,7 +36,9 @@ module datapath (
|
||||
input logic [4:0] ALUControlE,
|
||||
input logic ALUSrcAE, ALUSrcBE,
|
||||
input logic TargetSrcE,
|
||||
input logic JumpE,
|
||||
input logic [`XLEN-1:0] PCE,
|
||||
input logic [`XLEN-1:0] PCLinkE,
|
||||
output logic [2:0] FlagsE,
|
||||
output logic [`XLEN-1:0] PCTargetE,
|
||||
output logic [`XLEN-1:0] SrcAE, SrcBE,
|
||||
@ -64,7 +66,9 @@ module datapath (
|
||||
// Execute stage signals
|
||||
logic [`XLEN-1:0] RD1E, RD2E;
|
||||
logic [`XLEN-1:0] ExtImmE;
|
||||
logic [`XLEN-1:0] PreSrcAE;
|
||||
|
||||
logic [`XLEN-1:0] PreSrcAE, SrcAE2, SrcBE2;
|
||||
|
||||
logic [`XLEN-1:0] ALUResultE;
|
||||
logic [`XLEN-1:0] WriteDataE;
|
||||
logic [`XLEN-1:0] TargetBaseE;
|
||||
@ -93,8 +97,10 @@ module datapath (
|
||||
mux3 #(`XLEN) faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE);
|
||||
mux3 #(`XLEN) fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE);
|
||||
mux2 #(`XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
|
||||
mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);
|
||||
mux2 #(`XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);
|
||||
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUResultE, FlagsE);
|
||||
mux2 #(`XLEN) srcbmux2(SrcBE, {`XLEN{1'b0}}, JumpE, SrcBE2); // *** May be able to remove this mux.
|
||||
alu #(`XLEN) alu(SrcAE2, SrcBE2, ALUControlE, ALUResultE, FlagsE);
|
||||
mux2 #(`XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
|
||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
||||
|
||||
@ -109,6 +115,9 @@ module datapath (
|
||||
flopenrc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ~StallW, ALUResultM, ALUResultW);
|
||||
flopenrc #(5) RdWEg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
||||
|
||||
// *** something is not right here. Before the merge I found an issue with the jal instruction not writing
|
||||
// the link address through the alu.
|
||||
// not sure what changed.
|
||||
// handle Store Conditional result if atomic extension supported
|
||||
generate
|
||||
if (`A_SUPPORTED)
|
||||
@ -118,4 +127,11 @@ module datapath (
|
||||
endgenerate
|
||||
|
||||
mux6 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
// This mux4:1 no longer needs to include PCLinkW. This is set correctly in the execution stage.
|
||||
// *** need to look at how the decoder is coded to fix.
|
||||
mux4 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, ResultSrcW, ResultW);
|
||||
>>>>>>> bp
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
endmodule
|
||||
|
@ -33,6 +33,7 @@ module ieu (
|
||||
output logic IllegalBaseInstrFaultD,
|
||||
// Execute Stage interface
|
||||
input logic [`XLEN-1:0] PCE,
|
||||
input logic [`XLEN-1:0] PCLinkE,
|
||||
output logic [`XLEN-1:0] PCTargetE,
|
||||
output logic MulDivE, W64E,
|
||||
output logic [2:0] Funct3E,
|
||||
@ -72,6 +73,7 @@ module ieu (
|
||||
logic [1:0] ForwardAE, ForwardBE;
|
||||
logic RegWriteM, RegWriteW;
|
||||
logic MemReadE, CSRReadE;
|
||||
logic JumpE;
|
||||
|
||||
controller c(.*);
|
||||
datapath dp(.*);
|
||||
|
97
wally-pipelined/src/ifu/BTBPredictor.sv
Normal file
97
wally-pipelined/src/ifu/BTBPredictor.sv
Normal file
@ -0,0 +1,97 @@
|
||||
///////////////////////////////////////////
|
||||
// SRAM2P1R1W
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 15, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: BTB model. Outputs type of instruction (currently 1 hot encoded. Probably want
|
||||
// to encode to reduce storage), valid, target PC.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module BTBPredictor
|
||||
#(parameter int Depth = 10
|
||||
)
|
||||
(input logic clk,
|
||||
input logic reset,
|
||||
input logic [`XLEN-1:0] LookUpPC,
|
||||
output logic [`XLEN-1:0] TargetPC,
|
||||
output logic [3:0] InstrClass,
|
||||
output logic Valid,
|
||||
// update
|
||||
input logic UpdateEN,
|
||||
input logic [`XLEN-1:0] UpdatePC,
|
||||
input logic [`XLEN-1:0] UpdateTarget,
|
||||
input logic [3:0] UpdateInstrClass
|
||||
);
|
||||
|
||||
localparam TotalDepth = 2 ** Depth;
|
||||
logic [TotalDepth-1:0] ValidBits;
|
||||
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex, LookUpPCIndexQ, UpdatePCIndexQ;
|
||||
|
||||
// hashing function for indexing the PC
|
||||
// We have Depth bits to index, but XLEN bits as the input.
|
||||
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
||||
// using compressed instructions. XOR bit 1 with the MSB of index.
|
||||
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
|
||||
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
|
||||
|
||||
|
||||
flopenr #(Depth) UpdatePCIndexReg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(1'b1),
|
||||
.d(UpdatePCIndex),
|
||||
.q(UpdatePCIndexQ));
|
||||
|
||||
// The valid bit must be resetable.
|
||||
always_ff @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
ValidBits <= #1 {TotalDepth{1'b0}};
|
||||
end else if (UpdateEN) begin
|
||||
ValidBits[UpdatePCIndexQ] <= #1 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
flopenr #(Depth) LookupPCIndexReg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(1'b1),
|
||||
.d(LookUpPCIndex),
|
||||
.q(LookUpPCIndexQ));
|
||||
|
||||
assign Valid = ValidBits[LookUpPCIndexQ];
|
||||
|
||||
// the BTB contains the target address.
|
||||
// Another optimization may be using a PC relative address.
|
||||
// *** need to add forwarding.
|
||||
|
||||
SRAM2P1R1W #(Depth, `XLEN+4) memory(.clk(clk),
|
||||
.reset(reset),
|
||||
.RA1(LookUpPCIndex),
|
||||
.RD1({{InstrClass, TargetPC}}),
|
||||
.REN1(1'b1),
|
||||
.WA1(UpdatePCIndex),
|
||||
.WD1({UpdateInstrClass, UpdateTarget}),
|
||||
.WEN1(UpdateEN),
|
||||
.BitWEN1({4'b0000, {`XLEN{1'b1}}})); // *** definitely not right.
|
||||
|
||||
|
||||
endmodule
|
80
wally-pipelined/src/ifu/RAsPredictor.sv
Normal file
80
wally-pipelined/src/ifu/RAsPredictor.sv
Normal file
@ -0,0 +1,80 @@
|
||||
///////////////////////////////////////////
|
||||
// RASPredictor.sv
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 15, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: 2 bit saturating counter predictor with parameterized table depth.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module RASPredictor
|
||||
#(parameter int StackSize = 16
|
||||
)
|
||||
(input logic clk,
|
||||
input logic reset,
|
||||
input logic pop,
|
||||
output logic [`XLEN-1:0] popPC,
|
||||
input logic push,
|
||||
input logic incr,
|
||||
input logic [`XLEN-1:0] pushPC
|
||||
);
|
||||
|
||||
logic CounterEn;
|
||||
localparam Depth = $clog2(StackSize);
|
||||
|
||||
logic [StackSize-1:0] PtrD, PtrQ, PtrP1, PtrM1;
|
||||
logic [StackSize-1:0] [`XLEN-1:0] memory;
|
||||
integer index;
|
||||
|
||||
assign CounterEn = pop | push | incr;
|
||||
|
||||
assign PtrD = pop ? PtrM1 : PtrP1;
|
||||
|
||||
assign PtrM1 = PtrQ - 1'b1;
|
||||
assign PtrP1 = PtrQ + 1'b1;
|
||||
// may have to handle a push and an incr at the same time.
|
||||
// *** what happens if jal is executing and there is a return being flushed in Decode?
|
||||
|
||||
flopenr #(StackSize) PTR(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(CounterEn),
|
||||
.d(PtrD),
|
||||
.q(PtrQ));
|
||||
|
||||
// RAS must be reset.
|
||||
always_ff @ (posedge clk, posedge reset) begin
|
||||
if(reset) begin
|
||||
for(index=0; index<StackSize; index++)
|
||||
memory[index] <= {`XLEN{1'b0}};
|
||||
end else if(push) begin
|
||||
memory[PtrP1] <= #1 pushPC;
|
||||
end
|
||||
end
|
||||
|
||||
assign popPC = memory[PtrQ];
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
111
wally-pipelined/src/ifu/SramModel.sv
Normal file
111
wally-pipelined/src/ifu/SramModel.sv
Normal file
@ -0,0 +1,111 @@
|
||||
///////////////////////////////////////////
|
||||
// SRAM2P1R1W
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 14, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Behavioral model of two port SRAM. While this is synthesizable it will produce a flip flop based memory whi
|
||||
// behaves with the timing of an SRAM typical of GF 14nm, 32nm, and 45nm.
|
||||
//
|
||||
//
|
||||
// to preload this memory we can use the following command
|
||||
// in modelsim's do file.
|
||||
// mem load -infile <relative path to the text file > -format <bin|hex> <hierarchy to the memory.>
|
||||
// example
|
||||
// mem laod -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module SRAM2P1R1W
|
||||
#(parameter int Depth = 10,
|
||||
parameter int Width = 2
|
||||
)
|
||||
|
||||
(input logic clk,
|
||||
// *** have to remove reset eventually
|
||||
input logic reset,
|
||||
|
||||
// port 1 is read only
|
||||
input logic [Depth-1:0] RA1,
|
||||
output logic [Width-1:0] RD1,
|
||||
input logic REN1,
|
||||
|
||||
// port 2 is write only
|
||||
input logic [Depth-1:0] WA1,
|
||||
input logic [Width-1:0] WD1,
|
||||
input logic WEN1,
|
||||
input logic [Width-1:0] BitWEN1
|
||||
);
|
||||
|
||||
|
||||
logic [Depth-1:0] RA1Q, WA1Q;
|
||||
logic WEN1Q;
|
||||
logic [Width-1:0] WD1Q;
|
||||
|
||||
logic [Width-1:0] memory [2**Depth-1:0];
|
||||
|
||||
|
||||
// SRAMs address busses are always registered first.
|
||||
|
||||
flopenr #(Depth) RA1Reg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(REN1),
|
||||
.d(RA1),
|
||||
.q(RA1Q));
|
||||
|
||||
|
||||
flopenr #(Depth) WA1Reg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(REN1),
|
||||
.d(WA1),
|
||||
.q(WA1Q));
|
||||
|
||||
flopenr #(1) WEN1Reg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(1'b1),
|
||||
.d(WEN1),
|
||||
.q(WEN1Q));
|
||||
|
||||
flopenr #(Width) WD1Reg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(REN1),
|
||||
.d(WD1),
|
||||
.q(WD1Q));
|
||||
// read port
|
||||
assign RD1 = memory[RA1Q];
|
||||
|
||||
genvar index;
|
||||
|
||||
// write port
|
||||
generate
|
||||
for (index = 0; index < Width; index = index + 1) begin
|
||||
always_ff @ (posedge clk) begin
|
||||
if (WEN1Q & BitWEN1[index]) begin
|
||||
memory[WA1Q][index] <= WD1Q[index];
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
169
wally-pipelined/src/ifu/bpred.sv
Normal file
169
wally-pipelined/src/ifu/bpred.sv
Normal file
@ -0,0 +1,169 @@
|
||||
///////////////////////////////////////////
|
||||
// bpred.sv
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 12, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Branch prediction unit
|
||||
// Produces a branch prediction based on branch history.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module bpred
|
||||
(input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
|
||||
// Fetch stage
|
||||
// the prediction
|
||||
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
|
||||
output logic [`XLEN-1:0] BPPredPCF,
|
||||
output logic SelBPPredF,
|
||||
// Update Predictor
|
||||
input logic [`XLEN-1:0] PCE, // The address of the currently executing instruction
|
||||
// 1 hot encoding
|
||||
// return, jump register, jump, branch
|
||||
// *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class.
|
||||
// *** the specifics of how this is encode is subject to change.
|
||||
input logic PCSrcE, // AKA Branch Taken
|
||||
// Signals required to check the branch prediction accuracy.
|
||||
input logic [`XLEN-1:0] PCTargetE, // The branch destination if the branch is taken.
|
||||
input logic [`XLEN-1:0] PCD, // The address the branch predictor took.
|
||||
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
input logic [3:0] InstrClassE,
|
||||
// Report branch prediction status
|
||||
output logic BPPredWrongE
|
||||
);
|
||||
|
||||
logic BTBValidF;
|
||||
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
|
||||
|
||||
logic [3:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
|
||||
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
|
||||
logic TargetWrongE;
|
||||
logic FallThroughWrongE;
|
||||
logic PredictionDirWrongE;
|
||||
logic PredictionPCWrongE;
|
||||
logic [`XLEN-1:0] CorrectPCE;
|
||||
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
|
||||
twoBitPredictor DirPredictor(.clk(clk),
|
||||
.reset(reset),
|
||||
.LookUpPC(PCNextF),
|
||||
.Prediction(BPPredF),
|
||||
// update
|
||||
.UpdatePC(PCE),
|
||||
.UpdateEN(InstrClassE[0]),
|
||||
.UpdatePrediction(UpdateBPPredE));
|
||||
|
||||
// this predictor will have two pieces of data,
|
||||
// 1) A direction (1 = Taken, 0 = Not Taken)
|
||||
// 2) Any information which is necessary for the predictor to built it's next state.
|
||||
// For a 2 bit table this is the prediction count.
|
||||
|
||||
assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) |
|
||||
BPInstrClassF[3] |
|
||||
(BPInstrClassF[2] & BTBValidF) |
|
||||
BPInstrClassF[1] & BTBValidF) ;
|
||||
|
||||
|
||||
// Part 2 Branch target address prediction
|
||||
// *** For now the BTB will house the direct and indirect targets
|
||||
|
||||
BTBPredictor TargetPredictor(.clk(clk),
|
||||
.reset(reset),
|
||||
.LookUpPC(PCNextF),
|
||||
.TargetPC(BTBPredPCF),
|
||||
.InstrClass(BPInstrClassF),
|
||||
.Valid(BTBValidF),
|
||||
// update
|
||||
.UpdateEN(InstrClassE[2] | InstrClassE[1] | InstrClassE[0]),
|
||||
.UpdatePC(PCE),
|
||||
.UpdateTarget(PCTargetE),
|
||||
.UpdateInstrClass(InstrClassE));
|
||||
|
||||
// need to forward when updating to the same address as reading.
|
||||
//assign CorrectPCE = PCSrcE ? PCTargetE : PCLinkE;
|
||||
//assign TargetPC = (PCE == PCNextF) ? CorrectPCE : BTBPredPCF;
|
||||
|
||||
// Part 3 RAS
|
||||
// *** need to add the logic to restore RAS on flushes. We will use incr for this.
|
||||
RASPredictor RASPredictor(.clk(clk),
|
||||
.reset(reset),
|
||||
.pop(BPInstrClassF[3]),
|
||||
.popPC(RASPCF),
|
||||
.push(InstrClassE[3]),
|
||||
.incr(1'b0),
|
||||
.pushPC(PCLinkE));
|
||||
|
||||
assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF;
|
||||
|
||||
|
||||
|
||||
// The prediction and its results need to be passed through the pipeline
|
||||
// *** for other predictors will will be different.
|
||||
|
||||
flopenrc #(2) BPPredRegD(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallF),
|
||||
.clear(FlushF),
|
||||
.d(BPPredF),
|
||||
.q(BPPredD));
|
||||
|
||||
flopenrc #(2) BPPredRegE(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallD),
|
||||
.clear(FlushD),
|
||||
.d(BPPredD),
|
||||
.q(BPPredE));
|
||||
|
||||
// pipeline the class
|
||||
flopenrc #(4) InstrClassRegD(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallF),
|
||||
.clear(FlushF),
|
||||
.d(BPInstrClassF),
|
||||
.q(BPInstrClassD));
|
||||
|
||||
flopenrc #(4) InstrClassRegE(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallD),
|
||||
.clear(FlushD),
|
||||
.d(BPInstrClassD),
|
||||
.q(BPInstrClassE));
|
||||
|
||||
|
||||
|
||||
// Check the prediction makes execution.
|
||||
assign TargetWrongE = PCTargetE != PCD;
|
||||
assign FallThroughWrongE = PCLinkE != PCD;
|
||||
assign PredictionDirWrongE = (BPPredE[1] ^ PCSrcE) & InstrClassE[0];
|
||||
assign PredictionPCWrongE = PCSrcE ? TargetWrongE : FallThroughWrongE;
|
||||
assign BPPredWrongE = (PredictionPCWrongE | PredictionDirWrongE) & (|InstrClassE);
|
||||
|
||||
// Update predictors
|
||||
|
||||
satCounter2 BPDirUpdate(.BrDir(PCSrcE),
|
||||
.OldState(BPPredE),
|
||||
.NewState(UpdateBPPredE));
|
||||
|
||||
endmodule
|
@ -29,7 +29,7 @@
|
||||
module ifu (
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||
// Fetch
|
||||
input logic [`XLEN-1:0] InstrInF,
|
||||
output logic [`XLEN-1:0] PCF,
|
||||
@ -38,13 +38,15 @@ module ifu (
|
||||
output logic ICacheStallF,
|
||||
// Decode
|
||||
// Execute
|
||||
input logic PCSrcE,
|
||||
input logic [`XLEN-1:0] PCTargetE,
|
||||
output logic [`XLEN-1:0] PCE,
|
||||
output logic [`XLEN-1:0] PCLinkE,
|
||||
input logic PCSrcE,
|
||||
input logic [`XLEN-1:0] PCTargetE,
|
||||
output logic [`XLEN-1:0] PCE,
|
||||
output logic BPPredWrongE,
|
||||
// Mem
|
||||
input logic RetM, TrapM,
|
||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic [31:0] InstrD, InstrM,
|
||||
input logic RetM, TrapM,
|
||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic [31:0] InstrD, InstrM,
|
||||
output logic [`XLEN-1:0] PCM,
|
||||
// Writeback
|
||||
output logic [`XLEN-1:0] PCLinkW,
|
||||
@ -65,7 +67,7 @@ module ifu (
|
||||
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
|
||||
logic PrivilegedChangePCM;
|
||||
logic IllegalCompInstrD;
|
||||
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkE, PCLinkM, PCPF;
|
||||
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM, PCPF;
|
||||
logic CompressedF;
|
||||
logic [31:0] InstrRawD, InstrE, InstrW;
|
||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
@ -81,6 +83,12 @@ module ifu (
|
||||
tlb #(3) itlb(clk, reset, SATP, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
|
||||
ITLBInstrPAdrF, ITLBMissF, ITLBHitF);
|
||||
|
||||
// branch predictor signals
|
||||
logic SelBPPredF;
|
||||
logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F;
|
||||
logic [3:0] InstrClassD, InstrClassE;
|
||||
|
||||
|
||||
// *** put memory interface on here, InstrF becomes output
|
||||
//assign InstrPAdrF = PCF; // *** no MMU
|
||||
//assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
|
||||
@ -94,10 +102,48 @@ module ifu (
|
||||
|
||||
assign PrivilegedChangePCM = RetM | TrapM;
|
||||
|
||||
mux3 #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
|
||||
//mux3 #(`XLEN) pcmux(PCPlus2or4F, PCCorrectE, PrivilegedNextPCM, {PrivilegedChangePCM, BPPredWrongE}, UnalignedPCNextF);
|
||||
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F),
|
||||
.d1(BPPredPCF),
|
||||
.s(SelBPPredF),
|
||||
.y(PCNext0F));
|
||||
|
||||
mux2 #(`XLEN) pcmux1(.d0(PCNext0F),
|
||||
.d1(PCCorrectE),
|
||||
.s(BPPredWrongE),
|
||||
.y(PCNext1F));
|
||||
|
||||
mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
|
||||
.d1(PrivilegedNextPCM),
|
||||
.s(PrivilegedChangePCM),
|
||||
.y(UnalignedPCNextF));
|
||||
|
||||
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||
flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
|
||||
|
||||
// branch and jump predictor
|
||||
// I am making the port connection explicit for now as I want to see them and they will be changing.
|
||||
bpred bpred(.clk(clk),
|
||||
.reset(reset),
|
||||
.StallF(StallF),
|
||||
.StallD(StallD),
|
||||
.StallE(1'b0), // *** may need this eventually
|
||||
.FlushF(FlushF),
|
||||
.FlushD(FlushD),
|
||||
.FlushE(FlushE),
|
||||
.PCNextF(PCNextF),
|
||||
.BPPredPCF(BPPredPCF),
|
||||
.SelBPPredF(SelBPPredF),
|
||||
.PCE(PCE),
|
||||
.PCSrcE(PCSrcE),
|
||||
.PCTargetE(PCTargetE),
|
||||
.PCD(PCD),
|
||||
.PCLinkE(PCLinkE),
|
||||
.InstrClassE(InstrClassE),
|
||||
.BPPredWrongE(BPPredWrongE));
|
||||
// The true correct target is PCTargetE if PCSrcE is 1 else it is the fall through PCLinkE.
|
||||
assign PCCorrectE = PCSrcE ? PCTargetE : PCLinkE;
|
||||
|
||||
// pcadder
|
||||
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
||||
assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC
|
||||
@ -116,6 +162,14 @@ module ifu (
|
||||
assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
||||
// *** combine these with others in better way, including M, F
|
||||
|
||||
|
||||
// the branch predictor needs a compact decoding of the instruction class.
|
||||
// *** consider adding in the alternate return address x5 for returns.
|
||||
assign InstrClassD[3] = InstrD[6:0] == 7'h67 && InstrD[19:15] == 5'h01; // return
|
||||
assign InstrClassD[2] = InstrD[6:0] == 7'h67 && InstrD[19:15] != 5'h01; // jump register, but not return
|
||||
assign InstrClassD[1] = InstrD[6:0] == 7'h6F; // jump
|
||||
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
|
||||
|
||||
// Misaligned PC logic
|
||||
|
||||
generate
|
||||
@ -139,6 +193,13 @@ module ifu (
|
||||
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
|
||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later
|
||||
|
||||
flopenrc #(4) InstrClassRegE(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(~StallD),
|
||||
.clear(FlushD),
|
||||
.d(InstrClassD),
|
||||
.q(InstrClassE));
|
||||
|
||||
// seems like there should be a lower-cost way of doing this PC+2 or PC+4 for JAL.
|
||||
// either have ALU compute PC+2/4 and feed into ALUResult input of ResultMux or
|
||||
// have dedicated adder in Mem stage based on PCM + 2 or 4
|
||||
|
57
wally-pipelined/src/ifu/satCounter2.sv
Normal file
57
wally-pipelined/src/ifu/satCounter2.sv
Normal file
@ -0,0 +1,57 @@
|
||||
///////////////////////////////////////////
|
||||
// satCounter2.sv
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 13, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: 2 bit starting counter
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module satCounter2
|
||||
(input logic BrDir,
|
||||
input logic [1:0] OldState,
|
||||
output logic [1:0] NewState
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
case(OldState)
|
||||
2'b00: begin
|
||||
if(BrDir) NewState = 2'b01;
|
||||
else NewState = 2'b00;
|
||||
end
|
||||
2'b01: begin
|
||||
if(BrDir) NewState = 2'b10;
|
||||
else NewState = 2'b00;
|
||||
end
|
||||
2'b10: begin
|
||||
if(BrDir) NewState = 2'b11;
|
||||
else NewState = 2'b01;
|
||||
end
|
||||
2'b11: begin
|
||||
if(BrDir) NewState = 2'b11;
|
||||
else NewState = 2'b10;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
84
wally-pipelined/src/ifu/twoBitPredictor.sv
Normal file
84
wally-pipelined/src/ifu/twoBitPredictor.sv
Normal file
@ -0,0 +1,84 @@
|
||||
///////////////////////////////////////////
|
||||
// twoBitPredictor.sv
|
||||
//
|
||||
// Written: Ross Thomposn
|
||||
// Email: ross1728@gmail.com
|
||||
// Created: February 14, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: 2 bit saturating counter predictor with parameterized table depth.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module twoBitPredictor
|
||||
#(parameter int Depth = 10
|
||||
)
|
||||
(input logic clk,
|
||||
input logic reset,
|
||||
input logic [`XLEN-1:0] LookUpPC,
|
||||
output logic [1:0] Prediction,
|
||||
// update
|
||||
input logic [`XLEN-1:0] UpdatePC,
|
||||
input logic UpdateEN,
|
||||
input logic [1:0] UpdatePrediction
|
||||
);
|
||||
|
||||
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex;
|
||||
logic [1:0] PredictionMemory;
|
||||
logic DoForwarding, DoForwardingF;
|
||||
logic [1:0] UpdatePredictionF;
|
||||
|
||||
|
||||
// hashing function for indexing the PC
|
||||
// We have Depth bits to index, but XLEN bits as the input.
|
||||
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
||||
// using compressed instructions. XOR bit 1 with the MSB of index.
|
||||
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
|
||||
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
|
||||
|
||||
|
||||
SRAM2P1R1W #(Depth, 2) memory(.clk(clk),
|
||||
.reset(reset),
|
||||
.RA1(LookUpPCIndex),
|
||||
.RD1(PredictionMemory),
|
||||
.REN1(1'b1),
|
||||
.WA1(UpdatePCIndex),
|
||||
.WD1(UpdatePrediction),
|
||||
.WEN1(UpdateEN),
|
||||
.BitWEN1(2'b11));
|
||||
|
||||
// need to forward when updating to the same address as reading.
|
||||
// first we compare to see if the update and lookup addreses are the same
|
||||
assign DoForwarding = UpdatePCIndex == LookUpPCIndex;
|
||||
|
||||
// register the update value and the forwarding signal into the Fetch stage
|
||||
flopr #(1) DoForwardingReg(.clk(clk),
|
||||
.reset(reset),
|
||||
.d(DoForwarding),
|
||||
.q(DoForwardingF));
|
||||
|
||||
flopr #(2) UpdatePredictionReg(.clk(clk),
|
||||
.reset(reset),
|
||||
.d(UpdatePrediction),
|
||||
.q(UpdatePredictionF));
|
||||
|
||||
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
|
||||
|
||||
endmodule
|
@ -108,7 +108,7 @@ module csrm #(parameter
|
||||
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT);
|
||||
|
||||
// CSRs
|
||||
flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `RESET_VECTOR, MTVEC_REGW);
|
||||
flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `XLEN'b0, MTVEC_REGW); //busybear: changed reset value to 0
|
||||
generate
|
||||
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist
|
||||
flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, zero, MEDELEG_REGW);
|
||||
@ -125,7 +125,11 @@ module csrm #(parameter
|
||||
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
|
||||
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
|
||||
flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
|
||||
`ifndef BUSYBEAR
|
||||
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW);
|
||||
`else
|
||||
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW);
|
||||
`endif
|
||||
flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW);
|
||||
flopenr #(`XLEN) PMPADDR0reg(clk, reset, WritePMPADDR0M, CSRWriteValM, PMPADDR0_REGW);
|
||||
// PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32
|
||||
|
@ -75,13 +75,17 @@ module csrs #(parameter
|
||||
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN);
|
||||
|
||||
// CSRs
|
||||
flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, `RESET_VECTOR, STVEC_REGW);
|
||||
flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, zero, STVEC_REGW); //busybear: change reset to 0
|
||||
flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
|
||||
flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
|
||||
flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW);
|
||||
flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
|
||||
flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
|
||||
`ifndef BUSYBEAR
|
||||
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], allones, SCOUNTEREN_REGW);
|
||||
`else
|
||||
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW);
|
||||
`endif
|
||||
if (`N_SUPPORTED) begin
|
||||
logic WriteSEDELEGM, WriteSIDELEGM;
|
||||
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);
|
||||
|
@ -109,15 +109,15 @@ module csrsr (
|
||||
if (reset) begin
|
||||
STATUS_SUM_INT <= 0;
|
||||
STATUS_MPRV_INT <= 0; // Per Priv 3.3
|
||||
STATUS_FS_INT <= 2'b01; // initial
|
||||
STATUS_MPP <= `M_MODE;
|
||||
STATUS_SPP <= 1'b1;
|
||||
STATUS_MPIE <= 1;
|
||||
STATUS_SPIE <= `S_SUPPORTED;
|
||||
STATUS_UPIE <= `U_SUPPORTED;
|
||||
STATUS_FS_INT <= 0; //2'b01; // busybear: change all these reset values to 0
|
||||
STATUS_MPP <= 0; //`M_MODE;
|
||||
STATUS_SPP <= 0; //1'b1;
|
||||
STATUS_MPIE <= 0; //1;
|
||||
STATUS_SPIE <= 0; //`S_SUPPORTED;
|
||||
STATUS_UPIE <= 0; // `U_SUPPORTED;
|
||||
STATUS_MIE <= 0; // Per Priv 3.3
|
||||
STATUS_SIE <= `S_SUPPORTED;
|
||||
STATUS_UIE <= `U_SUPPORTED;
|
||||
STATUS_SIE <= 0; //`S_SUPPORTED;
|
||||
STATUS_UIE <= 0; //`U_SUPPORTED;
|
||||
end else if (~StallW) begin
|
||||
if (WriteMSTATUSM) begin
|
||||
STATUS_SUM_INT <= CSRWriteValM[18];
|
||||
@ -179,4 +179,4 @@ module csrsr (
|
||||
// *** add code to track STATUS_FS_INT for dirty floating point registers
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
endmodule
|
||||
|
@ -28,8 +28,9 @@
|
||||
|
||||
module clint (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic [1:0] MemRWclint,
|
||||
input logic [15:0] HADDR,
|
||||
input logic HSELCLINT,
|
||||
input logic [15:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
output logic [`XLEN-1:0] HREADCLINT,
|
||||
output logic HRESPCLINT, HREADYCLINT,
|
||||
@ -41,8 +42,8 @@ module clint (
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWclint[1];
|
||||
assign memwrite = MemRWclint[0];
|
||||
assign memread = HSELCLINT & ~HWRITE;
|
||||
assign memwrite = HSELCLINT & HWRITE;
|
||||
assign HRESPCLINT = 0; // OK
|
||||
// assign HREADYCLINT = 1; // Respond immediately
|
||||
always_ff @(posedge HCLK) // delay response
|
||||
|
@ -25,24 +25,30 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module dtim (
|
||||
module dtim #(parameter BASE=0, RANGE = 65535) (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic [1:0] MemRWtim,
|
||||
input logic [18:0] HADDR,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
input logic HSELTim,
|
||||
input logic [31:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
output logic [`XLEN-1:0] HREADTim,
|
||||
output logic HRESPTim, HREADYTim
|
||||
);
|
||||
|
||||
logic [`XLEN-1:0] RAM[0:65535];
|
||||
logic [18:0] HWADDR;
|
||||
logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)];
|
||||
logic [31:0] HWADDR, A;
|
||||
logic [`XLEN-1:0] HREADTim0;
|
||||
|
||||
// logic [`XLEN-1:0] write;
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
logic [3:0] busycount;
|
||||
logic memread, memwrite;
|
||||
logic [3:0] busycount;
|
||||
|
||||
always_ff @(posedge HCLK) begin
|
||||
memread <= HSELTim & ~ HWRITE;
|
||||
memwrite <= HSELTim & HWRITE;
|
||||
A <= HADDR;
|
||||
end
|
||||
|
||||
// busy FSM to extend READY signal
|
||||
always_ff @(posedge HCLK, negedge HRESETn)
|
||||
@ -61,42 +67,21 @@ module dtim (
|
||||
end
|
||||
end
|
||||
|
||||
/* always_ff @(posedge HCLK, negedge HRESETn)
|
||||
if (~HRESETn) begin
|
||||
HREADYTim <= 0;
|
||||
end else begin
|
||||
HREADYTim <= HSELTim; // always respond one cycle later
|
||||
end */
|
||||
|
||||
|
||||
assign memread = MemRWtim[1];
|
||||
assign memwrite = MemRWtim[0];
|
||||
// always_ff @(posedge HCLK)
|
||||
// memwrite <= MemRWtim[0]; // delay memwrite to write phase
|
||||
assign HRESPTim = 0; // OK
|
||||
// assign HREADYTim = 1; // Respond immediately; *** extend this
|
||||
|
||||
|
||||
// Model memory read and write
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
// always_ff @(negedge HCLK)
|
||||
// if (memwrite) RAM[HWADDR[17:3]] <= HWDATA;
|
||||
always_ff @(posedge HCLK) begin
|
||||
//if (memwrite) RAM[HADDR[17:3]] <= HWDATA;
|
||||
HWADDR <= HADDR;
|
||||
HREADTim0 <= RAM[HADDR[17:3]];
|
||||
if (memwrite && HREADYTim) RAM[HWADDR[17:3]] <= HWDATA;
|
||||
HWADDR <= A;
|
||||
HREADTim0 <= RAM[A[31:3]];
|
||||
if (memwrite && HREADYTim) RAM[HWADDR[31:3]] <= HWDATA;
|
||||
end
|
||||
end else begin
|
||||
// always_ff @(negedge HCLK)
|
||||
// if (memwrite) RAM[HWADDR[17:2]] <= HWDATA;
|
||||
always_ff @(posedge HCLK) begin
|
||||
//if (memwrite) RAM[HADDR[17:2]] <= HWDATA;
|
||||
HWADDR <= HADDR;
|
||||
HREADTim0 <= RAM[HADDR[17:2]];
|
||||
if (memwrite && HREADYTim) RAM[HWADDR[17:2]] <= HWDATA;
|
||||
HWADDR <= A;
|
||||
HREADTim0 <= RAM[A[31:2]];
|
||||
if (memwrite && HREADYTim) RAM[HWADDR[31:2]] <= HWDATA;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
@ -29,9 +29,10 @@
|
||||
|
||||
module gpio (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic [1:0] MemRWgpio,
|
||||
input logic HSELGPIO,
|
||||
input logic [7:0] HADDR,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
input logic HWRITE,
|
||||
output logic [`XLEN-1:0] HREADGPIO,
|
||||
output logic HRESPGPIO, HREADYGPIO,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
@ -42,8 +43,8 @@ module gpio (
|
||||
logic [7:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWgpio[1];
|
||||
assign memwrite = MemRWgpio[0];
|
||||
assign memread = HSELGPIO & ~HWRITE;
|
||||
assign memwrite = HSELGPIO & HWRITE;
|
||||
assign HRESPGPIO = 0; // OK
|
||||
always_ff @(posedge HCLK) // delay response to data cycle
|
||||
HREADYGPIO <= memread | memwrite;
|
||||
|
@ -32,24 +32,35 @@ module imem (
|
||||
output logic InstrAccessFaultF);
|
||||
|
||||
/* verilator lint_off UNDRIVEN */
|
||||
logic [`XLEN-1:0] RAM[0:65535];
|
||||
logic [`XLEN-1:0] RAM[`TIMBASE>>(1+`XLEN/32):(`TIMRANGE+`TIMBASE)>>(1+`XLEN/32)];
|
||||
`ifdef BOOTTIMBASE
|
||||
logic [`XLEN-1:0] bootram[`BOOTTIMBASE>>(1+`XLEN/32):(`BOOTTIMRANGE+`BOOTTIMBASE)>>(1+`XLEN/32)];
|
||||
`endif
|
||||
/* verilator lint_on UNDRIVEN */
|
||||
logic [15:0] adrbits;
|
||||
logic [28:0] adrbits;
|
||||
logic [`XLEN-1:0] rd;
|
||||
// logic [15:0] rd2;
|
||||
|
||||
generate
|
||||
if (`XLEN==32) assign adrbits = AdrF[17:2];
|
||||
else assign adrbits = AdrF[18:3];
|
||||
if (`XLEN==32) assign adrbits = AdrF[30:2];
|
||||
else assign adrbits = AdrF[31:3];
|
||||
endgenerate
|
||||
|
||||
`ifndef BOOTTIMBASE
|
||||
assign #2 rd = RAM[adrbits]; // word aligned
|
||||
`else
|
||||
assign #2 rd = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits] : RAM[adrbits]; // busybear: 2 memory options
|
||||
`endif
|
||||
|
||||
// hack right now for unaligned 32-bit instructions
|
||||
// eventually this will need to cause a stall like a cache miss
|
||||
// when the instruction wraps around a cache line
|
||||
// could be optimized to only stall when the instruction wrapping is 32 bits
|
||||
`ifndef BOOTTIMBASE
|
||||
assign #2 rd2 = RAM[adrbits+1][15:0];
|
||||
`else
|
||||
assign #2 rd2 = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits+1][15:0] : RAM[adrbits+1][15:0]; //busybear: 2 memory options
|
||||
`endif
|
||||
generate
|
||||
if (`XLEN==32) begin
|
||||
assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd;
|
||||
@ -57,7 +68,11 @@ module imem (
|
||||
end else begin
|
||||
assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32])
|
||||
: (AdrF[1] ? rd[47:16] : rd[31:0]);
|
||||
`ifndef BOOTTIMBASE
|
||||
assign InstrAccessFaultF = |AdrF[`XLEN-1:32] | ~&({AdrF[31:1],1'b0} ~^ `TIMBASE | `TIMRANGE);
|
||||
`else
|
||||
assign InstrAccessFaultF = 0; //busybear: for now, i know we're not doing this
|
||||
`endif
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
@ -29,8 +29,9 @@
|
||||
|
||||
module uart (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic [1:0] MemRWuart,
|
||||
input logic [2:0] HADDR,
|
||||
input logic HSELUART,
|
||||
input logic [2:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
output logic [`XLEN-1:0] HREADUART,
|
||||
output logic HRESPUART, HREADYUART,
|
||||
@ -44,37 +45,37 @@ module uart (
|
||||
logic [7:0] Din, Dout;
|
||||
|
||||
// rename processor interface signals to match PC16550D and provide one-byte interface
|
||||
assign MEMRb = ~MemRWuart[1];
|
||||
assign MEMWb = ~MemRWuart[0];
|
||||
assign A = HADDR[2:0];
|
||||
always_ff @(posedge HCLK) begin
|
||||
MEMRb <= ~(HSELUART & ~HWRITE);
|
||||
MEMWb <= ~(HSELUART & HWRITE);
|
||||
A <= HADDR[2:0];
|
||||
end
|
||||
assign HRESPUART = 0; // OK
|
||||
//assign HREADYUART = 1; // Respond immediately
|
||||
always_ff @(posedge HCLK) // delay response to data cycle
|
||||
HREADYUART <= ~MEMRb | ~MEMWb;
|
||||
assign HREADYUART = 1; // should idle high during address phase and respond high when done; will need to be modified if UART ever needs more than 1 cycle to do something
|
||||
|
||||
generate
|
||||
if (`XLEN == 64) begin
|
||||
always @(posedge HCLK) begin
|
||||
always_comb begin
|
||||
HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||
case (HADDR)
|
||||
3'b000: Din <= HWDATA[7:0];
|
||||
3'b001: Din <= HWDATA[15:8];
|
||||
3'b010: Din <= HWDATA[23:16];
|
||||
3'b011: Din <= HWDATA[31:24];
|
||||
3'b100: Din <= HWDATA[39:32];
|
||||
3'b101: Din <= HWDATA[47:40];
|
||||
3'b110: Din <= HWDATA[55:48];
|
||||
3'b111: Din <= HWDATA[63:56];
|
||||
case (A)
|
||||
3'b000: Din = HWDATA[7:0];
|
||||
3'b001: Din = HWDATA[15:8];
|
||||
3'b010: Din = HWDATA[23:16];
|
||||
3'b011: Din = HWDATA[31:24];
|
||||
3'b100: Din = HWDATA[39:32];
|
||||
3'b101: Din = HWDATA[47:40];
|
||||
3'b110: Din = HWDATA[55:48];
|
||||
3'b111: Din = HWDATA[63:56];
|
||||
endcase
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always @(posedge HCLK) begin
|
||||
always_comb begin
|
||||
HREADUART = {Dout, Dout, Dout, Dout};
|
||||
case (HADDR[1:0])
|
||||
2'b00: Din <= HWDATA[7:0];
|
||||
2'b01: Din <= HWDATA[15:8];
|
||||
2'b10: Din <= HWDATA[23:16];
|
||||
2'b11: Din <= HWDATA[31:24];
|
||||
case (A[1:0])
|
||||
2'b00: Din = HWDATA[7:0];
|
||||
2'b01: Din = HWDATA[15:8];
|
||||
2'b10: Din = HWDATA[23:16];
|
||||
2'b11: Din = HWDATA[31:24];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -376,7 +376,7 @@ module uartPC16550D(
|
||||
TXHR <= Din;
|
||||
txhrfull <= 1;
|
||||
end
|
||||
$display("UART transmits: %c",Din); // for testbench
|
||||
$write("%c",Din); // for testbench
|
||||
end
|
||||
if (txstate == UART_IDLE) begin // move data into tx shift register if available
|
||||
if (fifoenabled) begin
|
||||
|
@ -2,7 +2,7 @@
|
||||
// uncore.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
// Modified: Ben Bracker 6 Mar 2021 to better fit AMBA 3 AHB-Lite spec
|
||||
//
|
||||
// Purpose: System-on-Chip components outside the core (hart)
|
||||
// Memories, peripherals, external bus control
|
||||
@ -59,58 +59,96 @@ module uncore (
|
||||
|
||||
logic [`XLEN-1:0] HWDATA;
|
||||
logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADGPIO, HREADUART;
|
||||
|
||||
logic HSELTim, HSELCLINT, HSELGPIO, PreHSELUART, HSELUART;
|
||||
logic HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD;
|
||||
logic HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART;
|
||||
logic HREADYTim, HREADYCLINT, HREADYGPIO, HREADYUART;
|
||||
logic [1:0] MemRW;
|
||||
logic [1:0] MemRWtim, MemRWclint, MemRWgpio, MemRWuart;
|
||||
`ifdef BOOTTIMBASE
|
||||
logic [`XLEN-1:0] HREADBootTim;
|
||||
logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim;
|
||||
logic [1:0] MemRWboottim;
|
||||
`endif
|
||||
logic UARTIntr;// *** will need to tie INTR to an interrupt handler
|
||||
|
||||
|
||||
// AHB Address decoder
|
||||
adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
|
||||
`ifdef BOOTTIMBASE
|
||||
adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim);
|
||||
`endif
|
||||
adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT);
|
||||
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
|
||||
`ifdef GPIOBASE
|
||||
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
|
||||
`endif
|
||||
adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
|
||||
assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
|
||||
|
||||
// Enable read or write based on decoded address
|
||||
assign MemRW = {~HWRITE, HWRITED};
|
||||
assign MemRWtim = MemRW & {2{HSELTim}};
|
||||
assign MemRWclint = MemRW & {2{HSELCLINT}};
|
||||
assign MemRWgpio = MemRW & {2{HSELGPIO}};
|
||||
assign MemRWuart = MemRW & {2{HSELUART}};
|
||||
/* always_ff @(posedge HCLK) begin
|
||||
HADDRD <= HADDR;
|
||||
MemRWtim <= MemRW & {2{HSELTim}};
|
||||
MemRWclint <= MemRW & {2{HSELCLINT}};
|
||||
MemRWgpio <= MemRW & {2{HSELGPIO}};
|
||||
MemRWuart <= MemRW & {2{HSELUART}};
|
||||
end */
|
||||
|
||||
// subword accesses: converts HWDATAIN to HWDATA
|
||||
subwordwrite sww(.*);
|
||||
|
||||
// tightly integrated memory
|
||||
dtim dtim(.HADDR(HADDR[18:0]), .*);
|
||||
dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) dtim (.*);
|
||||
`ifdef BOOTTIMBASE
|
||||
dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim(.HSELTim(HSELBootTim), .HREADTim(HREADBootTim), .HRESPTim(HRESPBootTim), .HREADYTim(HREADYBootTim), .*);
|
||||
`endif
|
||||
|
||||
// memory-mapped I/O peripherals
|
||||
clint clint(.HADDR(HADDR[15:0]), .*);
|
||||
`ifdef GPIOBASE
|
||||
gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts
|
||||
`endif
|
||||
uart uart(.HADDR(HADDR[2:0]), .TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout),
|
||||
.DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),
|
||||
.RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*);
|
||||
.RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*);
|
||||
|
||||
// mux could also include external memory
|
||||
// AHB Read Multiplexer
|
||||
assign HRDATA = ({`XLEN{HSELTim}} & HREADTim) | ({`XLEN{HSELCLINT}} & HREADCLINT) |
|
||||
({`XLEN{HSELGPIO}} & HREADGPIO) | ({`XLEN{HSELUART}} & HREADUART);
|
||||
assign HRESP = HSELTim & HRESPTim | HSELCLINT & HRESPCLINT | HSELGPIO & HRESPGPIO | HSELUART & HRESPUART;
|
||||
assign HREADY = HSELTim & HREADYTim | HSELCLINT & HREADYCLINT | HSELGPIO & HREADYGPIO | HSELUART & HREADYUART;
|
||||
assign HRDATA = ({`XLEN{HSELTimD}} & HREADTim) | ({`XLEN{HSELCLINTD}} & HREADCLINT) |
|
||||
`ifdef GPIOBASE
|
||||
({`XLEN{HSELGPIOD}} & HREADGPIO) |
|
||||
`endif
|
||||
`ifdef BOOTTIMBASE
|
||||
({`XLEN{HSELBootTimD}} & HREADBootTim) |
|
||||
`endif
|
||||
({`XLEN{HSELUARTD}} & HREADUART);
|
||||
assign HRESP = HSELTimD & HRESPTim | HSELCLINTD & HRESPCLINT |
|
||||
`ifdef GPIOBASE
|
||||
HSELGPIOD & HRESPGPIO |
|
||||
`endif
|
||||
`ifdef BOOTTIMBASE
|
||||
HSELBootTimD & HRESPBootTim |
|
||||
`endif
|
||||
HSELUARTD & HRESPUART;
|
||||
assign HREADY = HSELTimD & HREADYTim | HSELCLINTD & HREADYCLINT |
|
||||
`ifdef GPIOBASE
|
||||
HSELGPIOD & HREADYGPIO |
|
||||
`endif
|
||||
`ifdef BOOTTIMBASE
|
||||
HSELBootTimD & HREADYBootTim |
|
||||
`endif
|
||||
HSELUARTD & HREADYUART;
|
||||
|
||||
// Faults
|
||||
assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELGPIO | HSELUART);
|
||||
assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD |
|
||||
`ifdef GPIOBASE
|
||||
HSELGPIOD |
|
||||
`endif
|
||||
`ifdef BOOTTIMBASE
|
||||
HSELBootTimD |
|
||||
`endif
|
||||
HSELUARTD);
|
||||
|
||||
|
||||
|
||||
// Address Decoder Delay (figure 4-2 in spec)
|
||||
flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD);
|
||||
flopr #(1) hselclintreg(HCLK, ~HRESETn, HSELCLINT, HSELCLINTD);
|
||||
`ifdef GPIOBASE
|
||||
flopr #(1) hselgpioreg(HCLK, ~HRESETn, HSELGPIO, HSELGPIOD);
|
||||
`endif
|
||||
flopr #(1) hseluartreg(HCLK, ~HRESETn, HSELUART, HSELUARTD);
|
||||
`ifdef BOOTTIMBASE
|
||||
flopr #(1) hselboottimreg(HCLK, ~HRESETn, HSELBootTim, HSELBootTimD);
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
|
@ -55,7 +55,7 @@ module wallypipelinedhart (
|
||||
|
||||
// logic [1:0] ForwardAE, ForwardBE;
|
||||
logic StallF, StallD, StallE, StallM, StallW;
|
||||
logic FlushD, FlushE, FlushM, FlushW;
|
||||
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||
logic RetM, TrapM;
|
||||
|
||||
// new signals that must connect through DP
|
||||
@ -66,7 +66,7 @@ module wallypipelinedhart (
|
||||
logic [2:0] Funct3E;
|
||||
// logic [31:0] InstrF;
|
||||
logic [31:0] InstrD, InstrM;
|
||||
logic [`XLEN-1:0] PCE, PCM, PCLinkW;
|
||||
logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
|
||||
logic [`XLEN-1:0] PCTargetE;
|
||||
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
|
||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||
@ -104,13 +104,14 @@ module wallypipelinedhart (
|
||||
logic InstrReadF;
|
||||
logic DataStall, InstrStall;
|
||||
logic InstrAckD, MemAckW;
|
||||
logic BPPredWrongE;
|
||||
|
||||
|
||||
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||
|
||||
ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
|
||||
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
|
||||
dmem dmem(.*); // data cache unit
|
||||
|
||||
|
||||
ahblite ebu(
|
||||
//.InstrReadF(1'b0),
|
||||
//.InstrRData(InstrF), // hook up InstrF later
|
||||
|
108
wally-pipelined/testbench/function_radix.sv
Normal file
108
wally-pipelined/testbench/function_radix.sv
Normal file
@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////
|
||||
// datapath.sv
|
||||
//
|
||||
// Written: Ross Thompson
|
||||
// email: ross1728@gmail.com
|
||||
// Created: November 9, 2019
|
||||
//
|
||||
// Purpose: Finds the current function or global assembly label based on PCE.
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module function_radix();
|
||||
|
||||
parameter PRELOAD_FILE = "funct_addr.txt";
|
||||
|
||||
integer memory_bank [];
|
||||
integer index;
|
||||
|
||||
logic [`XLEN-1:0] pc;
|
||||
|
||||
initial begin
|
||||
$init_signal_spy("/riscv_mram_tb/dut/pc", "/riscv_mram_tb/function_radix/pc");
|
||||
end
|
||||
|
||||
task automatic bin_search_min;
|
||||
input integer pc;
|
||||
input integer length;
|
||||
ref integer array [];
|
||||
output integer minval;
|
||||
|
||||
integer left, right;
|
||||
integer mid;
|
||||
|
||||
begin
|
||||
left = 0;
|
||||
right = length;
|
||||
while (left <= right) begin
|
||||
mid = left + ((right - left) / 2);
|
||||
if (array[mid] == pc) begin
|
||||
minval = array[mid];
|
||||
return;
|
||||
end
|
||||
if (array[mid] < pc) begin
|
||||
left = mid + 1;
|
||||
end else begin
|
||||
right = mid -1;
|
||||
end
|
||||
end // while (left <= right)
|
||||
// if the element pc is now found, right and left will be equal at this point.
|
||||
// we need to check if pc is less than the array at left or greather.
|
||||
// if it is less than pc, then we select left as the index.
|
||||
// if it is greather we want 1 less than left.
|
||||
if (array[left] < pc) begin
|
||||
minval = array[left];
|
||||
return;
|
||||
end else begin
|
||||
minval = array[left-1];
|
||||
return;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
// preload
|
||||
initial $readmemh(PRELOAD_FILE, memory_bank);
|
||||
|
||||
// we need to count the number of lines in the file so we can set line_count.
|
||||
integer fp;
|
||||
integer line_count = 0;
|
||||
logic [31:0] line;
|
||||
initial begin
|
||||
fp = $fopen(PRELOAD_FILE, "r");
|
||||
// read line by line to count lines
|
||||
if (fp) begin
|
||||
while (! $feof(fp)) begin
|
||||
$fscanf(fp, "%h\n", line);
|
||||
line_count = line_count + 1;
|
||||
end
|
||||
end else begin
|
||||
$display("Cannot open file %s for reading.", PRELOAD_FILE);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
always @(pc) begin
|
||||
bin_search_min(pc, line_count, memory_bank, index);
|
||||
|
||||
end
|
||||
|
||||
endmodule // function_radix
|
||||
|
@ -7,14 +7,9 @@ module testbench_busybear();
|
||||
logic [31:0] GPIOPinsOut, GPIOPinsEn;
|
||||
|
||||
// instantiate device to be tested
|
||||
logic [`XLEN-1:0] PCF;
|
||||
logic [31:0] InstrF;
|
||||
logic InstrAccessFaultF, DataAccessFaultM;
|
||||
logic TimerIntM = 0, SwIntM = 0; // from CLINT
|
||||
logic ExtIntM = 0; // not yet connected
|
||||
logic [31:0] CheckInstrF;
|
||||
|
||||
logic [`AHBW-1:0] HRDATA;
|
||||
logic HREADY, HRESP;
|
||||
logic [31:0] HADDR;
|
||||
logic [`AHBW-1:0] HWDATA;
|
||||
logic HWRITE;
|
||||
@ -24,85 +19,124 @@ module testbench_busybear();
|
||||
logic [1:0] HTRANS;
|
||||
logic HMASTLOCK;
|
||||
logic HCLK, HRESETn;
|
||||
logic [`AHBW-1:0] HRDATAEXT;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic UARTSout;
|
||||
|
||||
assign GPIOPinsIn = 0;
|
||||
assign UARTSin = 1;
|
||||
assign HREADY = 1;
|
||||
assign HRESP = 0;
|
||||
assign HRDATA = 0;
|
||||
|
||||
// for now, seem to need these to be zero until we get a better idea
|
||||
assign InstrAccessFaultF = 0;
|
||||
assign DataAccessFaultM = 0;
|
||||
|
||||
// instantiate processor and memories
|
||||
wallypipelinedhart dut(.*);
|
||||
wallypipelinedsoc dut(.*);
|
||||
|
||||
|
||||
// initialize test
|
||||
initial
|
||||
begin
|
||||
reset <= 1; # 22; reset <= 0;
|
||||
end
|
||||
|
||||
|
||||
// read pc trace file
|
||||
integer data_file_PC, scan_file_PC;
|
||||
initial begin
|
||||
data_file_PC = $fopen("../busybear-testgen/parsedPC.txt", "r");
|
||||
data_file_PC = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r");
|
||||
if (data_file_PC == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
integer data_file_PCW, scan_file_PCW;
|
||||
initial begin
|
||||
data_file_PCW = $fopen("../busybear-testgen/parsedPC.txt", "r");
|
||||
data_file_PCW = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r");
|
||||
if (data_file_PCW == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read register trace file
|
||||
integer data_file_rf, scan_file_rf;
|
||||
initial begin
|
||||
data_file_rf = $fopen("../busybear-testgen/parsedRegs.txt", "r");
|
||||
data_file_rf = $fopen("/courses/e190ax/busybear_boot/parsedRegs.txt", "r");
|
||||
if (data_file_rf == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read CSR trace file
|
||||
integer data_file_csr, scan_file_csr;
|
||||
initial begin
|
||||
data_file_csr = $fopen("../busybear-testgen/parsedCSRs.txt", "r");
|
||||
data_file_csr = $fopen("/courses/e190ax/busybear_boot/parsedCSRs.txt", "r");
|
||||
if (data_file_csr == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read memreads trace file
|
||||
integer data_file_memR, scan_file_memR;
|
||||
initial begin
|
||||
data_file_memR = $fopen("../busybear-testgen/parsedMemRead.txt", "r");
|
||||
data_file_memR = $fopen("/courses/e190ax/busybear_boot/parsedMemRead.txt", "r");
|
||||
if (data_file_memR == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// read memwrite trace file
|
||||
integer data_file_memW, scan_file_memW;
|
||||
initial begin
|
||||
data_file_memW = $fopen("../busybear-testgen/parsedMemWrite.txt", "r");
|
||||
data_file_memW = $fopen("/courses/e190ax/busybear_boot/parsedMemWrite.txt", "r");
|
||||
if (data_file_memW == 0) begin
|
||||
$display("file couldn't be opened");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// initial loading of memories
|
||||
initial begin
|
||||
$readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.uncore.bootdtim.RAM, 'h1000 >> 3);
|
||||
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.uncore.dtim.RAM);
|
||||
$readmemh("/courses/e190ax/busybear_boot/bootmem.txt", dut.imem.bootram, 'h1000 >> 3);
|
||||
$readmemh("/courses/e190ax/busybear_boot/ram.txt", dut.imem.RAM);
|
||||
end
|
||||
|
||||
integer warningCount = 0;
|
||||
|
||||
//logic[63:0] adrTranslation[4:0];
|
||||
//string translationType[4:0] = {"rf", "writeAdr", "PCW", "PC", "readAdr"};
|
||||
//initial begin
|
||||
// for(int i=0; i<5; i++) begin
|
||||
// adrTranslation[i] = 64'b0;
|
||||
// end
|
||||
//end
|
||||
|
||||
//function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func);
|
||||
// if (adr[11:0] !== adrExpected[11:0]) begin
|
||||
// equal = 1'b0;
|
||||
// end else begin
|
||||
// equal = 1'b1;
|
||||
// if ((adr+adrTranslation[func]) !== adrExpected) begin
|
||||
// adrTranslation[func] = adrExpected - adr;
|
||||
// $display("warning: probably new address translation %x for %s at instr %0d", adrTranslation[func], translationType[func], instrs);
|
||||
// warningCount += 1;
|
||||
// end
|
||||
// end
|
||||
//endfunction
|
||||
|
||||
// pretty sure this isn't necessary anymore, but keeping this for now since its easier
|
||||
function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func);
|
||||
equal = adr === adrExpected;
|
||||
endfunction
|
||||
|
||||
|
||||
`define ERROR \
|
||||
#10; \
|
||||
$display("processed %0d instructions with %0d warnings", instrs, warningCount); \
|
||||
$stop;
|
||||
|
||||
logic [63:0] pcExpected;
|
||||
logic [63:0] regExpected;
|
||||
integer regNumExpected;
|
||||
@ -110,115 +144,195 @@ module testbench_busybear();
|
||||
genvar i;
|
||||
generate
|
||||
for(i=1; i<32; i++) begin
|
||||
always @(dut.ieu.dp.regf.rf[i]) begin
|
||||
if ($time != 0) begin
|
||||
always @(dut.hart.ieu.dp.regf.rf[i]) begin
|
||||
if ($time == 0) begin
|
||||
scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected);
|
||||
if (dut.hart.ieu.dp.regf.rf[i] != regExpected) begin
|
||||
$display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected);
|
||||
`ERROR
|
||||
end
|
||||
end else begin
|
||||
scan_file_rf = $fscanf(data_file_rf, "%d\n", regNumExpected);
|
||||
scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected);
|
||||
if (i != regNumExpected) begin
|
||||
$display("%t ps, instr %0d: wrong register changed: %0d, %0d expected", $time, instrs, i, regNumExpected);
|
||||
$display("%0t ps, instr %0d: wrong register changed: %0d, %0d expected", $time, instrs, i, regNumExpected);
|
||||
`ERROR
|
||||
end
|
||||
if (dut.ieu.dp.regf.rf[i] != regExpected) begin
|
||||
$display("%t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.ieu.dp.regf.rf[i], regExpected);
|
||||
if (~equal(dut.hart.ieu.dp.regf.rf[i],regExpected, 0)) begin
|
||||
$display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected);
|
||||
`ERROR
|
||||
end
|
||||
//if (dut.hart.ieu.dp.regf.rf[i] !== regExpected) begin
|
||||
// force dut.hart.ieu.dp.regf.rf[i] = regExpected;
|
||||
// release dut.hart.ieu.dp.regf.rf[i];
|
||||
//end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// RAM and bootram are addressed in 64-bit blocks - this logic handles R/W
|
||||
// including subwords. Brief explanation on signals:
|
||||
//
|
||||
// readMask: bitmask of bits to read / write, left-shifted to align with
|
||||
// nearest 64-bit boundary - examples
|
||||
// HSIZE = 0 -> readMask = 11111111
|
||||
// HSIZE = 1 -> readMask = 1111111111111111
|
||||
//
|
||||
// In the linux boot, the processor spends the first ~5 instructions in
|
||||
// bootram, before jr jumps to main RAM
|
||||
|
||||
logic [63:0] readMask;
|
||||
assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0];
|
||||
|
||||
logic [`XLEN-1:0] readAdrExpected;
|
||||
// this might need to change
|
||||
always @(dut.MemRWM[1] or HADDR) begin
|
||||
if (dut.MemRWM[1]) begin
|
||||
|
||||
always @(dut.hart.MemRWM[1] or HADDR or dut.HRDATA) begin
|
||||
if (dut.hart.MemRWM[1] && HADDR != dut.PCF && dut.HRDATA != {64{1'bx}}) begin
|
||||
if($feof(data_file_memR)) begin
|
||||
$display("no more memR data to read");
|
||||
$stop;
|
||||
`ERROR
|
||||
end
|
||||
scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected);
|
||||
scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA);
|
||||
#1;
|
||||
if (HADDR != readAdrExpected) begin
|
||||
$display("%t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected);
|
||||
#2;
|
||||
if (~equal(HADDR,readAdrExpected,4)) begin
|
||||
$display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected);
|
||||
`ERROR
|
||||
end
|
||||
|
||||
if (((readMask & HRDATA) !== (readMask & dut.HRDATA)) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin
|
||||
$display("warning %0t ps, instr %0d: ExpectedHRDATA does not equal dut.HRDATA: %x, %x from address %x, %x", $time, instrs, HRDATA, dut.HRDATA, HADDR, HSIZE);
|
||||
warningCount += 1;
|
||||
`ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
logic [`XLEN-1:0] writeDataExpected, writeAdrExpected;
|
||||
|
||||
// this might need to change
|
||||
always @(HWDATA or HADDR or HSIZE) begin
|
||||
#1;
|
||||
if (HWRITE) begin
|
||||
//always @(HWDATA or HADDR or HSIZE or HWRITE) begin
|
||||
always @(negedge HWRITE) begin
|
||||
//#1;
|
||||
if ($time != 0) begin
|
||||
if($feof(data_file_memW)) begin
|
||||
$display("no more memW data to read");
|
||||
$stop;
|
||||
`ERROR
|
||||
end
|
||||
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected);
|
||||
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected);
|
||||
if (writeDataExpected != HWDATA) begin
|
||||
$display("%t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected);
|
||||
$display("%0t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected);
|
||||
`ERROR
|
||||
end
|
||||
if (writeAdrExpected != HADDR) begin
|
||||
$display("%t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected);
|
||||
if (~equal(writeAdrExpected,HADDR,1)) begin
|
||||
$display("%0t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected);
|
||||
`ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
`define CHECK_CSR(CSR) \
|
||||
integer totalCSR = 0;
|
||||
logic [99:0] StartCSRexpected[63:0];
|
||||
string StartCSRname[99:0];
|
||||
initial begin
|
||||
while(1) begin
|
||||
scan_file_csr = $fscanf(data_file_csr, "%s\n", StartCSRname[totalCSR]);
|
||||
if(StartCSRname[totalCSR] == "---") begin
|
||||
break;
|
||||
end
|
||||
scan_file_csr = $fscanf(data_file_csr, "%x\n", StartCSRexpected[totalCSR]);
|
||||
totalCSR = totalCSR + 1;
|
||||
end
|
||||
end
|
||||
|
||||
`define CHECK_CSR2(CSR, PATH) \
|
||||
string CSR; \
|
||||
logic [63:0] expected``CSR``; \
|
||||
//CSR checking \
|
||||
always @(dut.priv.csr.``CSR``_REGW) begin \
|
||||
always @(``PATH``.``CSR``_REGW) begin \
|
||||
if ($time > 1) begin \
|
||||
scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \
|
||||
scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \
|
||||
if(CSR.icompare(`"CSR`")) begin \
|
||||
$display("%t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \
|
||||
$display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \
|
||||
end \
|
||||
if(dut.priv.csr.``CSR``_REGW != ``expected``CSR) begin \
|
||||
$display("%t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, CSR, CSR, dut.priv.csr.``CSR``_REGW, ``expected``CSR); \
|
||||
if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \
|
||||
$display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \
|
||||
`ERROR \
|
||||
end \
|
||||
end else begin \
|
||||
for(integer j=0; j<totalCSR; j++) begin \
|
||||
if(!StartCSRname[j].icompare(`"CSR`")) begin \
|
||||
if(``PATH``.``CSR``_REGW != StartCSRexpected[j]) begin \
|
||||
$display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", StartCSRname[j], ``PATH``.``CSR``_REGW, StartCSRexpected[j]); \
|
||||
`ERROR \
|
||||
end \
|
||||
end \
|
||||
end \
|
||||
end \
|
||||
end
|
||||
`define CHECK_CSR(CSR) \
|
||||
`CHECK_CSR2(CSR, dut.hart.priv.csr)
|
||||
`define CSRM dut.hart.priv.csr.genblk1.csrm
|
||||
`define CSRS dut.hart.priv.csr.genblk1.csrs.genblk1
|
||||
|
||||
//`CHECK_CSR(FCSR)
|
||||
`CHECK_CSR2(MCAUSE, `CSRM)
|
||||
`CHECK_CSR(MCOUNTEREN)
|
||||
`CHECK_CSR(MEDELEG)
|
||||
`CHECK_CSR(MEPC)
|
||||
//`CHECK_CSR(MHARTID)
|
||||
`CHECK_CSR(MIDELEG)
|
||||
`CHECK_CSR(MIE)
|
||||
//`CHECK_CSR(MSCRATCH)
|
||||
//`CHECK_CSR(MIP)
|
||||
`CHECK_CSR2(MISA, `CSRM)
|
||||
`CHECK_CSR2(MSCRATCH, `CSRM)
|
||||
`CHECK_CSR(MSTATUS)
|
||||
`CHECK_CSR2(MTVAL, `CSRM)
|
||||
`CHECK_CSR(MTVEC)
|
||||
//`CHECK_CSR(SATP)
|
||||
//`CHECK_CSR2(PMPADDR0, `CSRM)
|
||||
//`CHECK_CSR2(PMdut.PCFG0, `CSRM)
|
||||
`CHECK_CSR2(SATP, `CSRS)
|
||||
`CHECK_CSR2(SCAUSE, `CSRS)
|
||||
`CHECK_CSR(SCOUNTEREN)
|
||||
`CHECK_CSR(SEPC)
|
||||
`CHECK_CSR(SIE)
|
||||
`CHECK_CSR2(SSCRATCH, `CSRS)
|
||||
`CHECK_CSR(SSTATUS)
|
||||
`CHECK_CSR2(STVAL, `CSRS)
|
||||
`CHECK_CSR(STVEC)
|
||||
|
||||
logic speculative;
|
||||
initial begin
|
||||
speculative = 0;
|
||||
speculative = 0;
|
||||
end
|
||||
logic [63:0] lastInstrF, lastPC, lastPC2;
|
||||
logic [63:0] lastCheckInstrF, lastPC, lastPC2;
|
||||
|
||||
string PCtextW, PCtext2W;
|
||||
logic [31:0] InstrWExpected;
|
||||
logic [63:0] PCWExpected;
|
||||
always @(dut.ifu.PCW or dut.ieu.InstrValidW) begin
|
||||
if(dut.ieu.InstrValidW && dut.ifu.PCW != 0) begin
|
||||
always @(dut.hart.ifu.PCW or dut.hart.ieu.InstrValidW) begin
|
||||
if(dut.hart.ieu.InstrValidW && dut.hart.ifu.PCW != 0) begin
|
||||
if($feof(data_file_PCW)) begin
|
||||
$display("no more PC data to read");
|
||||
$stop;
|
||||
`ERROR
|
||||
end
|
||||
scan_file_PCW = $fscanf(data_file_PCW, "%s\n", PCtextW);
|
||||
if (PCtextW != "ret") begin
|
||||
if (PCtextW != "ret" && PCtextW != "fence" && PCtextW != "nop" && PCtextW != "mret" && PCtextW != "sfence.vma" && PCtextW != "unimp") begin
|
||||
scan_file_PC = $fscanf(data_file_PCW, "%s\n", PCtext2W);
|
||||
PCtextW = {PCtextW, " ", PCtext2W};
|
||||
end
|
||||
scan_file_PCW = $fscanf(data_file_PCW, "%x\n", InstrWExpected);
|
||||
// then expected PC value
|
||||
scan_file_PCW = $fscanf(data_file_PCW, "%x\n", PCWExpected);
|
||||
if(dut.ifu.PCW != PCWExpected) begin
|
||||
$display("%t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.ifu.PCW, PCWExpected);
|
||||
if(~equal(dut.hart.ifu.PCW,PCWExpected,2)) begin
|
||||
$display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.hart.ifu.PCW, PCWExpected);
|
||||
`ERROR
|
||||
end
|
||||
//if(it.InstrW != InstrWExpected) begin
|
||||
// $display("%t ps, instr %0d: InstrW does not equal InstrW expected: %x, %x", $time, instrs, it.InstrW, InstrWExpected);
|
||||
// $display("%0t ps, instr %0d: InstrW does not equal InstrW expected: %x, %x", $time, instrs, it.InstrW, InstrWExpected);
|
||||
//end
|
||||
end
|
||||
end
|
||||
@ -227,72 +341,139 @@ module testbench_busybear();
|
||||
integer instrs;
|
||||
initial begin
|
||||
instrs = 0;
|
||||
end
|
||||
always @(PCF) begin
|
||||
lastInstrF = InstrF;
|
||||
lastPC <= PCF;
|
||||
lastPC2 <= lastPC;
|
||||
if (speculative && lastPC != pcExpected) begin
|
||||
speculative = (PCF != pcExpected);
|
||||
end
|
||||
else begin
|
||||
//if (~speculative) begin
|
||||
if($feof(data_file_PC)) begin
|
||||
$display("no more PC data to read");
|
||||
$stop;
|
||||
end
|
||||
// first read instruction
|
||||
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext);
|
||||
if (PCtext != "ret") begin
|
||||
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2);
|
||||
PCtext = {PCtext, " ", PCtext2};
|
||||
end
|
||||
scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF);
|
||||
if(InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
|
||||
InstrF = 32'b0010011;
|
||||
$display("warning: NOPing out %s at PC=%0x", PCtext, PCF);
|
||||
end
|
||||
// then expected PC value
|
||||
scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected);
|
||||
if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) ||
|
||||
(instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) ||
|
||||
(instrs <= 100000 && instrs % 10000 == 0)) begin
|
||||
$display("loaded %0d instructions", instrs);
|
||||
end
|
||||
instrs += 1;
|
||||
// are we at a branch/jump?
|
||||
casex (lastInstrF[15:0])
|
||||
16'bXXXXXXXXX1101111, // JAL
|
||||
16'bXXXXXXXXX1100111, // JALR
|
||||
16'bXXXXXXXXX1100011, // B
|
||||
16'b110XXXXXXXXXXX01, // C.BEQZ
|
||||
16'b111XXXXXXXXXXX01, // C.BNEZ
|
||||
16'b101XXXXXXXXXXX01: // C.J
|
||||
speculative = 1;
|
||||
16'b1001000000000010: // C.EBREAK:
|
||||
speculative = 0; // tbh don't really know what should happen here
|
||||
16'b1000XXXXX0000010, // C.JR
|
||||
16'b1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
|
||||
speculative = 1;
|
||||
default:
|
||||
speculative = 0;
|
||||
endcase
|
||||
end
|
||||
logic [31:0] InstrMask;
|
||||
logic forcedInstr;
|
||||
logic [63:0] lastPCF;
|
||||
always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin
|
||||
if(~HWRITE) begin
|
||||
#3;
|
||||
if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin
|
||||
if (dut.PCF !== lastPCF) begin
|
||||
lastCheckInstrF = CheckInstrF;
|
||||
lastPC <= dut.PCF;
|
||||
lastPC2 <= lastPC;
|
||||
if (speculative && (lastPC != pcExpected)) begin
|
||||
speculative = ~equal(dut.PCF,pcExpected,3);
|
||||
if(dut.PCF===pcExpected) begin
|
||||
if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
|
||||
force CheckInstrF = 32'b0010011;
|
||||
release CheckInstrF;
|
||||
force dut.hart.ifu.InstrF = 32'b0010011;
|
||||
#7;
|
||||
release dut.hart.ifu.InstrF;
|
||||
$display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time);
|
||||
warningCount += 1;
|
||||
forcedInstr = 1;
|
||||
end
|
||||
else begin
|
||||
if(dut.hart.ifu.InstrF[28:27] != 2'b11 && dut.hart.ifu.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD
|
||||
force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011};
|
||||
release CheckInstrF;
|
||||
force dut.hart.ifu.InstrF = {12'b0, dut.hart.ifu.InstrF[19:7], 7'b0000011};
|
||||
#7;
|
||||
release dut.hart.ifu.InstrF;
|
||||
$display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF);
|
||||
warningCount += 1;
|
||||
forcedInstr = 1;
|
||||
end
|
||||
else begin
|
||||
forcedInstr = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if($feof(data_file_PC)) begin
|
||||
$display("no more PC data to read");
|
||||
`ERROR
|
||||
end
|
||||
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext);
|
||||
if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin
|
||||
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2);
|
||||
PCtext = {PCtext, " ", PCtext2};
|
||||
end
|
||||
scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF);
|
||||
if(dut.PCF === pcExpected) begin
|
||||
if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
|
||||
force CheckInstrF = 32'b0010011;
|
||||
release CheckInstrF;
|
||||
force dut.hart.ifu.InstrF = 32'b0010011;
|
||||
#7;
|
||||
release dut.hart.ifu.InstrF;
|
||||
$display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time);
|
||||
warningCount += 1;
|
||||
forcedInstr = 1;
|
||||
end
|
||||
else begin
|
||||
if(dut.hart.ifu.InstrF[28:27] != 2'b11 && dut.hart.ifu.InstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD
|
||||
force CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011};
|
||||
release CheckInstrF;
|
||||
force dut.hart.ifu.InstrF = {12'b0, dut.hart.ifu.InstrF[19:7], 7'b0000011};
|
||||
#7;
|
||||
release dut.hart.ifu.InstrF;
|
||||
$display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF);
|
||||
warningCount += 1;
|
||||
forcedInstr = 1;
|
||||
end
|
||||
else begin
|
||||
forcedInstr = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
// then expected PC value
|
||||
scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected);
|
||||
if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) ||
|
||||
(instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) ||
|
||||
(instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin
|
||||
$display("loaded %0d instructions", instrs);
|
||||
end
|
||||
instrs += 1;
|
||||
// are we at a branch/jump?
|
||||
casex (lastCheckInstrF[31:0])
|
||||
32'b00000000001000000000000001110011, // URET
|
||||
32'b00010000001000000000000001110011, // SRET
|
||||
32'b00110000001000000000000001110011, // MRET
|
||||
32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL
|
||||
32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR
|
||||
32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B
|
||||
32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ
|
||||
32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ
|
||||
32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J
|
||||
speculative = 1;
|
||||
32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK:
|
||||
speculative = 0; // tbh don't really know what should happen here
|
||||
32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR
|
||||
32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
|
||||
speculative = 1;
|
||||
default:
|
||||
speculative = 0;
|
||||
endcase
|
||||
|
||||
//check things!
|
||||
if ((~speculative) && (PCF !== pcExpected)) begin
|
||||
$display("%t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, PCF, pcExpected);
|
||||
// $stop;
|
||||
//check things!
|
||||
if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin
|
||||
$display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected);
|
||||
`ERROR
|
||||
end
|
||||
InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF;
|
||||
if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrF) !== (InstrMask & CheckInstrF))) begin
|
||||
$display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrF, CheckInstrF, dut.PCF);
|
||||
`ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
lastPCF = dut.PCF;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Track names of instructions
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
logic [31:0] InstrW;
|
||||
instrNameDecTB dec(InstrF, InstrFName);
|
||||
instrTrackerTB it(clk, reset, dut.ieu.dp.FlushE,
|
||||
dut.ifu.InstrD, dut.ifu.InstrE,
|
||||
dut.ifu.InstrM, InstrW,
|
||||
instrNameDecTB dec(dut.hart.ifu.InstrF, InstrFName);
|
||||
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
||||
dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
|
||||
dut.hart.ifu.InstrM, InstrW,
|
||||
InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// generate clock to sequence tests
|
||||
@ -301,17 +482,4 @@ module testbench_busybear();
|
||||
clk <= 1; # 5; clk <= 0; # 5;
|
||||
end
|
||||
|
||||
//// check results
|
||||
//always @(negedge clk)
|
||||
// begin
|
||||
// if(MemWrite) begin
|
||||
// if(DataAdr === 84 & WriteData === 71) begin
|
||||
// $display("Simulation succeeded");
|
||||
// $stop;
|
||||
// end else if (DataAdr !== 80) begin
|
||||
// $display("Simulation failed");
|
||||
// $stop;
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
endmodule
|
||||
|
@ -37,6 +37,9 @@ module testbench();
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
//logic [31:0] InstrW;
|
||||
logic [`XLEN-1:0] meminit;
|
||||
string tests64a[] = '{
|
||||
"rv64a/WALLY-LRSC", "2110"
|
||||
};
|
||||
string tests64m[] = '{
|
||||
"rv64m/I-MUL-01", "3000",
|
||||
"rv64m/I-MULH-01", "3000",
|
||||
@ -321,9 +324,11 @@ string tests32i[] = {
|
||||
initial
|
||||
if (`XLEN == 64) begin // RV64
|
||||
tests = {tests64i};
|
||||
if (`C_SUPPORTED % 2 == 1) tests = {tests64ic, tests};
|
||||
else tests = {tests, tests64iNOc};
|
||||
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m};
|
||||
if (`C_SUPPORTED) tests = {tests64ic, tests};
|
||||
else tests = {tests, tests64iNOc};
|
||||
if (`M_SUPPORTED) tests = {tests, tests64m};
|
||||
if (`A_SUPPORTED) tests = {tests64a, tests};
|
||||
// tests = {tests64a, tests};
|
||||
end else begin // RV32
|
||||
tests = {tests32i};
|
||||
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
|
||||
@ -367,7 +372,8 @@ string tests32i[] = {
|
||||
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||
$readmemh(memfilename, dut.imem.RAM);
|
||||
$readmemh(memfilename, dut.uncore.dtim.RAM);
|
||||
reset = 1; # 22; reset = 0;
|
||||
$display("Read memfile %s", memfilename);
|
||||
reset = 1; # 42; reset = 0;
|
||||
end
|
||||
|
||||
// generate clock to sequence tests
|
||||
@ -406,9 +412,9 @@ string tests32i[] = {
|
||||
i = 0;
|
||||
errors = 0;
|
||||
if (`XLEN == 32)
|
||||
testadr = tests[test+1].atohex()/4;
|
||||
testadr = (`TIMBASE+tests[test+1].atohex())/4;
|
||||
else
|
||||
testadr = tests[test+1].atohex()/8;
|
||||
testadr = (`TIMBASE+tests[test+1].atohex())/8;
|
||||
/* verilator lint_off INFINITELOOP */
|
||||
while (signature[i] !== 'bx) begin
|
||||
//$display("signature[%h] = %h", i, signature[i]);
|
||||
@ -443,7 +449,11 @@ string tests32i[] = {
|
||||
reset = 1; # 17; reset = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // always @ (negedge clk)
|
||||
|
||||
// track the current function or label
|
||||
//function_rfunction_radix function_radix();
|
||||
|
||||
endmodule
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
@ -579,6 +589,30 @@ module instrNameDecTB(
|
||||
10'b1110011_101: name = "CSRRWI";
|
||||
10'b1110011_110: name = "CSRRSI";
|
||||
10'b1110011_111: name = "CSRRCI";
|
||||
10'b0101111_010: if (funct7[6:2] == 5'b00010) name = "LR.W";
|
||||
else if (funct7[6:2] == 5'b00011) name = "SC.W";
|
||||
else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.W";
|
||||
else if (funct7[6:2] == 5'b00000) name = "AMOADD.W";
|
||||
else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.W";
|
||||
else if (funct7[6:2] == 5'b01100) name = "AMOAND.W";
|
||||
else if (funct7[6:2] == 5'b01000) name = "AMOOR.W";
|
||||
else if (funct7[6:2] == 5'b10000) name = "AMOMIN.W";
|
||||
else if (funct7[6:2] == 5'b10100) name = "AMOMAX.W";
|
||||
else if (funct7[6:2] == 5'b11000) name = "AMOMINU.W";
|
||||
else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.W";
|
||||
else name = "ILLEGAL";
|
||||
10'b0101111_011: if (funct7[6:2] == 5'b00010) name = "LR.D";
|
||||
else if (funct7[6:2] == 5'b00011) name = "SC.D";
|
||||
else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.D";
|
||||
else if (funct7[6:2] == 5'b00000) name = "AMOADD.D";
|
||||
else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.D";
|
||||
else if (funct7[6:2] == 5'b01100) name = "AMOAND.D";
|
||||
else if (funct7[6:2] == 5'b01000) name = "AMOOR.D";
|
||||
else if (funct7[6:2] == 5'b10000) name = "AMOMIN.D";
|
||||
else if (funct7[6:2] == 5'b10100) name = "AMOMAX.D";
|
||||
else if (funct7[6:2] == 5'b11000) name = "AMOMINU.D";
|
||||
else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.D";
|
||||
else name = "ILLEGAL";
|
||||
10'b0001111_???: name = "FENCE";
|
||||
default: name = "ILLEGAL";
|
||||
endcase
|
||||
|
@ -136,9 +136,9 @@ module testbench();
|
||||
i = 0;
|
||||
errors = 0;
|
||||
if (`XLEN == 32)
|
||||
testadr = tests[test+1].atohex()/4;
|
||||
testadr = (`TIMBASE+tests[test+1].atohex())/4;
|
||||
else
|
||||
testadr = tests[test+1].atohex()/8;
|
||||
testadr = (`TIMBASE+tests[test+1].atohex())/8;
|
||||
/* verilator lint_off INFINITELOOP */
|
||||
while (signature[i] !== 'bx) begin
|
||||
//$display("signature[%h] = %h", i, signature[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user