Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

Conflicts:
	wally-pipelined/src/ebu/ahblite.sv
This commit is contained in:
Thomas Fleming 2021-03-11 00:15:58 -05:00
commit e57b6cf18c
27 changed files with 5554 additions and 1223 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,8 @@
// RV32 or RV64: XLEN = 32 or 64 // RV32 or RV64: XLEN = 32 or 64
`define XLEN 64 `define XLEN 64
//`define MISA (32'h00000104) //`define MISA (32'h00000105)
`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12) `define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0)
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1)

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@ def test_config(config, print_res=True):
passed = search_log_for_text("no more .* to read", logname) passed = search_log_for_text("no more .* to read", logname)
else: else:
cmd = "vsim -c >" + logname +" <<!\ndo wally-pipelined-batch-parallel.do ../config/" + config + " " + config + "\n!\n" cmd = "vsim -c >" + logname +" <<!\ndo wally-pipelined-batch-parallel.do ../config/" + config + " " + config + "\n!\n"
print(cmd)
os.system(cmd) os.system(cmd)
# check for success. grep returns 0 if found, 1 if not found # check for success. grep returns 0 if found, 1 if not found
passed = search_log_for_text("All tests ran without failures", logname) passed = search_log_for_text("All tests ran without failures", logname)

View File

@ -1,3 +1,3 @@
vsim -c <<! vsim -c <<!
do wally-busybear.do do wally-busybear-batch.do
! !

View 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

View File

@ -1,76 +1,74 @@
# wally-pipelined.do # wally-pipelined.do
# #
# Modification by Oklahoma State University & Harvey Mudd College # Modification by Oklahoma State University & Harvey Mudd College
# Use with testbench_busybear # Use with testbench_busybear
# James Stine, 2008; David Harris 2021 # James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!! # Go Cowboys!!!!!!
# #
# Takes 1:10 to run RV64IC tests using gui # Takes 1:10 to run RV64IC tests using gui
# Use this wally-pipelined.do file to run this example. # Use this wally-pipelined.do file to run this example.
# Either bring up ModelSim and type the following at the "ModelSim>" prompt: # Either bring up ModelSim and type the following at the "ModelSim>" prompt:
# do wally-pipelined.do # do wally-pipelined.do
# or, to run from a shell, type the following at the shell prompt: # or, to run from a shell, type the following at the shell prompt:
# vsim -do wally-pipelined.do -c # vsim -do wally-pipelined.do -c
# (omit the "-c" to see the GUI while running from the shell) # (omit the "-c" to see the GUI while running from the shell)
onbreak {resume} onbreak {resume}
# create library # create library
if [file exists work-busybear] { if [file exists work-busybear] {
vdel -all -lib work-busybear vdel -all -lib work-busybear
} }
vlib work-busybear vlib work-busybear
# compile source files # compile source files
# suppress spurious warnngs about # suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time" # "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt # because vsim will run vopt
vlog +incdir+../config/busybear ../testbench/*.sv ../src/*/*.sv -suppress 2583 vlog +incdir+../config/busybear ../testbench/*.sv ../src/*/*.sv -suppress 2583
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt +acc work.testbench_busybear -o workopt vopt +acc work.testbench_busybear -o workopt
vsim workopt -suppress 8852,12070 vsim workopt -suppress 8852,12070
# load the branch predictors with known data. The value of the data is not important for function, but # 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. # is important for perventing pessimistic x propagation.
mem load -infile twoBitPredictor.txt -format bin /testbench_busybear/dut/hart/ifu/bpred/DirPredictor/memory/memory mem load -infile twoBitPredictor.txt -format bin testbench_busybear/dut/hart/ifu/bpred/DirPredictor/memory/memory
mem load -infile BTBPredictor.txt -format bin /testbench_busybear/dut/hart/ifu/bpred/TargetPredictor/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}
}
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 view wave
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 -- display input and output signals as hexidecimal values
mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/dtim/RAM # Diplays All Signals recursively
mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/uncore/dtim/RAM add wave /testbench_busybear/clk
mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/RAM add wave /testbench_busybear/reset
mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/imem/RAM add wave -divider
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/PCtext
add wave -hex /testbench_busybear/pcExpected add wave -hex /testbench_busybear/pcExpected
add wave -hex /testbench_busybear/dut/hart/ifu/PCF 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/InstrF
add wave -hex /testbench_busybear/dut/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/CheckInstrF
add wave /testbench_busybear/lastCheckInstrF add wave /testbench_busybear/lastCheckInstrF
add wave /testbench_busybear/speculative add wave /testbench_busybear/speculative
add wave /testbench_busybear/lastPC2 add wave /testbench_busybear/lastPC2
add wave -divider add wave -divider
add wave -divider add wave -divider
add wave /testbench_busybear/dut/uncore/HSELBootTim add wave /testbench_busybear/dut/uncore/HSELBootTim
add wave /testbench_busybear/dut/uncore/HSELTim add wave /testbench_busybear/dut/uncore/HSELTim
add wave /testbench_busybear/dut/uncore/HREADTim add wave /testbench_busybear/dut/uncore/HREADTim
add wave /testbench_busybear/dut/uncore/dtim/HREADTim0 add wave /testbench_busybear/dut/uncore/dtim/HREADTim0
add wave /testbench_busybear/dut/uncore/HREADYTim add wave /testbench_busybear/dut/uncore/HREADYTim
add wave -divider add wave -divider
add wave /testbench_busybear/dut/uncore/HREADBootTim add wave /testbench_busybear/dut/uncore/HREADBootTim
add wave /testbench_busybear/dut/uncore/bootdtim/HREADTim0 add wave /testbench_busybear/dut/uncore/bootdtim/HREADTim0
add wave /testbench_busybear/dut/uncore/HREADYBootTim add wave /testbench_busybear/dut/uncore/HREADYBootTim
@ -84,8 +82,8 @@ add wave /testbench_busybear/dut/uncore/HRDATA
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MIE_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/MIDELEG_REG
#add wave -hex /testbench_busybear/dut/hart/priv/csr/MEDELEG_REG #add wave -hex /testbench_busybear/dut/hart/priv/csr/MEDELEG_REG
add wave -divider add wave -divider
# registers! # registers!
add wave -hex /testbench_busybear/regExpected add wave -hex /testbench_busybear/regExpected
add wave -hex /testbench_busybear/regNumExpected add wave -hex /testbench_busybear/regNumExpected
add wave -hex /testbench_busybear/HWRITE add wave -hex /testbench_busybear/HWRITE
@ -125,49 +123,49 @@ 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[29]
add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[30] 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 -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[31]
add wave /testbench_busybear/InstrFName add wave /testbench_busybear/InstrFName
add wave -hex /testbench_busybear/dut/hart/ifu/PCD add wave -hex /testbench_busybear/dut/hart/ifu/PCD
#add wave -hex /testbench_busybear/dut/hart/ifu/InstrD #add wave -hex /testbench_busybear/dut/hart/ifu/InstrD
add wave /testbench_busybear/InstrDName add wave /testbench_busybear/InstrDName
#add wave -divider #add wave -divider
add wave -hex /testbench_busybear/dut/hart/ifu/PCE add wave -hex /testbench_busybear/dut/hart/ifu/PCE
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrE ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrE
add wave /testbench_busybear/InstrEName add wave /testbench_busybear/InstrEName
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/SrcAE #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/SrcBE
add wave -hex /testbench_busybear/dut/hart/ieu/dp/ALUResultE add wave -hex /testbench_busybear/dut/hart/ieu/dp/ALUResultE
#add wave /testbench_busybear/dut/hart/ieu/dp/PCSrcE #add wave /testbench_busybear/dut/hart/ieu/dp/PCSrcE
#add wave -divider #add wave -divider
add wave -hex /testbench_busybear/dut/hart/ifu/PCM add wave -hex /testbench_busybear/dut/hart/ifu/PCM
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrM ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrM
add wave /testbench_busybear/InstrMName add wave /testbench_busybear/InstrMName
#add wave /testbench_busybear/dut/hart/dmem/dtim/memwrite #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/AdrM
#add wave -hex /testbench_busybear/dut/hart/dmem/WriteDataM #add wave -hex /testbench_busybear/dut/hart/dmem/WriteDataM
#add wave -divider #add wave -divider
add wave -hex /testbench_busybear/dut/hart/ifu/PCW add wave -hex /testbench_busybear/dut/hart/ifu/PCW
##add wave -hex /testbench_busybear/dut/hart/ifu/InstrW ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrW
add wave /testbench_busybear/InstrWName add wave /testbench_busybear/InstrWName
#add wave /testbench_busybear/dut/hart/ieu/dp/RegWriteW #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/ResultW
#add wave -hex /testbench_busybear/dut/hart/ieu/dp/RdW #add wave -hex /testbench_busybear/dut/hart/ieu/dp/RdW
#add wave -divider #add wave -divider
##add ww ##add ww
add wave -hex -r /testbench_busybear/* add wave -hex -r /testbench_busybear/*
# #
#-- Set Wave Output Items #-- Set Wave Output Items
#TreeUpdate [SetDefaultTree] #TreeUpdate [SetDefaultTree]
#WaveRestoreZoom {0 ps} {100 ps} #WaveRestoreZoom {0 ps} {100 ps}
#configure wave -namecolwidth 250 #configure wave -namecolwidth 250
#configure wave -valuecolwidth 120 #configure wave -valuecolwidth 120
#configure wave -justifyvalue left #configure wave -justifyvalue left
#configure wave -signalnamewidth 0 #configure wave -signalnamewidth 0
#configure wave -snapdistance 10 #configure wave -snapdistance 10
#configure wave -datasetprefix 0 #configure wave -datasetprefix 0
#configure wave -rowmargin 4 #configure wave -rowmargin 4
#configure wave -childrowmargin 2 #configure wave -childrowmargin 2
#set DefaultRadix hexadecimal #set DefaultRadix hexadecimal
# #
#-- Run the Simulation #-- Run the Simulation
run -all run -all
##quit ##quit

View File

@ -35,6 +35,14 @@ vlog +incdir+../config/coremark ../testbench/testbench-coremark.sv ../src/*/*.sv
vopt +acc work.testbench -o workopt vopt +acc work.testbench -o workopt
vsim 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 view wave
-- display input and output signals as hexidecimal values -- display input and output signals as hexidecimal values

View File

@ -38,5 +38,13 @@ switch $argc {
vopt +acc work.testbench -o workopt vopt +acc work.testbench -o workopt
vsim 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 view wave
do wally-peripherals-signals.do do wally-peripherals-signals.do

View File

@ -34,5 +34,10 @@ vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583
vopt work.testbench -o workopt vopt work.testbench -o workopt
vsim 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 run -all
quit quit

View File

@ -35,13 +35,16 @@ switch $argc {
} }
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt +acc 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 vsim workopt
# load the branch predictors with known data. The value of the data is not important for function, but # 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. # 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 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 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 run -all
quit quit

View File

@ -41,7 +41,10 @@ vsim workopt
# load the branch predictors with known data. The value of the data is not important for function, but # 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. # 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 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 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 do wave.do
add log -r /* add log -r /*

View File

@ -41,7 +41,10 @@ vsim workopt
# load the branch predictors with known data. The value of the data is not important for function, but # 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. # 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 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 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 view wave
@ -110,6 +113,6 @@ configure wave -childrowmargin 2
set DefaultRadix hexadecimal set DefaultRadix hexadecimal
-- Run the Simulation -- Run the Simulation
#run 2000 #run 4100
run -all run -all
#quit #quit

View File

@ -37,7 +37,7 @@ module dmem (
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
//input logic [`XLEN-1:0] ReadDataW, //input logic [`XLEN-1:0] ReadDataW,
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
input logic AtomicM, input logic [1:0] AtomicM,
output logic [`XLEN-1:0] MemPAdrM, output logic [`XLEN-1:0] MemPAdrM,
output logic MemReadM, MemWriteM, output logic MemReadM, MemWriteM,
output logic DataMisalignedM, output logic DataMisalignedM,
@ -92,9 +92,9 @@ module dmem (
logic ReservationValidM, ReservationValidW; logic ReservationValidM, ReservationValidW;
logic lrM, scM, WriteAdrMatchM; logic lrM, scM, WriteAdrMatchM;
assign lrM = MemReadM && AtomicM; assign lrM = MemReadM && AtomicM[0];
assign scM = MemRWM[0] && AtomicM; assign scM = MemRWM[0] && AtomicM[0];
assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM == ReservationPAdrW) && ReservationValidW; assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM[`XLEN-1:2] == ReservationPAdrW) && ReservationValidW;
assign SquashSCM = scM && ~WriteAdrMatchM; assign SquashSCM = scM && ~WriteAdrMatchM;
always_comb begin // ReservationValidM (next valiue of valid reservation) always_comb begin // ReservationValidM (next valiue of valid reservation)
if (lrM) ReservationValidM = 1; // set valid on load reserve if (lrM) ReservationValidM = 1; // set valid on load reserve

View File

@ -35,6 +35,8 @@ module ahblite (
input logic StallW, FlushW, input logic StallW, FlushW,
// Load control // Load control
input logic UnsignedLoadM, input logic UnsignedLoadM,
input logic [1:0] AtomicM,
input logic [6:0] Funct7M,
// Signals from Instruction Cache // Signals from Instruction Cache
input logic [`XLEN-1:0] InstrPAdrF, // *** rename these to match block diagram input logic [`XLEN-1:0] InstrPAdrF, // *** rename these to match block diagram
input logic InstrReadF, input logic InstrReadF,
@ -71,7 +73,7 @@ module ahblite (
logic GrantData; logic GrantData;
logic [2:0] ISize; logic [2:0] ISize;
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, ReadDataPreW, WriteData;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM; logic CaptureDataM;
@ -84,19 +86,23 @@ module ahblite (
// Data accesses have priority over instructions. However, if a data access comes // Data accesses have priority over instructions. However, if a data access comes
// while an instruction read is occuring, the instruction read finishes before // while an instruction read is occuring, the instruction read finishes before
// the data access can take place. // the data access can take place.
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADMEMPENDING} statetype; typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADMEMPENDING, ATOMICREAD, ATOMICWRITE} statetype;
statetype BusState, NextBusState; statetype BusState, NextBusState;
always_ff @(posedge HCLK, negedge HRESETn) flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
if (~HRESETn) BusState <= #1 IDLE;
else BusState <= #1 NextBusState;
always_comb always_comb
case (BusState) case (BusState)
IDLE: if (MemReadM) NextBusState = MEMREAD; // Memory has priority over instructions IDLE: if (AtomicM[1]) NextBusState = ATOMICREAD;
else if (MemReadM) NextBusState = MEMREAD; // Memory has pirority over instructions
else if (MemWriteM) NextBusState = MEMWRITE; else if (MemWriteM) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
else NextBusState = ATOMICWRITE;
ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD; MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
@ -105,24 +111,21 @@ module ahblite (
else NextBusState = IDLE; else NextBusState = IDLE;
INSTRREAD: //if (~HREADY & (MemReadM | MemWriteM)) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete INSTRREAD: //if (~HREADY & (MemReadM | MemWriteM)) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete
if (~HREADY) NextBusState = INSTRREAD; if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE; // if (InstrReadF still high)
INSTRREADMEMPENDING: if (~HREADY) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete INSTRREADMEMPENDING: if (~HREADY) NextBusState = INSTRREADMEMPENDING; // *** shouldn't happen, delete
else if (MemReadM) NextBusState = MEMREAD; else if (MemReadM) NextBusState = MEMREAD;
else NextBusState = MEMWRITE; // must be write if not a read. Don't return to idle. else NextBusState = MEMWRITE; // must be write if not a read. Don't return to idle.
endcase endcase
// stall signals // stall signals
assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) || (NextBusState == INSTRREADMEMPENDING); assign #2 DataStall = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
(NextBusState == INSTRREADMEMPENDING);
assign #1 InstrStall = (NextBusState == INSTRREAD); assign #1 InstrStall = (NextBusState == INSTRREAD);
// DH 2/20/22: A cyclic path presently exists
// HREADY->NextBusState->GrantData->HSIZE->HSELUART->HREADY
// This is because the peripherals assert HREADY on the same cycle
// When memory is working, also fix the peripherals to respond on the subsequent cycle
// and this path should be fixed.
// bus outputs // bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE); assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; assign #1 HADDR = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0];
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize; assign #1 HSIZE = GrantData ? {1'b0, MemSizeM} : ISize;
@ -130,9 +133,9 @@ module ahblite (
assign HPROT = 4'b0011; // not used; see Section 3.7 assign HPROT = 4'b0011; // not used; see Section 3.7
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
assign HMASTLOCK = 0; // no locking supported assign HMASTLOCK = 0; // no locking supported
assign HWRITE = (NextBusState == MEMWRITE); assign HWRITE = (NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE);
// delay write data by one cycle for // delay write data by one cycle for
flop #(`XLEN) wdreg(HCLK, WriteDataM, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN flop #(`XLEN) wdreg(HCLK, WriteData, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
// delay signals for subword writes // delay signals for subword writes
flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD); flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD);
flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED); flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED);
@ -143,11 +146,24 @@ module ahblite (
assign InstrRData = HRDATA; assign InstrRData = HRDATA;
assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021 assign ReadDataM = HRDATAMasked; // changed from W to M dh 2/7/2021
assign CaptureDataM = (BusState == MEMREAD) && (NextBusState != MEMREAD); assign CaptureDataM = ((BusState == MEMREAD) && (NextBusState != MEMREAD)) ||
((BusState == ATOMICREAD) && (NextBusState == ATOMICWRITE));
// *** check if this introduces an unnecessary cycle of latency in memory accesses
flopenr #(`XLEN) ReadDataPreWReg(clk, reset, CaptureDataM, ReadDataM, ReadDataPreW); // *** this may break when there is no instruction read after data read flopenr #(`XLEN) ReadDataPreWReg(clk, reset, CaptureDataM, ReadDataM, ReadDataPreW); // *** this may break when there is no instruction read after data read
flopenr #(`XLEN) ReadDataWReg(clk, reset, ~StallW, ReadDataPreW, ReadDataW); flopenr #(`XLEN) ReadDataWReg(clk, reset, ~StallW, ReadDataPreW, ReadDataW);
// Extract and sign-extend subwords if necessary
subwordread swr(.*); subwordread swr(.*);
endmodule // Handle AMO instructions if applicable
generate
if (`A_SUPPORTED) begin
logic [`XLEN-1:0] AMOResult;
amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM),
.result(AMOResult));
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicM[1], WriteData);
end else
assign WriteData = WriteDataM;
endgenerate
endmodule

View File

@ -0,0 +1,66 @@
///////////////////////////////////////////
// amoalu.sv
//
// Written: David_Harris@hmc.edu 10 March 2021
// Modified:
//
// Purpose: Performs AMO operations
//
// 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 amoalu (
input logic [`XLEN-1:0] a, b,
input logic [6:0] funct,
input logic [1:0] width,
output logic [`XLEN-1:0] result);
logic [`XLEN-1:0] y;
// *** see how synthesis generates this and optimize more structurally if necessary to share hardware
// a single carry chain should be shared for + and the four min/max
// and the same mux can be used to select b for swap.
always_comb
case (funct[6:2])
5'b00001: y = b; // amoswap
5'b00000: y = a + b; // amoadd
5'b00100: y = a ^ b; // amoxor
5'b01100: y = a & b; // amoand
5'b01000: y = a | b; // amoor
5'b10000: y = (a < b) ? a : b; // amomin
5'b10100: y = (a >= b) ? a : b; // amomax
5'b11000: y = ({1'b0, a} < {1'b0, b}) ? a : b; // amominu
5'b11100: y = ({1'b0, a} >= {1'b0, b}) ? a : b; // amomaxu
default: y = 'bx; // undefined; *** could change to b for efficiency
endcase
// sign extend if necessary
generate
if (`XLEN == 32) begin
assign result = y;
end else begin // `XLEN = 64
always_comb
if (width == 2'b10) // sign-extend word-length operations
result = {{32{y[31]}}, y[31:0]};
else result = y;
end
endgenerate
endmodule

View File

@ -82,11 +82,11 @@ module flopenr #(parameter WIDTH = 8) (
endmodule endmodule
// flop with enable, asynchronous load // flop with enable, asynchronous load
module flopenl #(parameter WIDTH = 8) ( module flopenl #(parameter WIDTH = 8, parameter type TYPE=logic [WIDTH-1:0]) (
input logic clk, load, en, input logic clk, load, en,
input logic [WIDTH-1:0] d, input TYPE d,
input logic [WIDTH-1:0] val, input TYPE val,
output logic [WIDTH-1:0] q); output TYPE q);
always_ff @(posedge clk, posedge load) always_ff @(posedge clk, posedge load)
if (load) q <= #1 val; if (load) q <= #1 val;

View File

@ -48,7 +48,7 @@ module controller(
input logic StallM, FlushM, input logic StallM, FlushM,
output logic [1:0] MemRWM, output logic [1:0] MemRWM,
output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic AtomicM, output logic [1:0] AtomicM,
output logic [2:0] Funct3M, output logic [2:0] Funct3M,
output logic RegWriteM, // for Hazard Unit output logic RegWriteM, // for Hazard Unit
// Writeback stage control signals // Writeback stage control signals
@ -65,6 +65,8 @@ module controller(
logic [6:0] Funct7D; logic [6:0] Funct7D;
logic [4:0] Rs1D; logic [4:0] Rs1D;
`define CTRLW 23
// pipelined control signals // pipelined control signals
logic RegWriteD, RegWriteE; logic RegWriteD, RegWriteE;
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
@ -77,11 +79,11 @@ module controller(
logic TargetSrcD, W64D, MulDivD; logic TargetSrcD, W64D, MulDivD;
logic CSRZeroSrcD; logic CSRZeroSrcD;
logic CSRReadD; logic CSRReadD;
logic AtomicD, AtomicE; logic [1:0] AtomicD, AtomicE;
logic CSRWriteD, CSRWriteE; logic CSRWriteD, CSRWriteE;
logic InstrValidE, InstrValidM; logic InstrValidE, InstrValidM;
logic PrivilegedD, PrivilegedE; logic PrivilegedD, PrivilegedE;
logic [21:0] ControlsD; logic [`CTRLW-1:0] ControlsD;
logic aluc3D; logic aluc3D;
logic subD, sraD, sltD, sltuD; logic subD, sraD, sltD, sltuD;
logic BranchTakenE; logic BranchTakenE;
@ -100,48 +102,47 @@ module controller(
generate generate
always_comb always_comb
case(OpD) case(OpD)
// *** Atomic p. 132 assembly encodings, defs 48
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Atomic_Illegal // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Atomic_Illegal
7'b0000000: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // illegal instruction 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // illegal instruction
7'b0000011: ControlsD = 22'b1_000_01_10_001_0_00_0_0_0_0_0_0_0_0; // lw 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_00_0_0_0_0_0_0_00_0; // lw
7'b0001111: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_0; // fence = nop 7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_0; // fence = nop
7'b0010011: ControlsD = 22'b1_000_01_00_000_0_10_0_0_0_0_0_0_0_0; // I-type ALU 7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = 22'b1_100_11_00_000_0_00_0_0_0_0_0_0_0_0; // auipc 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_00_0_0_0_0_0_0_00_0; // auipc
7'b0011011: if (`XLEN == 64) 7'b0011011: if (`XLEN == 64)
ControlsD = 22'b1_000_01_00_000_0_10_0_0_1_0_0_0_0_0; // IW-type ALU for RV64i ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_1_0_0_0_00_0; // IW-type ALU for RV64i
else else
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0100011: ControlsD = 22'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_0; // sw 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_00_0; // sw
7'b0101111: if (`A_SUPPORTED) begin 7'b0101111: if (`A_SUPPORTED) begin
if (InstrD[31:27] == 5'b00010) if (InstrD[31:27] == 5'b00010)
ControlsD = 22'b1_000_00_10_001_0_00_0_0_0_0_0_0_1_0; // lr ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_01_0; // lr
else if (InstrD[31:27] == 5'b00011) 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 = `CTRLW'b1_101_01_01_101_0_00_0_0_0_0_0_0_01_0; // sc
else else
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_1_0; // other atomic; decode later ControlsD = `CTRLW'b1_101_00_11_001_0_00_0_0_0_0_0_0_10_0;; // amo
end else end else
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000)
ControlsD = 22'b1_000_00_00_000_0_10_0_0_0_0_0_0_0_0; // R-type ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_00_0; // R-type
else if (Funct7D == 7'b0000001 && `M_SUPPORTED) else if (Funct7D == 7'b0000001 && `M_SUPPORTED)
ControlsD = 22'b1_000_00_00_100_0_00_0_0_0_0_0_1_0_0; // Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_0_0_0_1_00_0; // Multiply/Divide
else else
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0110111: ControlsD = 22'b1_100_01_00_000_0_11_0_0_0_0_0_0_0_0; // lui 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_00_0; // lui
7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64) 7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64)
ControlsD = 22'b1_000_00_00_000_0_10_0_0_1_0_0_0_0_0; // R-type W instructions for RV64i ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_00_0; // R-type W instructions for RV64i
else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64) else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64)
ControlsD = 22'b1_000_00_00_100_0_00_0_0_1_0_0_1_0_0; // W-type Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_100_0_00_0_0_1_0_0_1_00_0; // W-type Multiply/Divide
else else
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b1100011: ControlsD = 22'b0_010_00_00_000_1_01_0_0_0_0_0_0_0_0; // beq 7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_00_0; // beq
7'b1100111: ControlsD = 22'b1_000_00_00_010_0_00_1_1_0_0_0_0_0_0; // jalr 7'b1100111: ControlsD = `CTRLW'b1_000_00_00_010_0_00_1_1_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = 22'b1_011_00_00_010_0_00_1_0_0_0_0_0_0_0; // jal 7'b1101111: ControlsD = `CTRLW'b1_011_00_00_010_0_00_1_0_0_0_0_0_00_0; // jal
7'b1110011: if (Funct3D == 3'b000) 7'b1110011: if (Funct3D == 3'b000)
ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_1_0_0_0; // privileged; decoded further in priveleged modules ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_00_0; // privileged; decoded further in priveleged modules
else else
ControlsD = 22'b1_000_00_00_011_0_00_0_0_0_1_0_0_0_0; // csrs ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_1_0_0_00_0; // csrs
default: ControlsD = 22'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_1; // non-implemented instruction default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase endcase
endgenerate endgenerate
@ -173,7 +174,7 @@ module controller(
endcase endcase
// Execute stage pipeline control register and logic // Execute stage pipeline control register and logic
flopenrc #(26) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, 1'b1}, {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, 1'b1},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InstrValidE}); {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InstrValidE});
@ -196,7 +197,7 @@ module controller(
assign MemReadE = MemRWE[1]; assign MemReadE = MemRWE[1];
// Memory stage pipeline control register // Memory stage pipeline control register
flopenrc #(14) controlregM(clk, reset, FlushM, ~StallM, flopenrc #(15) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InstrValidE}, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InstrValidM}); {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InstrValidM});

View File

@ -43,7 +43,7 @@ module ieu (
input logic DataAccessFaultM, input logic DataAccessFaultM,
input logic SquashSCW, input logic SquashSCW,
output logic [1:0] MemRWM, output logic [1:0] MemRWM,
output logic AtomicM, output logic [1:0] AtomicM,
output logic [`XLEN-1:0] MemAdrM, WriteDataM, output logic [`XLEN-1:0] MemAdrM, WriteDataM,
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [2:0] Funct3M, output logic [2:0] Funct3M,

View File

@ -91,7 +91,7 @@ module BTBPredictor
.WA1(UpdatePCIndex), .WA1(UpdatePCIndex),
.WD1({UpdateInstrClass, UpdateTarget}), .WD1({UpdateInstrClass, UpdateTarget}),
.WEN1(UpdateEN), .WEN1(UpdateEN),
.BitWEN1({`XLEN{1'b1}})); .BitWEN1({4'b0000, {`XLEN{1'b1}}})); // *** definitely not right.
endmodule endmodule

View File

@ -59,7 +59,7 @@ module dtim #(parameter BASE=0, RANGE = 65535) (
busycount <= 0; busycount <= 0;
HREADYTim <= #1 0; HREADYTim <= #1 0;
end else if (~HREADYTim) begin end else if (~HREADYTim) begin
if (busycount == 2) begin // TIM latency, for testing purposes if (busycount == 2) begin // TIM latency, for testing purposes. *** test with different values
HREADYTim <= #1 1; HREADYTim <= #1 1;
end else begin end else begin
busycount <= busycount + 1; busycount <= busycount + 1;

View File

@ -60,7 +60,8 @@ module wallypipelinedhart (
// new signals that must connect through DP // new signals that must connect through DP
logic MulDivE, W64E; logic MulDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM, AtomicM; logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM;
logic [`XLEN-1:0] SrcAE, SrcBE; logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM; logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E; logic [2:0] Funct3E;
@ -117,6 +118,7 @@ module wallypipelinedhart (
//.InstrReadF(1'b0), //.InstrReadF(1'b0),
//.InstrRData(InstrF), // hook up InstrF later //.InstrRData(InstrF), // hook up InstrF later
.MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]), .MemSizeM(Funct3M[1:0]), .UnsignedLoadM(Funct3M[2]),
.Funct7M(InstrM[31:25]),
.*); .*);
// walker walker(.*); *** // can send addresses to ahblite, send out pagetablestall // walker walker(.*); *** // can send addresses to ahblite, send out pagetablestall

View File

@ -95,6 +95,14 @@ module testbench_busybear();
end 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; integer warningCount = 0;
//logic[63:0] adrTranslation[4:0]; //logic[63:0] adrTranslation[4:0];
@ -154,10 +162,10 @@ module testbench_busybear();
$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); $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 `ERROR
end end
if (dut.hart.ieu.dp.regf.rf[i] !== regExpected) begin //if (dut.hart.ieu.dp.regf.rf[i] !== regExpected) begin
force dut.hart.ieu.dp.regf.rf[i] = regExpected; // force dut.hart.ieu.dp.regf.rf[i] = regExpected;
release dut.hart.ieu.dp.regf.rf[i]; // release dut.hart.ieu.dp.regf.rf[i];
end //end
end end
end end
end end
@ -179,8 +187,8 @@ module testbench_busybear();
logic [`XLEN-1:0] readAdrExpected; logic [`XLEN-1:0] readAdrExpected;
always @(dut.hart.MemRWM[1] or HADDR) begin always @(dut.hart.MemRWM[1] or HADDR or dut.HRDATA) begin
if (dut.hart.MemRWM[1] && HADDR != dut.PCF) begin if (dut.hart.MemRWM[1] && HADDR != dut.PCF && dut.HRDATA != {64{1'bx}}) begin
if($feof(data_file_memR)) begin if($feof(data_file_memR)) begin
$display("no more memR data to read"); $display("no more memR data to read");
`ERROR `ERROR
@ -194,7 +202,7 @@ module testbench_busybear();
end end
if (((readMask & HRDATA) !== (readMask & dut.HRDATA)) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin 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); $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; warningCount += 1;
`ERROR `ERROR
end end
@ -340,13 +348,40 @@ module testbench_busybear();
always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin
if(~HWRITE) begin if(~HWRITE) begin
#3; #3;
if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}}) begin if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}} && ~dut.hart.StallD) begin
if (dut.PCF !== lastPCF) begin if (dut.PCF !== lastPCF) begin
lastCheckInstrF = CheckInstrF; lastCheckInstrF = CheckInstrF;
lastPC <= dut.PCF; lastPC <= dut.PCF;
lastPC2 <= lastPC; lastPC2 <= lastPC;
if (speculative && (lastPC != pcExpected)) begin if (speculative && (lastPC != pcExpected)) begin
speculative = ~equal(dut.PCF,pcExpected,3); 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 end
else begin else begin
if($feof(data_file_PC)) begin if($feof(data_file_PC)) begin
@ -359,21 +394,31 @@ module testbench_busybear();
PCtext = {PCtext, " ", PCtext2}; PCtext = {PCtext, " ", PCtext2};
end end
scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF); scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF);
if(CheckInstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs if(dut.PCF === pcExpected) begin
CheckInstrF = 32'b0010011; if(dut.hart.ifu.InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
$display("warning: NOPing out %s at PC=%0x", PCtext, dut.PCF); force CheckInstrF = 32'b0010011;
warningCount += 1; release CheckInstrF;
forcedInstr = 1; force dut.hart.ifu.InstrF = 32'b0010011;
end #7;
else begin release dut.hart.ifu.InstrF;
if(CheckInstrF[28:27] != 2'b11 && CheckInstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.PCF, instrs, $time);
CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011};
$display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF);
warningCount += 1; warningCount += 1;
forcedInstr = 1; forcedInstr = 1;
end end
else begin else begin
forcedInstr = 0; 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 end
// then expected PC value // then expected PC value

View File

@ -37,6 +37,9 @@ module testbench();
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
//logic [31:0] InstrW; //logic [31:0] InstrW;
logic [`XLEN-1:0] meminit; logic [`XLEN-1:0] meminit;
string tests64a[] = '{
"rv64a/WALLY-LRSC", "2110"
};
string tests64m[] = '{ string tests64m[] = '{
"rv64m/I-MUL-01", "3000", "rv64m/I-MUL-01", "3000",
"rv64m/I-MULH-01", "3000", "rv64m/I-MULH-01", "3000",
@ -322,9 +325,11 @@ string tests32i[] = {
initial initial
if (`XLEN == 64) begin // RV64 if (`XLEN == 64) begin // RV64
tests = {tests64i}; tests = {tests64i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; if (`C_SUPPORTED) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc}; else tests = {tests, tests64iNOc};
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m}; if (`M_SUPPORTED) tests = {tests, tests64m};
if (`A_SUPPORTED) tests = {tests64a, tests};
// tests = {tests64a, tests};
end else begin // RV32 end else begin // RV32
tests = {tests32i}; tests = {tests32i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
@ -368,6 +373,7 @@ string tests32i[] = {
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.imem.RAM); $readmemh(memfilename, dut.imem.RAM);
$readmemh(memfilename, dut.uncore.dtim.RAM); $readmemh(memfilename, dut.uncore.dtim.RAM);
$display("Read memfile %s", memfilename);
reset = 1; # 42; reset = 0; reset = 1; # 42; reset = 0;
end end
@ -584,6 +590,30 @@ module instrNameDecTB(
10'b1110011_101: name = "CSRRWI"; 10'b1110011_101: name = "CSRRWI";
10'b1110011_110: name = "CSRRSI"; 10'b1110011_110: name = "CSRRSI";
10'b1110011_111: name = "CSRRCI"; 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"; 10'b0001111_???: name = "FENCE";
default: name = "ILLEGAL"; default: name = "ILLEGAL";
endcase endcase