mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
d6bc34121f
@ -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
|
||||
|
||||
|
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.do
|
||||
!
|
@ -27,12 +27,13 @@ vlib work-busybear
|
||||
# "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
|
||||
|
||||
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/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||
@ -41,6 +42,15 @@ switch $argc {
|
||||
1 {mem load -infile ../config/$1/BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory}
|
||||
}
|
||||
|
||||
mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/bootdtim/RAM
|
||||
mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/uncore/bootdtim/RAM
|
||||
mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/bootram
|
||||
mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/imem/bootram
|
||||
mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/dtim/RAM
|
||||
mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/uncore/dtim/RAM
|
||||
mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/RAM
|
||||
mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/imem/RAM
|
||||
|
||||
|
||||
view wave
|
||||
|
||||
@ -51,80 +61,104 @@ 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/InstrF
|
||||
add wave /testbench_busybear/CheckInstrF
|
||||
add wave /testbench_busybear/lastCheckInstrF
|
||||
add wave /testbench_busybear/speculative
|
||||
add wave /testbench_busybear/lastPC2
|
||||
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 -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/ifu/PCD
|
||||
#add wave -hex /testbench_busybear/dut/ifu/InstrD
|
||||
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/ifu/PCE
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrE
|
||||
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/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 -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/ifu/PCM
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrM
|
||||
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/dmem/dtim/memwrite
|
||||
#add wave -hex /testbench_busybear/dut/dmem/AdrM
|
||||
#add wave -hex /testbench_busybear/dut/dmem/WriteDataM
|
||||
#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/ifu/PCW
|
||||
##add wave -hex /testbench_busybear/dut/ifu/InstrW
|
||||
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/ieu/dp/RegWriteW
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/ResultW
|
||||
#add wave -hex /testbench_busybear/dut/ieu/dp/RdW
|
||||
#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/*
|
||||
add wave -hex -r /testbench_busybear/*
|
||||
#
|
||||
#-- Set Wave Output Items
|
||||
#TreeUpdate [SetDefaultTree]
|
||||
@ -140,6 +174,5 @@ add wave /testbench_busybear/InstrWName
|
||||
#set DefaultRadix hexadecimal
|
||||
#
|
||||
#-- Run the Simulation
|
||||
run 1483850
|
||||
#run -all
|
||||
run -all
|
||||
##quit
|
||||
|
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
|
@ -47,70 +47,4 @@ switch $argc {
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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,8 +26,13 @@ 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 +acc=+/testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory +acc=+/testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory work.testbench -o workopt
|
||||
@ -40,8 +44,6 @@ mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/Di
|
||||
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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,116 @@ 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
|
||||
|
||||
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 +136,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) begin
|
||||
if (dut.hart.MemRWM[1] && HADDR != dut.PCF) 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: HRDATA 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 +333,102 @@ 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}}) begin
|
||||
if (dut.PCF !== lastPCF) begin
|
||||
lastCheckInstrF = CheckInstrF;
|
||||
lastPC <= dut.PCF;
|
||||
lastPC2 <= lastPC;
|
||||
if (speculative && (lastPC != pcExpected)) begin
|
||||
speculative = ~equal(dut.PCF,pcExpected,3);
|
||||
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(CheckInstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
|
||||
CheckInstrF = 32'b0010011;
|
||||
$display("warning: NOPing out %s at PC=%0x", PCtext, dut.PCF);
|
||||
warningCount += 1;
|
||||
forcedInstr = 1;
|
||||
end
|
||||
else begin
|
||||
if(CheckInstrF[28:27] != 2'b11 && CheckInstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD
|
||||
CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011};
|
||||
$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
|
||||
// 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 +437,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
|
||||
|
@ -407,9 +407,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]);
|
||||
|
@ -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