Merge branch 'main' of https://github.com/openhwgroup/cvw into bit-manip

This commit is contained in:
Kevin Kim 2023-03-20 13:06:10 -07:00
commit 07a43e1935
28 changed files with 337 additions and 145 deletions

5
.editorconfig Normal file
View File

@ -0,0 +1,5 @@
root = true
[src/**.sv]
indent_style = space
indent_size = 2

View File

@ -261,6 +261,22 @@ $ make all
Note: When the make tasks complete, youll find source code in $RISCV/buildroot/output/build and the executables in $RISCV/buildroot/output/images. Note: When the make tasks complete, youll find source code in $RISCV/buildroot/output/build and the executables in $RISCV/buildroot/output/images.
### Generate load images for linux boot
The Questa linux boot uses preloaded bootram and ram memory. We use QEMU to generate these preloaded memory files. Files output in $RISCV/linux-testvectors
cd cvw/linux/testvector-generation
./genInitMem.sh
This may require changing file permissions to the linux-testvectors directory.
### Generate QEMU linux trace
The linux testbench can instruction by instruction compare Wally's committed instructions against QEMU. To do this QEMU outputs a log file consisting of all instructions executed. Interrupts are handled by forcing the testbench to generate an interrupt at the same cycle as in QEMU. Generating this trace will take more than 24 hours.
cd cvw/linux/testvector-generation
./genTrace.sh
### Download Synthesis Libraries ### Download Synthesis Libraries
For logic synthesis, we need a synthesis tool (see Section 3.XREF) and a cell library. Clone the OSU 12-track cell library for the Skywater 130 nm process: For logic synthesis, we need a synthesis tool (see Section 3.XREF) and a cell library. Clone the OSU 12-track cell library for the Skywater 130 nm process:

57
bin/CModelBranchAccuracy.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
###########################################
## Written: ross1728@gmail.com
## Created: 12 March 2023
## Modified:
##
## Purpose: Takes a directory of branch outcomes organized as 1 files per benchmark.
## Computes the geometric mean.
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
Directory="$1"
Files="$1/*.log"
for Pred in "bimodal" "gshare"
do
for Size in $(seq 6 2 16)
do
if [ $Pred = "gshare" ]; then
SizeString="$Size $Size 18 1"
elif [ $Pred = "bimodal" ]; then
SizeString="$Size 18 1"
fi
Product=1.0
Count=0
for File in $Files
do
#echo "sim_bp $Pred $Size $Size 18 1 $File | tail -1 | awk '{print $4}'"
#echo "sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'"
BMDR=`sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'`
Product=`echo "$Product * $BMDR" | bc`
Count=$((Count+1))
done
GeoMean=`perl -E "say $Product**(1/$Count)"`
echo "$Pred$Size $GeoMean"
done
done

52
bin/SeparateBranch.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/bash
###########################################
## Written: ross1728@gmail.com
## Created: 12 March 2023
## Modified:
##
## Purpose: Converts a single branch.log containing multiple benchmark branch outcomes into
## separate files, one for each program.x4
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
File="$1"
TrainLineNumbers=`cat $File | grep -n "TRAIN" | awk -NF ':' '{print $1}'`
BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'`
Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6_$4}'`
EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'`
echo $Name
echo $BeginLineNumbers
echo $EndLineNumbers
NameArray=($Name)
TrainLineNumberArray=($TrainLineNumbers)
BeginLineNumberArray=($BeginLineNumbers)
EndLineNumberArray=($EndLineNumbers)
mkdir -p branch
Length=${#EndLineNumberArray[@]}
for i in $(seq 0 1 $((Length-1)))
do
CurrName=${NameArray[$i]}
CurrTrain=$((${TrainLineNumberArray[$i]}+1))
CurrEnd=$((${EndLineNumberArray[$i]}-1))
echo $CurrName, $CurrTrain, $CurrEnd
sed -n "${CurrTrain},${CurrEnd}p" $File > branch/${CurrName}_branch.log
done

View File

@ -30,6 +30,18 @@ import sys
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import re import re
#RefData={'twobitCModel' :(['6', '8', '10', '12', '14', '16'],
# [11.0680836450622, 8.53864970807778, 7.59565430177984, 6.38741598498948, 5.83662961500838, 5.83662961500838]),
# 'gshareCModel' : (['6', '8', '10', '12', '14', '16'],
# [14.5859173702079, 12.3634674403619, 10.5806018170154, 8.38831266973592, 6.37097544620762, 3.52638362703015])
#}
RefData = [('twobitCModel6', 11.0501534891674), ('twobitCModel8', 8.51829052266352), ('twobitCModel10', 7.56775222626483),
('twobitCModel12', 6.31366834586515), ('twobitCModel14', 5.72699936834177), ('twobitCModel16', 5.72699936834177),
('gshareCModel6', 14.5731555979574), ('gshareCModel8', 12.3155658100497), ('gshareCModel10', 10.4589596630561),
('gshareCModel12', 8.25796055444401), ('gshareCModel14', 6.23093702707613), ('gshareCModel16', 3.34001125650374)]
def ComputeCPI(benchmark): def ComputeCPI(benchmark):
'Computes and inserts CPI into benchmark stats.' 'Computes and inserts CPI into benchmark stats.'
(nameString, opt, dataDict) = benchmark (nameString, opt, dataDict) = benchmark
@ -221,14 +233,15 @@ if(sys.argv[1] == '-b'):
for benchmark in benchmarkAll: for benchmark in benchmarkAll:
(name, opt, config, dataDict) = benchmark (name, opt, config, dataDict) = benchmark
if name+'_'+opt in benchmarkDict: if name+'_'+opt in benchmarkDict:
benchmarkDict[name+'_'+opt].append((config, dataDict['BTMR'])) benchmarkDict[name+'_'+opt].append((config, dataDict['BDMR']))
else: else:
benchmarkDict[name+'_'+opt] = [(config, dataDict['BTMR'])] benchmarkDict[name+'_'+opt] = [(config, dataDict['BDMR'])]
size = len(benchmarkDict) size = len(benchmarkDict)
index = 1 index = 1
if(summery == 0): if(summery == 0):
#print('Number of plots', size) #print('Number of plots', size)
for benchmarkName in benchmarkDict: for benchmarkName in benchmarkDict:
currBenchmark = benchmarkDict[benchmarkName] currBenchmark = benchmarkDict[benchmarkName]
(names, values) = FormatToPlot(currBenchmark) (names, values) = FormatToPlot(currBenchmark)
@ -241,6 +254,8 @@ if(sys.argv[1] == '-b'):
index += 1 index += 1
else: else:
combined = benchmarkDict['All_'] combined = benchmarkDict['All_']
# merge the reference data into rtl data
combined.extend(RefData)
(name, value) = FormatToPlot(combined) (name, value) = FormatToPlot(combined)
lst = [] lst = []
dct = {} dct = {}
@ -264,8 +279,8 @@ if(sys.argv[1] == '-b'):
dct[PredType] = (currSize, currPercent) dct[PredType] = (currSize, currPercent)
print(dct) print(dct)
fig, axes = plt.subplots() fig, axes = plt.subplots()
marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x', 'btb': 'x'} marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x', 'btb': 'x', 'twobitCModel' : 'x', 'gshareCModel' : '*'}
colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue', 'btb' : 'blue'} colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue', 'btb' : 'blue', 'twobitCModel' : 'gray', 'gshareCModel' : 'dodgerblue'}
for cat in dct: for cat in dct:
(x, y) = dct[cat] (x, y) = dct[cat]
x=[int(2**int(v)) for v in x] x=[int(2**int(v)) for v in x]

1
bin/sim_bp Symbolic link
View File

@ -0,0 +1 @@
../addins/branch-predictor-simulator/src/sim_bp

View File

@ -62,7 +62,7 @@ make install
# elf2hex # elf2hex
cd $RISCV cd $RISCV
#export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH #export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH
gexport PATH=$RISCV/bin:$PATH export PATH=$RISCV/bin:$PATH
git clone https://github.com/sifive/elf2hex.git git clone https://github.com/sifive/elf2hex.git
cd elf2hex cd elf2hex
autoreconf -i autoreconf -i

View File

@ -48,8 +48,9 @@ if [ -e "$IDV" ]; then
export IMPERAS_HOME=$IDV/Imperas export IMPERAS_HOME=$IDV/Imperas
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
export ROOTDIR=~/ export ROOTDIR=~/
source ${IDV}/Imperas/bin/setup.sh source ${IMPERAS_HOME}/bin/setup.sh
setupImperas ${IDV}/Imperas setupImperas ${IMPERAS_HOME}
export PATH=$IDV/scripts/cvw:$PATH
fi fi

View File

@ -1,42 +1,55 @@
#--showoverrides #--showoverrides
#--help --helpall #--showcommands
--override cpu/show_c_prefix=T # Core settings
--override cpu/unaligned=F --override cpu/unaligned=F
--override cpu/ignore_non_leaf_DAU=1 --override cpu/ignore_non_leaf_DAU=1
--override cpu/wfi_is_nop=T --override cpu/wfi_is_nop=T
--override cpu/mimpid=0x100
--override cpu/misa_Extensions_mask=0x0
# this should be 16 not 0 # THIS NEEDS FIXING to 16
--override cpu/PMP_registers=0 --override cpu/PMP_registers=0
# PMA Settings
# 'r': read access allowed
# 'w': write access allowed
# 'x': execute access allowed
# 'a': aligned access required
# 'A': atomic instructions NOT allowed (actually USER1 privilege needed)
# 'P': push/pop instructions NOT allowed (actually USER2 privilege needed)
# '1': 1-byte accesses allowed
# '2': 2-byte accesses allowed
# '4': 4-byte accesses allowed
# '8': 8-byte accesses allowed
# '-', space: ignored (use for input string formatting).
#
# SV39 Memory 0x0000000000 0x7FFFFFFFFF
#
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ------ ---- "; # INITIAL
--callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 "; # BOOTROM
--callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw--A- --48 "; # SDC
--callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw--A- 1248 "; # CLINT
--callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw--A- --4- "; # PLIC
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw--A- 1--- "; # UART0 error - 0x10000000 - 0x100000FF
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw--A- --4- "; # GPIO error - 0x10006000 - 0x100060FF
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 "; # UNCORE_RAM
# Enable the Imperas instruction coverage # Enable the Imperas instruction coverage
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0 #-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
#-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/cover=basic
#-override refRoot/cpu/cv/extensions=RV32I #-override refRoot/cpu/cv/extensions=RV32I
# Add Imperas simulator application instruction tracing # Add Imperas simulator application instruction tracing
--trace --override cpu/show_c_prefix=T
--tracechange --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange
--traceshowicount
--tracemode
--tracemem ASX
--monitornetschange
# Exceptions and pagetables debug # Exceptions and pagetables debug
--override cpu/debugflags=6 --override cpu/debugflags=6
# Turn on verbose output for Imperas simulator # Turn on verbose output for Imperas simulator and Model
--verbose --verbose
# Turn on verbose output for RISCV model
--override cpu/verbose=1 --override cpu/verbose=1
# Store simulator output to logfile # Store simulator output to logfile
--output imperas.log --output imperas.log
# ignore settings of bits DAU for non leaf page table walks
--override cpu/ignore_non_leaf_DAU=1
# mimpid = 0x100
--override cpu/mimpid=0x100

View File

@ -27,6 +27,8 @@ from collections import namedtuple
regressionDir = os.path.dirname(os.path.abspath(__file__)) regressionDir = os.path.dirname(os.path.abspath(__file__))
os.chdir(regressionDir) os.chdir(regressionDir)
coverage = '-coverage' in sys.argv
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr']) TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# name: the name of this test configuration (used in printing human-readable # name: the name of this test configuration (used in printing human-readable
# output and picking logfile names) # output and picking logfile names)
@ -66,14 +68,6 @@ tc = TestCase(
configs.append(tc) configs.append(tc)
tests64gcimperas = ["imperas64i", "imperas64f", "imperas64d", "imperas64m", "imperas64c"] # unused tests64gcimperas = ["imperas64i", "imperas64f", "imperas64d", "imperas64m", "imperas64c"] # unused
tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "wally64a", "wally64periph", "wally64priv"]
for test in tests64gc:
tc = TestCase(
name=test,
variant="rv64gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests64i = ["arch64i"] tests64i = ["arch64i"]
for test in tests64i: for test in tests64i:
@ -131,6 +125,20 @@ for test in ahbTests:
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc ahb "+test[0]+" "+test[1]+"\n!", cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc ahb "+test[0]+" "+test[1]+"\n!",
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"]
if (coverage): # delete all but 64gc tests when running coverage
configs = []
coverStr = '-coverage'
else:
coverStr = ''
for test in tests64gc:
tc = TestCase(
name=test,
variant="rv64gc",
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc "+test+" " + coverStr + "\n!",
grepstr="All tests ran without failures")
configs.append(tc)
import os import os
@ -158,7 +166,7 @@ def run_test_case(config):
def main(): def main():
"""Run the tests and count the failures""" """Run the tests and count the failures"""
global configs global configs, coverage
try: try:
os.chdir(regressionDir) os.chdir(regressionDir)
os.mkdir("logs") os.mkdir("logs")
@ -183,6 +191,10 @@ def main():
elif '-buildroot' in sys.argv: elif '-buildroot' in sys.argv:
TIMEOUT_DUR = 30*7200 # seconds TIMEOUT_DUR = 30*7200 # seconds
configs=[getBuildrootTC(boot=True)] configs=[getBuildrootTC(boot=True)]
elif '-coverage' in sys.argv:
TIMEOUT_DUR = 20*60 # seconds
#configs.append(getBuildrootTC(boot=False))
os.system('rm cov/*.ucdb')
else: else:
TIMEOUT_DUR = 10*60 # seconds TIMEOUT_DUR = 10*60 # seconds
configs.append(getBuildrootTC(boot=False)) configs.append(getBuildrootTC(boot=False))
@ -201,6 +213,12 @@ def main():
num_fail+=1 num_fail+=1
print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR)) print(f"{bcolors.FAIL}%s_%s: Timeout - runtime exceeded %d seconds{bcolors.ENDC}" % (config.variant, config.name, TIMEOUT_DUR))
# Coverage report
if coverage:
print('Generating coverage report')
os.system('vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log')
os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage.rpt')
os.system('vcover report -html cov/cov.ucdb')
# Count the number of failures # Count the number of failures
if num_fail: if num_fail:
print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail)

View File

@ -40,6 +40,17 @@ if {$2 eq "ahb"} {
} }
vlib wkdir/work_${1}_${2} vlib wkdir/work_${1}_${2}
} }
# Create directory for coverage data
mkdir -p cov
# Check if measuring coverage
set coverage 0
if {$argc >= 3} {
if {$3 eq "-coverage"} {
set coverage 1
}
}
# 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"
@ -112,20 +123,26 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
# 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 wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt if {$coverage} {
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf } else {
#vsim -coverage -lib work_$2 workopt_$2 vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
}
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
# power add generates the logging necessary for said generation. # power add generates the logging necessary for said generation.
# power add -r /dut/core/* # power add -r /dut/core/*
run -all run -all
# power off -r /dut/core/* # power off -r /dut/core/*
} }
#coverage report -file wally-coverage.txt if {$coverage} {
do coverage-exclusions.do
coverage save -instance /testbench/dut cov/${1}_${2}.ucdb
}
# These aren't doing anything helpful # These aren't doing anything helpful
#coverage report -memory
#profile report -calltree -file wally-calltree.rpt -cutoff 2 #profile report -calltree -file wally-calltree.rpt -cutoff 2
#power report -all -bsaif power.saif #power report -all -bsaif power.saif
quit quit

View File

@ -24,6 +24,7 @@ vlib work
# 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
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings. # *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 \ vlog +incdir+../config/$1 \
+incdir+../config/shared \ +incdir+../config/shared \
+define+USE_IMPERAS_DV \ +define+USE_IMPERAS_DV \
@ -42,6 +43,7 @@ vlog +incdir+../config/$1 \
../src/*/*/*.sv \ ../src/*/*/*.sv \
-suppress 2583 \ -suppress 2583 \
-suppress 7063 -suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \ vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \

View File

@ -366,11 +366,9 @@ add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VI
add wave -noupdate -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/WalkerState add wave -noupdate -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/WalkerState
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/HPTWAdr add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/HPTWAdr
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PTE add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PTE
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PCFSpill
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/NextPageType add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/NextPageType
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PageType add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PageType
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ValidNonLeafPTE add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ValidNonLeafPTE
add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PCFSpill
add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF
add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM
add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ITLBWriteF add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ITLBWriteF
@ -467,7 +465,6 @@ add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/d
add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/IFUCacheBusStallD add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/IFUCacheBusStallD
add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/ITLBMissF add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/ITLBMissF
add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/TakeSpillF add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/TakeSpillF
add wave -noupdate -group ifu -group Spill /testbench/dut/core/ifu/SelNextSpillF
add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HSIZE add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HSIZE
add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HBURST add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HBURST
add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HTRANS add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HTRANS
@ -635,8 +632,10 @@ add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/DCacheMis
add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/InstrValidNotFlushedM add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/InstrValidNotFlushedM
add wave -noupdate /testbench/clk add wave -noupdate /testbench/clk
add wave -noupdate /testbench/HPMCSample/InitialHPMCOUNTERH add wave -noupdate /testbench/HPMCSample/InitialHPMCOUNTERH
add wave -noupdate /testbench/HPMCSample/EndSample
add wave -noupdate /testbench/HPMCSample/StartSample
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {49231900 ns} 0} {{Cursor 5} {394987 ns} 1} WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {23 ns} 0} {{Cursor 5} {394987 ns} 1}
quietly wave cursor active 4 quietly wave cursor active 4
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 194 configure wave -valuecolwidth 194
@ -652,4 +651,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {49231842 ns} {49231960 ns} WaveRestoreZoom {0 ns} {52 ns}

24
src/cache/cache.sv vendored
View File

@ -29,7 +29,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, DCACHE) ( module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
@ -39,7 +39,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
input logic [1:0] CacheAtomic, // Atomic operation input logic [1:0] CacheAtomic, // Atomic operation
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits input logic InvalidateCache, // Clear all valid bits
input logic [11:0] NextAdr, // Virtual address, but we only use the lower 12 bits. input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits.
input logic [`PA_BITS-1:0] PAdr, // Physical address input logic [`PA_BITS-1:0] PAdr, // Physical address
input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only) input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only) input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only)
@ -50,7 +50,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
output logic CacheMiss, // Cache miss output logic CacheMiss, // Cache miss
output logic CacheAccess, // Cache access output logic CacheAccess, // Cache access
// lsu control // lsu control
input logic SelHPTW, // Use PAdr from Hardware Page Table Walker rather than NextAdr input logic SelHPTW, // Use PAdr from Hardware Page Table Walker rather than NextSet
// Bus fsm interface // Bus fsm interface
input logic CacheBusAck, // Bus operation completed input logic CacheBusAck, // Bus operation completed
input logic SelBusBeat, // Word in cache line comes from BeatCount input logic SelBusBeat, // Word in cache line comes from BeatCount
@ -74,7 +74,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
logic SelAdr; logic SelAdr;
logic [1:0] AdrSelMuxSel; logic [1:0] AdrSelMuxSel;
logic [SETLEN-1:0] CAdr; logic [SETLEN-1:0] CacheSet;
logic [LINELEN-1:0] LineWriteData; logic [LINELEN-1:0] LineWriteData;
logic ClearValid, ClearDirty, SetDirty, SetValid; logic ClearValid, ClearDirty, SetDirty, SetValid;
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0]; logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
@ -106,24 +106,24 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
// Read Path // Read Path
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Choose read address (CAdr). Normally use NextAdr, but use PAdr during stalls // Choose read address (CacheSet). Normally use NextSet, but use PAdr during stalls
// and FlushAdr when handling D$ flushes // and FlushAdr when handling D$ flushes
// The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap
// sets PCNextF to XTVEC and the icache must start reading the instruction. // sets PCNextF to XTVEC and the icache must start reading the instruction.
assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((DCACHE == 0) & FlushStage))}; assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))};
mux3 #(SETLEN) AdrSelMux(NextAdr[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, mux3 #(SETLEN) AdrSelMux(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr,
AdrSelMuxSel, CAdr); AdrSelMuxSel, CacheSet);
// Array of cache ways, along with victim, hit, dirty, and read merging logic // Array of cache ways, along with victim, hit, dirty, and read merging logic
cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE) CacheWays[NUMWAYS-1:0]( cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CAdr, .PAdr, .LineWriteData, .LineByteMask, .clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay,
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches // Select victim way for associative caches
if(NUMWAYS > 1) begin:vict if(NUMWAYS > 1) begin:vict
cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU(
.clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CAdr, .LRUWriteEn(LRUWriteEn & ~FlushStage), .clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn(LRUWriteEn & ~FlushStage),
.SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache); .SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache);
end else end else
assign VictimWay = 1'b1; // one hot. assign VictimWay = 1'b1; // one hot.
@ -138,7 +138,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
or_rows #(NUMWAYS, TAGLEN) TagAOMux(.a(TagWay), .y(Tag)); or_rows #(NUMWAYS, TAGLEN) TagAOMux(.a(TagWay), .y(Tag));
// Data cache needs to choose word offset from PAdr or BeatCount to writeback dirty lines // Data cache needs to choose word offset from PAdr or BeatCount to writeback dirty lines
if(DCACHE) if(!READ_ONLY_CACHE)
mux2 #(LOGBWPL) WordAdrrMux(.d0(PAdr[$clog2(LINELEN/8) - 1 : $clog2(MUXINTERVAL/8)]), mux2 #(LOGBWPL) WordAdrrMux(.d0(PAdr[$clog2(LINELEN/8) - 1 : $clog2(MUXINTERVAL/8)]),
.d1(BeatCount), .s(SelBusBeat), .d1(BeatCount), .s(SelBusBeat),
.y(WordOffsetAddr)); .y(WordOffsetAddr));

View File

@ -37,7 +37,7 @@ module cacheLRU
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag
input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag
input logic [SETLEN-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [SETLEN-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
input logic [SETLEN-1:0] PAdr, // Physical address input logic [SETLEN-1:0] PAdr, // Physical address
input logic LRUWriteEn, // Update the LRU state input logic LRUWriteEn, // Update the LRU state
input logic SetValid, // Set the dirty bit in the selected way and set input logic SetValid, // Set the dirty bit in the selected way and set
@ -124,8 +124,7 @@ module cacheLRU
// LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice. // LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice.
// This is a two port memory. // This is a two port memory.
// Every cycle must read from CAdr and each load/store must write the new LRU. // Every cycle must read from CacheSet and each load/store must write the new LRU.
// this is still wrong.***************************
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0;
if(CacheEn) begin if(CacheEn) begin
@ -133,10 +132,10 @@ module cacheLRU
else if (LRUWriteEn & ~FlushStage) begin else if (LRUWriteEn & ~FlushStage) begin
LRUMemory[PAdr] <= NextLRU; LRUMemory[PAdr] <= NextLRU;
end end
if(LRUWriteEn & ~FlushStage & (PAdr == CAdr)) if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet))
CurrLRU <= #1 NextLRU; CurrLRU <= #1 NextLRU;
else else
CurrLRU <= #1 LRUMemory[CAdr]; CurrLRU <= #1 LRUMemory[CacheSet];
end end
end end

18
src/cache/cacheway.sv vendored
View File

@ -30,12 +30,12 @@
`include "wally-config.vh" `include "wally-config.vh"
module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
OFFSETLEN = 5, INDEXLEN = 9, DIRTY_BITS = 1) ( OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
input logic [$clog2(NUMLINES)-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [$clog2(NUMLINES)-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
input logic [`PA_BITS-1:0] PAdr, // Physical address input logic [`PA_BITS-1:0] PAdr, // Physical address
input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only) input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only)
input logic SetValid, // Set the dirty bit in the selected way and set input logic SetValid, // Set the dirty bit in the selected way and set
@ -114,7 +114,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn),
.addr(CAdr), .dout(ReadTag), .bwe('1), .addr(CacheSet), .dout(ReadTag), .bwe('1),
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); .din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
@ -136,7 +136,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
localparam LOGNUMSRAM = $clog2(NUMSRAM); localparam LOGNUMSRAM = $clog2(NUMSRAM);
for(words = 0; words < NUMSRAM; words++) begin: word for(words = 0; words < NUMSRAM; words++) begin: word
ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CAdr), ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words])); .we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
@ -152,9 +152,9 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
always_ff @(posedge clk) begin // Valid bit array, always_ff @(posedge clk) begin // Valid bit array,
if (reset) ValidBits <= #1 '0; if (reset) ValidBits <= #1 '0;
if(CacheEn) begin if(CacheEn) begin
ValidWay <= #1 ValidBits[CAdr]; ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; if(InvalidateCache) ValidBits <= #1 '0;
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay; else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay;
end end
end end
@ -163,13 +163,13 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Dirty bits // Dirty bits
if (DIRTY_BITS) begin:dirty if (!READ_ONLY_CACHE) begin:dirty
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
// reset is optional. Consider merging with TAG array in the future. // reset is optional. Consider merging with TAG array in the future.
//if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; //if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
if(CacheEn) begin if(CacheEn) begin
Dirty <= #1 DirtyBits[CAdr]; Dirty <= #1 DirtyBits[CacheSet];
if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay; if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSet] <= #1 SetDirtyWay;
end end
end end
end else assign Dirty = 1'b0; end else assign Dirty = 1'b0;

View File

@ -69,6 +69,6 @@ module fdivsqrtexpcalc(
assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias};
// correct exponent for subnormal input's normalization shifts // correct exponent for subnormal input's normalization shifts
assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; // *** why Xzero? Is this a hack for postprocessor?
assign Qe = Sqrt ? SExp : DExp; assign Qe = Sqrt ? SExp : DExp;
endmodule endmodule

View File

@ -151,7 +151,7 @@ module fdivsqrtpreproc (
lzc #(`DIVb) lzcY (IFNormLenD, mE); lzc #(`DIVb) lzcY (IFNormLenD, mE);
// Normalization shift // Normalization shift
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
// append leading 1 (for normal inputs) // append leading 1 (for normal inputs)

View File

@ -43,7 +43,7 @@ module hazard (
); );
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW;
logic FlushDCause, FlushECause, FlushMCause, FlushWCause; logic FlushDCause, FlushECause, FlushMCause, FlushWCause;
// stalls and flushes // stalls and flushes
@ -95,14 +95,14 @@ module hazard (
assign #1 StallW = StallWCause; assign #1 StallW = StallWCause;
// detect the first stage that is not stalled // detect the first stage that is not stalled
assign FirstUnstalledD = ~StallD & StallF; assign LatestUnstalledD = ~StallD & StallF;
assign FirstUnstalledE = ~StallE & StallD; assign LatestUnstalledE = ~StallE & StallD;
assign FirstUnstalledM = ~StallM & StallE; assign LatestUnstalledM = ~StallM & StallE;
assign FirstUnstalledW = ~StallW & StallM; assign LatestUnstalledW = ~StallW & StallM;
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
assign #1 FlushD = FirstUnstalledD | FlushDCause; assign #1 FlushD = LatestUnstalledD | FlushDCause;
assign #1 FlushE = FirstUnstalledE | FlushECause; assign #1 FlushE = LatestUnstalledE | FlushECause;
assign #1 FlushM = FirstUnstalledM | FlushMCause; assign #1 FlushM = LatestUnstalledM | FlushMCause;
assign #1 FlushW = FirstUnstalledW | FlushWCause; assign #1 FlushW = LatestUnstalledW | FlushWCause;
endmodule endmodule

View File

@ -116,10 +116,6 @@ module alu #(parameter WIDTH=32) (
assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg; assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg;
assign LTU = ~Carry; assign LTU = ~Carry;
// SLT
assign SLT = {{(WIDTH-1){1'b0}}, LT};
assign SLTU = {{(WIDTH-1){1'b0}}, LTU};
// Select appropriate ALU Result // Select appropriate ALU Result
if (`ZBS_SUPPORTED | `ZBB_SUPPORTED) begin if (`ZBS_SUPPORTED | `ZBB_SUPPORTED) begin
always_comb always_comb

View File

@ -71,7 +71,7 @@ module bpred (
logic [1:0] BPDirPredF; logic [1:0] BPDirPredF;
logic [`XLEN-1:0] BTAF, RASPCF; logic [`XLEN-1:0] BPBTAF, RASPCF;
logic BPPCWrongE; logic BPPCWrongE;
logic IClassWrongE; logic IClassWrongE;
logic BPDirPredWrongE; logic BPDirPredWrongE;
@ -85,7 +85,7 @@ module bpred (
logic BTBTargetWrongE; logic BTBTargetWrongE;
logic RASTargetWrongE; logic RASTargetWrongE;
logic [`XLEN-1:0] BTAD; logic [`XLEN-1:0] BPBTAD;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF; logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF; logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
@ -95,7 +95,7 @@ module bpred (
logic BranchM, JumpM, ReturnM, CallM; logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW; logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD; logic BPReturnWrongD;
logic [`XLEN-1:0] BTAE; logic [`XLEN-1:0] BPBTAE;
@ -150,7 +150,7 @@ module bpred (
btb #(`BTB_SIZE) btb #(`BTB_SIZE)
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCNextF, .PCF, .PCD, .PCE, .PCM,
.BTAF, .BTAD, .BTAE, .BPBTAF, .BPBTAD, .BPBTAE,
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
.IClassWrongM, .IClassWrongE, .IClassWrongM, .IClassWrongE,
.IEUAdrE, .IEUAdrM, .IEUAdrE, .IEUAdrM,
@ -181,7 +181,7 @@ module bpred (
// Output the predicted PC or corrected PC on miss-predict. // Output the predicted PC or corrected PC on miss-predict.
assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF;
mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF); mux2 #(`XLEN) pcmuxbp(BPBTAF, RASPCF, BPReturnF, BPPCF);
// Selects the BP or PC+2/4. // Selects the BP or PC+2/4.
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF); mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF);
// If the prediction is wrong select the correct address. // If the prediction is wrong select the correct address.
@ -196,7 +196,7 @@ module bpred (
if(`ZICOUNTERS_SUPPORTED) begin if(`ZICOUNTERS_SUPPORTED) begin
logic [`XLEN-1:0] RASPCD, RASPCE; logic [`XLEN-1:0] RASPCD, RASPCE;
logic BTBPredPCWrongE, RASPredPCWrongE; logic BTAWrongE, RASPredPCWrongE;
// performance counters // performance counters
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now // 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
@ -207,14 +207,14 @@ module bpred (
// could be wrong or the fall through address selected for branch predict not taken. // could be wrong or the fall through address selected for branch predict not taken.
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
// both without the above inaccuracies. // both without the above inaccuracies.
// **** use BTAWrongM from BTB. // **** use BPBTAWrongM from BTB.
assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE; assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE}, {BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM}); {BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
end else begin end else begin

View File

@ -35,9 +35,9 @@ module btb #(parameter Depth = 10 ) (
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages
output logic [`XLEN-1:0] BTAF, // BTB's guess at PC output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC
output logic [`XLEN-1:0] BTAD, output logic [`XLEN-1:0] BPBTAD,
output logic [`XLEN-1:0] BTAE, output logic [`XLEN-1:0] BPBTAE,
output logic [3:0] BTBIClassF, // BTB's guess at instruction class output logic [3:0] BTBIClassF, // BTB's guess at instruction class
// update // update
input logic IClassWrongM, // BTB's instruction class guess was wrong input logic IClassWrongM, // BTB's instruction class guess was wrong
@ -57,8 +57,8 @@ module btb #(parameter Depth = 10 ) (
logic [`XLEN+3:0] TableBTBPredF; logic [`XLEN+3:0] TableBTBPredF;
logic [`XLEN-1:0] IEUAdrW; logic [`XLEN-1:0] IEUAdrW;
logic [`XLEN-1:0] PCW; logic [`XLEN-1:0] PCW;
logic BTBWrongE, BTAWrongE; logic BTBWrongE, BPBTAWrongE;
logic BTBWrongM, BTAWrongM; logic BTBWrongM, BPBTAWrongM;
// hashing function for indexing the PC // hashing function for indexing the PC
@ -84,12 +84,12 @@ module btb #(parameter Depth = 10 ) (
assign MatchW = PCFIndex == PCWIndex; assign MatchW = PCFIndex == PCWIndex;
assign MatchX = MatchD | MatchE | MatchM | MatchW; assign MatchX = MatchD | MatchE | MatchM | MatchW;
assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} : assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BPBTAD} :
MatchE ? {InstrClassE, IEUAdrE} : MatchE ? {InstrClassE, IEUAdrE} :
MatchM ? {InstrClassM, IEUAdrM} : MatchM ? {InstrClassM, IEUAdrM} :
{InstrClassW, IEUAdrW} ; {InstrClassW, IEUAdrW} ;
assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; assign {BTBIClassF, BPBTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF};
// An optimization may be using a PC relative address. // An optimization may be using a PC relative address.
@ -97,16 +97,16 @@ module btb #(parameter Depth = 10 ) (
.clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF),
.ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1));
flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BPBTAF, BPBTAD);
// BTAE is not strickly necessary. However it is used by two parts of wally. // BPBTAE is not strickly necessary. However it is used by two parts of wally.
// 1. It gates updates to the BTB when the prediction does not change. This save power. // 1. It gates updates to the BTB when the prediction does not change. This save power.
// 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. // 2. BPBTAWrongE is used by the performance counters to track when the BTB's BPBTA or instruction class is wrong.
flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BPBTAD, BPBTAE);
assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); assign BPBTAWrongE = (BPBTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]);
flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM); flopenrc #(1) BPBTAWrongMReg(clk, reset, FlushM, ~StallM, BPBTAWrongE, BPBTAWrongM);
assign BTBWrongM = BTAWrongM | IClassWrongM; assign BTBWrongM = BPBTAWrongM | IClassWrongM;
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);

View File

@ -233,7 +233,7 @@ module ifu (
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
cache #(.LINELEN(`ICACHE_LINELENINBITS), cache #(.LINELEN(`ICACHE_LINELENINBITS),
.NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS),
.NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .DCACHE(0)) .NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD),
.FetchBuffer, .CacheBusAck(ICacheBusAck), .FetchBuffer, .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
@ -245,7 +245,7 @@ module ifu (
.CacheWriteData('0), .CacheWriteData('0),
.CacheRW(CacheRWF), .CacheRW(CacheRWF),
.CacheAtomic('0), .FlushCache('0), .CacheAtomic('0), .FlushCache('0),
.NextAdr(PCSpillNextF[11:0]), .NextSet(PCSpillNextF[11:0]),
.PAdr(PCPF), .PAdr(PCPF),
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM)); .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW) ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW)

View File

@ -264,9 +264,9 @@ module lsu (
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW); assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .DCACHE(1)) dcache( .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache(
.clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM), .clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM),
.FlushCache(FlushDCache), .NextAdr(IEUAdrE[11:0]), .PAdr(PAdrM), .FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM),
.ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), .ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
.CacheWriteData(LSUWriteDataM), .SelHPTW, .CacheWriteData(LSUWriteDataM), .SelHPTW,
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), .CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),

View File

@ -32,11 +32,11 @@ module mdu(
input logic clk, reset, input logic clk, reset,
input logic StallM, StallW, input logic StallM, StallW,
input logic FlushE, FlushM, FlushW, input logic FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
input logic [2:0] Funct3E, Funct3M, // type of MDU operation input logic [2:0] Funct3E, Funct3M, // type of MDU operation
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
output logic [`XLEN-1:0] MDUResultW, // multiply/divide result output logic [`XLEN-1:0] MDUResultW, // multiply/divide result
output logic DivBusyE // busy signal to stall pipeline in Execute stage output logic DivBusyE // busy signal to stall pipeline in Execute stage
); );
logic [`XLEN*2-1:0] ProdM; // double-width product from mul logic [`XLEN*2-1:0] ProdM; // double-width product from mul

View File

@ -133,7 +133,7 @@ module csr #(parameter
if (InterruptM) NextFaultMtvalM = 0; if (InterruptM) NextFaultMtvalM = 0;
else case (CauseM) else case (CauseM)
12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint 12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint
2: NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM}; // Illegal instruction fault 2: NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM}; // Illegal instruction fault // *** this should probably set to the uncompressed instruction
0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults 0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults
default: NextFaultMtvalM = 0; // Ecall, interrupts default: NextFaultMtvalM = 0; // Ecall, interrupts
endcase endcase

View File

@ -69,6 +69,7 @@ logic [3:0] dummy;
logic DCacheFlushDone, DCacheFlushStart; logic DCacheFlushDone, DCacheFlushStart;
logic riscofTest; logic riscofTest;
logic StartSample, EndSample;
flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW);
@ -412,8 +413,7 @@ logic [3:0] dummy;
integer HPMCindex; integer HPMCindex;
logic StartSampleFirst; logic StartSampleFirst;
logic StartSampleDelayed; logic StartSampleDelayed;
logic StartSample; logic EndSampleFirst, EndSampleDelayed;
logic EndSample, EndSampleFirst, EndSampleDelayed;
logic [`XLEN-1:0] InitialHPMCOUNTERH[`COUNTERS-1:0]; logic [`XLEN-1:0] InitialHPMCOUNTERH[`COUNTERS-1:0];
string HPMCnames[] = '{"Mcycle", string HPMCnames[] = '{"Mcycle",
@ -454,6 +454,17 @@ logic [3:0] dummy;
flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed);
assign EndSample = EndSampleFirst & ~ EndSampleDelayed; assign EndSample = EndSampleFirst & ~ EndSampleDelayed;
end else if(TEST == "coremark") begin
// embench runs warmup then runs start_trigger
// embench end with stop_trigger.
assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time";
flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed);
assign StartSample = StartSampleFirst & ~ StartSampleDelayed;
assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time";
flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed);
assign EndSample = EndSampleFirst & ~ EndSampleDelayed;
end else begin end else begin
// default start condiction is reset // default start condiction is reset
// default end condiction is end of test (DCacheFlushDone) // default end condiction is end of test (DCacheFlushDone)
@ -540,15 +551,23 @@ logic [3:0] dummy;
string direction; string direction;
int file; int file;
logic PCSrcM; logic PCSrcM;
string LogFile;
logic resetD, resetEdge;
flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM); flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM);
flop #(1) ResetDReg(clk, reset, resetD);
assign resetEdge = ~reset & resetD;
initial begin initial begin
file = $fopen("branch.log", "w"); LogFile = $psprintf("branch_%s%0d.log", `BPRED_TYPE, `BPRED_SIZE);
file = $fopen(LogFile, "w");
end end
always @(posedge clk) begin always @(posedge clk) begin
if(resetEdge) $fwrite(file, "TRAIN\n");
if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename);
if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin
direction = PCSrcM ? "t" : "n"; direction = PCSrcM ? "t" : "n";
$fwrite(file, "%h %s\n", dut.core.PCM, direction); $fwrite(file, "%h %s\n", dut.core.PCM, direction);
end end
if(EndSample) $fwrite(file, "END %s\n", memfilename);
end end
end end
end end

View File

@ -138,11 +138,6 @@ module testbench;
.CMP_CSR (1) .CMP_CSR (1)
) idv_trace2api(rvvi); ) idv_trace2api(rvvi);
int PRIV_RWX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE | RVVI_MEMORY_PRIVILEGE_EXEC;
int PRIV_RW = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE;
int PRIV_RX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_EXEC;
int PRIV_X = RVVI_MEMORY_PRIVILEGE_EXEC;
initial begin initial begin
MAX_ERRS = 3; MAX_ERRS = 3;
@ -173,37 +168,24 @@ module testbench;
void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP
void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP
/* // Privileges for PMA are set in the imperas.ic
// Memory lo, hi, priv (RVVI_MEMORY_PRIVILEGE_{READ,WRITE,EXEC}) // volatile (IO) regions are defined here
void'(rvviRefMemorySetPrivilege(56'h0, 56'h7fffffffff, 0)); // only real ROM/RAM areas are BOOTROM and UNCORE_RAM
if (`BOOTROM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`BOOTROM_BASE, (`BOOTROM_BASE + `BOOTROM_RANGE), PRIV_RX));
if (`UNCORE_RAM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`UNCORE_RAM_BASE, (`UNCORE_RAM_BASE + `UNCORE_RAM_RANGE), PRIV_RWX));
if (`EXT_MEM_SUPPORTED)
void'(rvviRefMemorySetPrivilege(`EXT_MEM_BASE, (`EXT_MEM_BASE + `EXT_MEM_RANGE), PRIV_RWX));
if (`CLINT_SUPPORTED) begin if (`CLINT_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE))); void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE)));
end end
if (`GPIO_SUPPORTED) begin if (`GPIO_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE))); void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE)));
end end
if (`UART_SUPPORTED) begin if (`UART_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`UART_BASE, (`UART_BASE + `UART_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE)));
end end
if (`PLIC_SUPPORTED) begin if (`PLIC_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE))); void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE)));
end end
if (`SDC_SUPPORTED) begin if (`SDC_SUPPORTED) begin
void'(rvviRefMemorySetPrivilege(`SDC_BASE, (`SDC_BASE + `SDC_RANGE), PRIV_RW));
void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE))); void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE)));
end end
*/
if(`XLEN==32) begin if(`XLEN==32) begin
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH