mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'bp' into main
Concerns: 1. I don't think the correct data buses are going to the multiplier. 2. I'm not sure the FlushF signal is correct.
This commit is contained in:
commit
66e84f3a2c
47
wally-pipelined/bin/extractFunctionRadix.sh
Executable file
47
wally-pipelined/bin/extractFunctionRadix.sh
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
allProgramRadixFile="FunctionRadix"
|
||||||
|
|
||||||
|
index=0
|
||||||
|
|
||||||
|
for objDumpFile in "$@";
|
||||||
|
do
|
||||||
|
# get the lines with named labels from the obj files.
|
||||||
|
# 64 bit addresses
|
||||||
|
listOfAddr16=`egrep -i '^[0-9]{16} <[0-9a-zA-Z_]+>' $objDumpFile`
|
||||||
|
# 32 bit addresses
|
||||||
|
listOfAddr8=`egrep -i '^[0-9]{8} <[0-9a-zA-Z_]+>' $objDumpFile`
|
||||||
|
listOfAddr=`echo "$listOfAddr16" "$listOfAddr8"`
|
||||||
|
|
||||||
|
# parse out the addresses and the labels
|
||||||
|
addresses=`echo "$listOfAddr" | awk '{print $1}'`
|
||||||
|
labels=`echo "$listOfAddr" | awk '{print "\""$2"\"", "-color \"SpringGreen\","}' | tr -d '<>:'`
|
||||||
|
|
||||||
|
echo "$addresses" > $objDumpFile.addr
|
||||||
|
|
||||||
|
# need to add some formatting to each line
|
||||||
|
numLines=`echo "$listOfAddr" | wc -l`
|
||||||
|
prefix=`yes " 16#" | head -n $numLines`
|
||||||
|
midfix=`yes "# " | head -n $numLines`
|
||||||
|
|
||||||
|
# paste echos each of the 4 parts on a per line basis.
|
||||||
|
#-d'\0' sets no delimiter
|
||||||
|
temp=`paste -d'\0' <(echo "$prefix") <(echo "$addresses") <(echo "$midfix") <(echo "$labels")`
|
||||||
|
|
||||||
|
# remove the last comma
|
||||||
|
temp2=${temp::-1}
|
||||||
|
|
||||||
|
echo "radix define Functions {" > $objDumpFile.do
|
||||||
|
echo "$temp2" >> $objDumpFile.do
|
||||||
|
echo " -default hex -color green" >> $objDumpFile.do
|
||||||
|
echo "}" >> $objDumpFile.do
|
||||||
|
|
||||||
|
# now create the all in one version
|
||||||
|
# put the index at the begining of each line
|
||||||
|
allAddresses=`paste -d'\0' <(printf "%04x" "$index") <(echo "$addresses")`
|
||||||
|
|
||||||
|
printf "%04x%s" "$index" "$addresses" >> $allProgramRadixFile.addr
|
||||||
|
|
||||||
|
index=$(($index+1))
|
||||||
|
|
||||||
|
done
|
1024
wally-pipelined/regression/BTBPredictor.txt
Normal file
1024
wally-pipelined/regression/BTBPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
1024
wally-pipelined/regression/twoBitPredictor.txt
Normal file
1024
wally-pipelined/regression/twoBitPredictor.txt
Normal file
File diff suppressed because it is too large
Load Diff
52
wally-pipelined/regression/wally-pipelined-ross.do
Normal file
52
wally-pipelined/regression/wally-pipelined-ross.do
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# wally-pipelined.do
|
||||||
|
#
|
||||||
|
# Modification by Oklahoma State University & Harvey Mudd College
|
||||||
|
# Use with Testbench
|
||||||
|
# James Stine, 2008; David Harris 2021
|
||||||
|
# Go Cowboys!!!!!!
|
||||||
|
#
|
||||||
|
# Takes 1:10 to run RV64IC tests using gui
|
||||||
|
|
||||||
|
# Use this wally-pipelined.do file to run this example.
|
||||||
|
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||||
|
# do wally-pipelined.do
|
||||||
|
# or, to run from a shell, type the following at the shell prompt:
|
||||||
|
# vsim -do wally-pipelined.do -c
|
||||||
|
# (omit the "-c" to see the GUI while running from the shell)
|
||||||
|
|
||||||
|
onbreak {resume}
|
||||||
|
|
||||||
|
# create library
|
||||||
|
if [file exists work] {
|
||||||
|
vdel -all
|
||||||
|
}
|
||||||
|
vlib work
|
||||||
|
|
||||||
|
# compile source files
|
||||||
|
# suppress spurious warnngs about
|
||||||
|
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||||
|
# because vsim will run vopt
|
||||||
|
|
||||||
|
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
|
||||||
|
# do wally-pipelined.do ../config/rv32ic
|
||||||
|
switch $argc {
|
||||||
|
0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||||
|
1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
|
||||||
|
}
|
||||||
|
# start and run simulation
|
||||||
|
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||||
|
vopt +acc work.testbench -o workopt
|
||||||
|
vsim workopt
|
||||||
|
|
||||||
|
# load the branch predictors with known data. The value of the data is not important for function, but
|
||||||
|
# is important for perventing pessimistic x propagation.
|
||||||
|
mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||||
|
mem load -infile BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory
|
||||||
|
|
||||||
|
do wave.do
|
||||||
|
add log -r /*
|
||||||
|
|
||||||
|
-- Run the Simulation
|
||||||
|
#run 1000
|
||||||
|
run -all
|
||||||
|
#quit
|
@ -38,6 +38,11 @@ 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
|
||||||
|
mem load -infile 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
|
||||||
|
1622
wally-pipelined/regression/wave-all.do
Normal file
1622
wally-pipelined/regression/wave-all.do
Normal file
File diff suppressed because it is too large
Load Diff
134
wally-pipelined/regression/wave.do
Normal file
134
wally-pipelined/regression/wave.do
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
onerror {resume}
|
||||||
|
quietly WaveActivateNextPane {} 0
|
||||||
|
add wave -noupdate /testbench/clk
|
||||||
|
add wave -noupdate /testbench/reset
|
||||||
|
add wave -noupdate -radix ascii /testbench/memfilename
|
||||||
|
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE
|
||||||
|
add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName
|
||||||
|
add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/InstrE
|
||||||
|
add wave -noupdate -divider <NULL>
|
||||||
|
add wave -noupdate /testbench/dut/hart/ebu/IReadF
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/InstrStall
|
||||||
|
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushM
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushW
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF
|
||||||
|
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction -divider Update
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePC
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdateEN
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePCIndex
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/UpdatePrediction
|
||||||
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||||
|
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassF
|
||||||
|
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassD
|
||||||
|
add wave -noupdate -group InstrClass /testbench/dut/hart/ifu/bpred/InstrClassE
|
||||||
|
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrF
|
||||||
|
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD
|
||||||
|
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE
|
||||||
|
add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrM
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/BPPredWrongE
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNextF
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCF
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCPlus2or4F
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/BPPredPCF
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNext0F
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNext1F
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/SelBPPredF
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/BPPredWrongE
|
||||||
|
add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PrivilegedChangePCM
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/ValidBits
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/BPPredF
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/BTBValidF
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/LookUpPCIndexQ
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePCIndexQ
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/LookUpPC
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/TargetWrongE
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/FallThroughWrongE
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionDirWrongE
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/PredictionPCWrongE
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/BPPredWrongE
|
||||||
|
add wave -noupdate -group {bp wrong} /testbench/dut/hart/ifu/bpred/InstrClassE
|
||||||
|
add wave -noupdate -group BTB -divider Update
|
||||||
|
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateEN
|
||||||
|
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdatePC
|
||||||
|
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/UpdateTarget
|
||||||
|
add wave -noupdate -group BTB -divider Lookup
|
||||||
|
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
|
||||||
|
add wave -noupdate -group BTB /testbench/dut/hart/ifu/bpred/TargetPredictor/Valid
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/BTBPredPCF
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/TargetPredictor/TargetPC
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/CorrectPCE
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/bpred/FlushF
|
||||||
|
add wave -noupdate /testbench/dut/hart/FlushF
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rf
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a1
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a2
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a3
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd1
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd2
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/we3
|
||||||
|
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/wd3
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ALUResultW
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ReadDataW
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/PCLinkW
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW
|
||||||
|
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW
|
||||||
|
add wave -noupdate /testbench/dut/hart/ieu/c/RegWriteE
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ifu/InstrD
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/InstrDName
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
|
||||||
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
|
||||||
|
add wave -noupdate /testbench/InstrFName
|
||||||
|
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemAdrM
|
||||||
|
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemPAdrM
|
||||||
|
add wave -noupdate -expand -group dcache /testbench/dut/hart/WriteDataM
|
||||||
|
add wave -noupdate -expand -group dcache /testbench/dut/hart/ReadDataM
|
||||||
|
add wave -noupdate -expand -group dcache /testbench/dut/hart/dmem/MemRWM
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2E
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdE
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdM
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RdW
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/MemReadE
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RegWriteM
|
||||||
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/RegWriteW
|
||||||
|
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/ForwardAE
|
||||||
|
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/ForwardBE
|
||||||
|
add wave -noupdate -group Forward -color Thistle /testbench/dut/hart/ieu/fw/LoadStallD
|
||||||
|
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/WriteDataE
|
||||||
|
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/ALUResultE
|
||||||
|
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcAE
|
||||||
|
add wave -noupdate -expand -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcBE
|
||||||
|
add wave -noupdate /testbench/dut/hart/ieu/dp/ALUResultM
|
||||||
|
TreeUpdate [SetDefaultTree]
|
||||||
|
WaveRestoreCursors {{Cursor 2} {231033 ns} 0} {{Cursor 3} {1276117 ns} 0}
|
||||||
|
quietly wave cursor active 2
|
||||||
|
configure wave -namecolwidth 250
|
||||||
|
configure wave -valuecolwidth 518
|
||||||
|
configure wave -justifyvalue left
|
||||||
|
configure wave -signalnamewidth 1
|
||||||
|
configure wave -snapdistance 10
|
||||||
|
configure wave -datasetprefix 0
|
||||||
|
configure wave -rowmargin 4
|
||||||
|
configure wave -childrowmargin 2
|
||||||
|
configure wave -gridoffset 0
|
||||||
|
configure wave -gridperiod 1
|
||||||
|
configure wave -griddelta 40
|
||||||
|
configure wave -timeline 0
|
||||||
|
configure wave -timelineunits ns
|
||||||
|
update
|
||||||
|
WaveRestoreZoom {1276094 ns} {1276208 ns}
|
@ -27,12 +27,12 @@
|
|||||||
|
|
||||||
module hazard(
|
module hazard(
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
|
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
|
||||||
input logic LoadStallD, MulDivStallD, CSRRdStallD,
|
input logic LoadStallD, MulDivStallD, CSRRdStallD,
|
||||||
input logic InstrStall, DataStall,
|
input logic InstrStall, DataStall,
|
||||||
// Stall & flush outputs
|
// Stall & flush outputs
|
||||||
output logic StallF, StallD, StallE, StallM, StallW,
|
output logic StallF, StallD, StallE, StallM, StallW,
|
||||||
output logic FlushD, FlushE, FlushM, FlushW
|
output logic FlushF, FlushD, FlushE, FlushM, FlushW
|
||||||
);
|
);
|
||||||
|
|
||||||
logic BranchFlushDE;
|
logic BranchFlushDE;
|
||||||
@ -51,7 +51,7 @@ module hazard(
|
|||||||
// A stage must stall if the next stage is stalled
|
// A stage must stall if the next stage is stalled
|
||||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||||
|
|
||||||
assign BranchFlushDE = PCSrcE | RetM | TrapM;
|
assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
|
||||||
|
|
||||||
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
|
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
|
||||||
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
|
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
|
||||||
@ -62,6 +62,7 @@ module hazard(
|
|||||||
|
|
||||||
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
|
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
|
||||||
assign StallF = StallD | StallFCause;
|
assign StallF = StallD | StallFCause;
|
||||||
|
|
||||||
assign StallD = StallE | StallDCause;
|
assign StallD = StallE | StallDCause;
|
||||||
assign StallE = StallM | StallECause;
|
assign StallE = StallM | StallECause;
|
||||||
assign StallM = StallW | StallMCause;
|
assign StallM = StallW | StallMCause;
|
||||||
@ -73,6 +74,7 @@ module hazard(
|
|||||||
assign FirstUnstalledW = (~StallW & StallM);;
|
assign FirstUnstalledW = (~StallW & StallM);;
|
||||||
|
|
||||||
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
||||||
|
assign FlushF = BPPredWrongE;
|
||||||
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
|
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
|
||||||
assign FlushE = FirstUnstalledE || BranchFlushDE; //LoadStallD | PCSrcE | RetM | TrapM;
|
assign FlushE = FirstUnstalledE || BranchFlushDE; //LoadStallD | PCSrcE | RetM | TrapM;
|
||||||
assign FlushM = FirstUnstalledM || RetM || TrapM;
|
assign FlushM = FirstUnstalledM || RetM || TrapM;
|
||||||
|
@ -43,6 +43,7 @@ module controller(
|
|||||||
output logic MemReadE, CSRReadE, // for Hazard Unit
|
output logic MemReadE, CSRReadE, // for Hazard Unit
|
||||||
output logic [2:0] Funct3E,
|
output logic [2:0] Funct3E,
|
||||||
output logic MulDivE, W64E,
|
output logic MulDivE, W64E,
|
||||||
|
output logic JumpE,
|
||||||
// Memory stage control signals
|
// Memory stage control signals
|
||||||
input logic StallM, FlushM,
|
input logic StallM, FlushM,
|
||||||
output logic [1:0] MemRWM,
|
output logic [1:0] MemRWM,
|
||||||
@ -68,7 +69,7 @@ module controller(
|
|||||||
logic RegWriteD, RegWriteE;
|
logic RegWriteD, RegWriteE;
|
||||||
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
|
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
|
||||||
logic [1:0] MemRWD, MemRWE;
|
logic [1:0] MemRWD, MemRWE;
|
||||||
logic JumpD, JumpE;
|
logic JumpD;
|
||||||
logic BranchD, BranchE;
|
logic BranchD, BranchE;
|
||||||
logic [1:0] ALUOpD;
|
logic [1:0] ALUOpD;
|
||||||
logic [4:0] ALUControlD;
|
logic [4:0] ALUControlD;
|
||||||
|
@ -36,7 +36,9 @@ module datapath (
|
|||||||
input logic [4:0] ALUControlE,
|
input logic [4:0] ALUControlE,
|
||||||
input logic ALUSrcAE, ALUSrcBE,
|
input logic ALUSrcAE, ALUSrcBE,
|
||||||
input logic TargetSrcE,
|
input logic TargetSrcE,
|
||||||
|
input logic JumpE,
|
||||||
input logic [`XLEN-1:0] PCE,
|
input logic [`XLEN-1:0] PCE,
|
||||||
|
input logic [`XLEN-1:0] PCLinkE,
|
||||||
output logic [2:0] FlagsE,
|
output logic [2:0] FlagsE,
|
||||||
output logic [`XLEN-1:0] PCTargetE,
|
output logic [`XLEN-1:0] PCTargetE,
|
||||||
output logic [`XLEN-1:0] SrcAE, SrcBE,
|
output logic [`XLEN-1:0] SrcAE, SrcBE,
|
||||||
@ -64,7 +66,9 @@ module datapath (
|
|||||||
// Execute stage signals
|
// Execute stage signals
|
||||||
logic [`XLEN-1:0] RD1E, RD2E;
|
logic [`XLEN-1:0] RD1E, RD2E;
|
||||||
logic [`XLEN-1:0] ExtImmE;
|
logic [`XLEN-1:0] ExtImmE;
|
||||||
logic [`XLEN-1:0] PreSrcAE;
|
|
||||||
|
logic [`XLEN-1:0] PreSrcAE, SrcAE2, SrcBE2;
|
||||||
|
|
||||||
logic [`XLEN-1:0] ALUResultE;
|
logic [`XLEN-1:0] ALUResultE;
|
||||||
logic [`XLEN-1:0] WriteDataE;
|
logic [`XLEN-1:0] WriteDataE;
|
||||||
logic [`XLEN-1:0] TargetBaseE;
|
logic [`XLEN-1:0] TargetBaseE;
|
||||||
@ -93,8 +97,10 @@ module datapath (
|
|||||||
mux3 #(`XLEN) faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE);
|
mux3 #(`XLEN) faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE);
|
||||||
mux3 #(`XLEN) fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE);
|
mux3 #(`XLEN) fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE);
|
||||||
mux2 #(`XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
|
mux2 #(`XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
|
||||||
|
mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);
|
||||||
mux2 #(`XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);
|
mux2 #(`XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);
|
||||||
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUResultE, FlagsE);
|
mux2 #(`XLEN) srcbmux2(SrcBE, {`XLEN{1'b0}}, JumpE, SrcBE2); // *** May be able to remove this mux.
|
||||||
|
alu #(`XLEN) alu(SrcAE2, SrcBE2, ALUControlE, ALUResultE, FlagsE);
|
||||||
mux2 #(`XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
|
mux2 #(`XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
|
||||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
assign PCTargetE = ExtImmE + TargetBaseE;
|
||||||
|
|
||||||
@ -109,6 +115,9 @@ module datapath (
|
|||||||
flopenrc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ~StallW, ALUResultM, ALUResultW);
|
flopenrc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ~StallW, ALUResultM, ALUResultW);
|
||||||
flopenrc #(5) RdWEg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
flopenrc #(5) RdWEg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
||||||
|
|
||||||
|
// *** something is not right here. Before the merge I found an issue with the jal instruction not writing
|
||||||
|
// the link address through the alu.
|
||||||
|
// not sure what changed.
|
||||||
// handle Store Conditional result if atomic extension supported
|
// handle Store Conditional result if atomic extension supported
|
||||||
generate
|
generate
|
||||||
if (`A_SUPPORTED)
|
if (`A_SUPPORTED)
|
||||||
@ -118,4 +127,11 @@ module datapath (
|
|||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
mux6 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
|
mux6 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
|
// This mux4:1 no longer needs to include PCLinkW. This is set correctly in the execution stage.
|
||||||
|
// *** need to look at how the decoder is coded to fix.
|
||||||
|
mux4 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, ResultSrcW, ResultW);
|
||||||
|
>>>>>>> bp
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -33,6 +33,7 @@ module ieu (
|
|||||||
output logic IllegalBaseInstrFaultD,
|
output logic IllegalBaseInstrFaultD,
|
||||||
// Execute Stage interface
|
// Execute Stage interface
|
||||||
input logic [`XLEN-1:0] PCE,
|
input logic [`XLEN-1:0] PCE,
|
||||||
|
input logic [`XLEN-1:0] PCLinkE,
|
||||||
output logic [`XLEN-1:0] PCTargetE,
|
output logic [`XLEN-1:0] PCTargetE,
|
||||||
output logic MulDivE, W64E,
|
output logic MulDivE, W64E,
|
||||||
output logic [2:0] Funct3E,
|
output logic [2:0] Funct3E,
|
||||||
@ -72,6 +73,7 @@ module ieu (
|
|||||||
logic [1:0] ForwardAE, ForwardBE;
|
logic [1:0] ForwardAE, ForwardBE;
|
||||||
logic RegWriteM, RegWriteW;
|
logic RegWriteM, RegWriteW;
|
||||||
logic MemReadE, CSRReadE;
|
logic MemReadE, CSRReadE;
|
||||||
|
logic JumpE;
|
||||||
|
|
||||||
controller c(.*);
|
controller c(.*);
|
||||||
datapath dp(.*);
|
datapath dp(.*);
|
||||||
|
97
wally-pipelined/src/ifu/BTBPredictor.sv
Normal file
97
wally-pipelined/src/ifu/BTBPredictor.sv
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// SRAM2P1R1W
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 15, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: BTB model. Outputs type of instruction (currently 1 hot encoded. Probably want
|
||||||
|
// to encode to reduce storage), valid, target PC.
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module BTBPredictor
|
||||||
|
#(parameter int Depth = 10
|
||||||
|
)
|
||||||
|
(input logic clk,
|
||||||
|
input logic reset,
|
||||||
|
input logic [`XLEN-1:0] LookUpPC,
|
||||||
|
output logic [`XLEN-1:0] TargetPC,
|
||||||
|
output logic [3:0] InstrClass,
|
||||||
|
output logic Valid,
|
||||||
|
// update
|
||||||
|
input logic UpdateEN,
|
||||||
|
input logic [`XLEN-1:0] UpdatePC,
|
||||||
|
input logic [`XLEN-1:0] UpdateTarget,
|
||||||
|
input logic [3:0] UpdateInstrClass
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam TotalDepth = 2 ** Depth;
|
||||||
|
logic [TotalDepth-1:0] ValidBits;
|
||||||
|
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex, LookUpPCIndexQ, UpdatePCIndexQ;
|
||||||
|
|
||||||
|
// hashing function for indexing the PC
|
||||||
|
// We have Depth bits to index, but XLEN bits as the input.
|
||||||
|
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
||||||
|
// using compressed instructions. XOR bit 1 with the MSB of index.
|
||||||
|
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
|
||||||
|
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
|
||||||
|
|
||||||
|
|
||||||
|
flopenr #(Depth) UpdatePCIndexReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(1'b1),
|
||||||
|
.d(UpdatePCIndex),
|
||||||
|
.q(UpdatePCIndexQ));
|
||||||
|
|
||||||
|
// The valid bit must be resetable.
|
||||||
|
always_ff @ (posedge clk) begin
|
||||||
|
if (reset) begin
|
||||||
|
ValidBits <= #1 {TotalDepth{1'b0}};
|
||||||
|
end else if (UpdateEN) begin
|
||||||
|
ValidBits[UpdatePCIndexQ] <= #1 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
flopenr #(Depth) LookupPCIndexReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(1'b1),
|
||||||
|
.d(LookUpPCIndex),
|
||||||
|
.q(LookUpPCIndexQ));
|
||||||
|
|
||||||
|
assign Valid = ValidBits[LookUpPCIndexQ];
|
||||||
|
|
||||||
|
// the BTB contains the target address.
|
||||||
|
// Another optimization may be using a PC relative address.
|
||||||
|
// *** need to add forwarding.
|
||||||
|
|
||||||
|
SRAM2P1R1W #(Depth, `XLEN+4) memory(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.RA1(LookUpPCIndex),
|
||||||
|
.RD1({{InstrClass, TargetPC}}),
|
||||||
|
.REN1(1'b1),
|
||||||
|
.WA1(UpdatePCIndex),
|
||||||
|
.WD1({UpdateInstrClass, UpdateTarget}),
|
||||||
|
.WEN1(UpdateEN),
|
||||||
|
.BitWEN1({`XLEN{1'b1}}));
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
80
wally-pipelined/src/ifu/RAsPredictor.sv
Normal file
80
wally-pipelined/src/ifu/RAsPredictor.sv
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// RASPredictor.sv
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 15, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: 2 bit saturating counter predictor with parameterized table depth.
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module RASPredictor
|
||||||
|
#(parameter int StackSize = 16
|
||||||
|
)
|
||||||
|
(input logic clk,
|
||||||
|
input logic reset,
|
||||||
|
input logic pop,
|
||||||
|
output logic [`XLEN-1:0] popPC,
|
||||||
|
input logic push,
|
||||||
|
input logic incr,
|
||||||
|
input logic [`XLEN-1:0] pushPC
|
||||||
|
);
|
||||||
|
|
||||||
|
logic CounterEn;
|
||||||
|
localparam Depth = $clog2(StackSize);
|
||||||
|
|
||||||
|
logic [StackSize-1:0] PtrD, PtrQ, PtrP1, PtrM1;
|
||||||
|
logic [StackSize-1:0] [`XLEN-1:0] memory;
|
||||||
|
integer index;
|
||||||
|
|
||||||
|
assign CounterEn = pop | push | incr;
|
||||||
|
|
||||||
|
assign PtrD = pop ? PtrM1 : PtrP1;
|
||||||
|
|
||||||
|
assign PtrM1 = PtrQ - 1'b1;
|
||||||
|
assign PtrP1 = PtrQ + 1'b1;
|
||||||
|
// may have to handle a push and an incr at the same time.
|
||||||
|
// *** what happens if jal is executing and there is a return being flushed in Decode?
|
||||||
|
|
||||||
|
flopenr #(StackSize) PTR(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(CounterEn),
|
||||||
|
.d(PtrD),
|
||||||
|
.q(PtrQ));
|
||||||
|
|
||||||
|
// RAS must be reset.
|
||||||
|
always_ff @ (posedge clk, posedge reset) begin
|
||||||
|
if(reset) begin
|
||||||
|
for(index=0; index<StackSize; index++)
|
||||||
|
memory[index] <= {`XLEN{1'b0}};
|
||||||
|
end else if(push) begin
|
||||||
|
memory[PtrP1] <= #1 pushPC;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign popPC = memory[PtrQ];
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
111
wally-pipelined/src/ifu/SramModel.sv
Normal file
111
wally-pipelined/src/ifu/SramModel.sv
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// SRAM2P1R1W
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 14, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Behavioral model of two port SRAM. While this is synthesizable it will produce a flip flop based memory whi
|
||||||
|
// behaves with the timing of an SRAM typical of GF 14nm, 32nm, and 45nm.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// to preload this memory we can use the following command
|
||||||
|
// in modelsim's do file.
|
||||||
|
// mem load -infile <relative path to the text file > -format <bin|hex> <hierarchy to the memory.>
|
||||||
|
// example
|
||||||
|
// mem laod -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module SRAM2P1R1W
|
||||||
|
#(parameter int Depth = 10,
|
||||||
|
parameter int Width = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
(input logic clk,
|
||||||
|
// *** have to remove reset eventually
|
||||||
|
input logic reset,
|
||||||
|
|
||||||
|
// port 1 is read only
|
||||||
|
input logic [Depth-1:0] RA1,
|
||||||
|
output logic [Width-1:0] RD1,
|
||||||
|
input logic REN1,
|
||||||
|
|
||||||
|
// port 2 is write only
|
||||||
|
input logic [Depth-1:0] WA1,
|
||||||
|
input logic [Width-1:0] WD1,
|
||||||
|
input logic WEN1,
|
||||||
|
input logic [Width-1:0] BitWEN1
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
logic [Depth-1:0] RA1Q, WA1Q;
|
||||||
|
logic WEN1Q;
|
||||||
|
logic [Width-1:0] WD1Q;
|
||||||
|
|
||||||
|
logic [Width-1:0] memory [2**Depth-1:0];
|
||||||
|
|
||||||
|
|
||||||
|
// SRAMs address busses are always registered first.
|
||||||
|
|
||||||
|
flopenr #(Depth) RA1Reg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(REN1),
|
||||||
|
.d(RA1),
|
||||||
|
.q(RA1Q));
|
||||||
|
|
||||||
|
|
||||||
|
flopenr #(Depth) WA1Reg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(REN1),
|
||||||
|
.d(WA1),
|
||||||
|
.q(WA1Q));
|
||||||
|
|
||||||
|
flopenr #(1) WEN1Reg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(1'b1),
|
||||||
|
.d(WEN1),
|
||||||
|
.q(WEN1Q));
|
||||||
|
|
||||||
|
flopenr #(Width) WD1Reg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(REN1),
|
||||||
|
.d(WD1),
|
||||||
|
.q(WD1Q));
|
||||||
|
// read port
|
||||||
|
assign RD1 = memory[RA1Q];
|
||||||
|
|
||||||
|
genvar index;
|
||||||
|
|
||||||
|
// write port
|
||||||
|
generate
|
||||||
|
for (index = 0; index < Width; index = index + 1) begin
|
||||||
|
always_ff @ (posedge clk) begin
|
||||||
|
if (WEN1Q & BitWEN1[index]) begin
|
||||||
|
memory[WA1Q][index] <= WD1Q[index];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
169
wally-pipelined/src/ifu/bpred.sv
Normal file
169
wally-pipelined/src/ifu/bpred.sv
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// bpred.sv
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 12, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Branch prediction unit
|
||||||
|
// Produces a branch prediction based on branch history.
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module bpred
|
||||||
|
(input logic clk, reset,
|
||||||
|
input logic StallF, StallD, StallE, FlushF, FlushD, FlushE,
|
||||||
|
// Fetch stage
|
||||||
|
// the prediction
|
||||||
|
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
|
||||||
|
output logic [`XLEN-1:0] BPPredPCF,
|
||||||
|
output logic SelBPPredF,
|
||||||
|
// Update Predictor
|
||||||
|
input logic [`XLEN-1:0] PCE, // The address of the currently executing instruction
|
||||||
|
// 1 hot encoding
|
||||||
|
// return, jump register, jump, branch
|
||||||
|
// *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class.
|
||||||
|
// *** the specifics of how this is encode is subject to change.
|
||||||
|
input logic PCSrcE, // AKA Branch Taken
|
||||||
|
// Signals required to check the branch prediction accuracy.
|
||||||
|
input logic [`XLEN-1:0] PCTargetE, // The branch destination if the branch is taken.
|
||||||
|
input logic [`XLEN-1:0] PCD, // The address the branch predictor took.
|
||||||
|
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||||
|
input logic [3:0] InstrClassE,
|
||||||
|
// Report branch prediction status
|
||||||
|
output logic BPPredWrongE
|
||||||
|
);
|
||||||
|
|
||||||
|
logic BTBValidF;
|
||||||
|
logic [1:0] BPPredF, BPPredD, BPPredE, UpdateBPPredE;
|
||||||
|
|
||||||
|
logic [3:0] BPInstrClassF, BPInstrClassD, BPInstrClassE;
|
||||||
|
logic [`XLEN-1:0] BTBPredPCF, RASPCF;
|
||||||
|
logic TargetWrongE;
|
||||||
|
logic FallThroughWrongE;
|
||||||
|
logic PredictionDirWrongE;
|
||||||
|
logic PredictionPCWrongE;
|
||||||
|
logic [`XLEN-1:0] CorrectPCE;
|
||||||
|
|
||||||
|
|
||||||
|
// Part 1 branch direction prediction
|
||||||
|
|
||||||
|
twoBitPredictor DirPredictor(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.LookUpPC(PCNextF),
|
||||||
|
.Prediction(BPPredF),
|
||||||
|
// update
|
||||||
|
.UpdatePC(PCE),
|
||||||
|
.UpdateEN(InstrClassE[0]),
|
||||||
|
.UpdatePrediction(UpdateBPPredE));
|
||||||
|
|
||||||
|
// this predictor will have two pieces of data,
|
||||||
|
// 1) A direction (1 = Taken, 0 = Not Taken)
|
||||||
|
// 2) Any information which is necessary for the predictor to built it's next state.
|
||||||
|
// For a 2 bit table this is the prediction count.
|
||||||
|
|
||||||
|
assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) |
|
||||||
|
BPInstrClassF[3] |
|
||||||
|
(BPInstrClassF[2] & BTBValidF) |
|
||||||
|
BPInstrClassF[1] & BTBValidF) ;
|
||||||
|
|
||||||
|
|
||||||
|
// Part 2 Branch target address prediction
|
||||||
|
// *** For now the BTB will house the direct and indirect targets
|
||||||
|
|
||||||
|
BTBPredictor TargetPredictor(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.LookUpPC(PCNextF),
|
||||||
|
.TargetPC(BTBPredPCF),
|
||||||
|
.InstrClass(BPInstrClassF),
|
||||||
|
.Valid(BTBValidF),
|
||||||
|
// update
|
||||||
|
.UpdateEN(InstrClassE[2] | InstrClassE[1] | InstrClassE[0]),
|
||||||
|
.UpdatePC(PCE),
|
||||||
|
.UpdateTarget(PCTargetE),
|
||||||
|
.UpdateInstrClass(InstrClassE));
|
||||||
|
|
||||||
|
// need to forward when updating to the same address as reading.
|
||||||
|
//assign CorrectPCE = PCSrcE ? PCTargetE : PCLinkE;
|
||||||
|
//assign TargetPC = (PCE == PCNextF) ? CorrectPCE : BTBPredPCF;
|
||||||
|
|
||||||
|
// Part 3 RAS
|
||||||
|
// *** need to add the logic to restore RAS on flushes. We will use incr for this.
|
||||||
|
RASPredictor RASPredictor(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.pop(BPInstrClassF[3]),
|
||||||
|
.popPC(RASPCF),
|
||||||
|
.push(InstrClassE[3]),
|
||||||
|
.incr(1'b0),
|
||||||
|
.pushPC(PCLinkE));
|
||||||
|
|
||||||
|
assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The prediction and its results need to be passed through the pipeline
|
||||||
|
// *** for other predictors will will be different.
|
||||||
|
|
||||||
|
flopenrc #(2) BPPredRegD(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(~StallF),
|
||||||
|
.clear(FlushF),
|
||||||
|
.d(BPPredF),
|
||||||
|
.q(BPPredD));
|
||||||
|
|
||||||
|
flopenrc #(2) BPPredRegE(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(~StallD),
|
||||||
|
.clear(FlushD),
|
||||||
|
.d(BPPredD),
|
||||||
|
.q(BPPredE));
|
||||||
|
|
||||||
|
// pipeline the class
|
||||||
|
flopenrc #(4) InstrClassRegD(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(~StallF),
|
||||||
|
.clear(FlushF),
|
||||||
|
.d(BPInstrClassF),
|
||||||
|
.q(BPInstrClassD));
|
||||||
|
|
||||||
|
flopenrc #(4) InstrClassRegE(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(~StallD),
|
||||||
|
.clear(FlushD),
|
||||||
|
.d(BPInstrClassD),
|
||||||
|
.q(BPInstrClassE));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Check the prediction makes execution.
|
||||||
|
assign TargetWrongE = PCTargetE != PCD;
|
||||||
|
assign FallThroughWrongE = PCLinkE != PCD;
|
||||||
|
assign PredictionDirWrongE = (BPPredE[1] ^ PCSrcE) & InstrClassE[0];
|
||||||
|
assign PredictionPCWrongE = PCSrcE ? TargetWrongE : FallThroughWrongE;
|
||||||
|
assign BPPredWrongE = (PredictionPCWrongE | PredictionDirWrongE) & (|InstrClassE);
|
||||||
|
|
||||||
|
// Update predictors
|
||||||
|
|
||||||
|
satCounter2 BPDirUpdate(.BrDir(PCSrcE),
|
||||||
|
.OldState(BPPredE),
|
||||||
|
.NewState(UpdateBPPredE));
|
||||||
|
|
||||||
|
endmodule
|
@ -29,7 +29,7 @@
|
|||||||
module ifu (
|
module ifu (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||||
// Fetch
|
// Fetch
|
||||||
input logic [`XLEN-1:0] InstrInF,
|
input logic [`XLEN-1:0] InstrInF,
|
||||||
output logic [`XLEN-1:0] PCF,
|
output logic [`XLEN-1:0] PCF,
|
||||||
@ -37,13 +37,15 @@ module ifu (
|
|||||||
output logic InstrReadF,
|
output logic InstrReadF,
|
||||||
// Decode
|
// Decode
|
||||||
// Execute
|
// Execute
|
||||||
input logic PCSrcE,
|
output logic [`XLEN-1:0] PCLinkE,
|
||||||
input logic [`XLEN-1:0] PCTargetE,
|
input logic PCSrcE,
|
||||||
output logic [`XLEN-1:0] PCE,
|
input logic [`XLEN-1:0] PCTargetE,
|
||||||
|
output logic [`XLEN-1:0] PCE,
|
||||||
|
output logic BPPredWrongE,
|
||||||
// Mem
|
// Mem
|
||||||
input logic RetM, TrapM,
|
input logic RetM, TrapM,
|
||||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||||
output logic [31:0] InstrD, InstrM,
|
output logic [31:0] InstrD, InstrM,
|
||||||
output logic [`XLEN-1:0] PCM,
|
output logic [`XLEN-1:0] PCM,
|
||||||
// Writeback
|
// Writeback
|
||||||
output logic [`XLEN-1:0] PCLinkW,
|
output logic [`XLEN-1:0] PCLinkW,
|
||||||
@ -60,13 +62,14 @@ module ifu (
|
|||||||
output logic ITLBMissF, ITLBHitF,
|
output logic ITLBMissF, ITLBHitF,
|
||||||
// bogus
|
// bogus
|
||||||
input logic [15:0] rd2
|
input logic [15:0] rd2
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] UnalignedPCNextF, PCNextF;
|
logic [`XLEN-1:0] UnalignedPCNextF, PCNextF;
|
||||||
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
|
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
|
||||||
logic PrivilegedChangePCM;
|
logic PrivilegedChangePCM;
|
||||||
logic IllegalCompInstrD;
|
logic IllegalCompInstrD;
|
||||||
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkE, PCLinkM;
|
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM;
|
||||||
logic CompressedF;
|
logic CompressedF;
|
||||||
logic [31:0] InstrF, InstrRawD, InstrE, InstrW;
|
logic [31:0] InstrF, InstrRawD, InstrE, InstrW;
|
||||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||||
@ -81,6 +84,12 @@ module ifu (
|
|||||||
tlb #(3) itlb(clk, reset, SATP, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
|
tlb #(3) itlb(clk, reset, SATP, PCF, PageTableEntryF, ITLBWriteF, ITLBFlushF,
|
||||||
InstrPAdrF, ITLBMissF, ITLBHitF);
|
InstrPAdrF, ITLBMissF, ITLBHitF);
|
||||||
|
|
||||||
|
// branch predictor signals
|
||||||
|
logic SelBPPredF;
|
||||||
|
logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F;
|
||||||
|
logic [3:0] InstrClassD, InstrClassE;
|
||||||
|
|
||||||
|
|
||||||
// *** put memory interface on here, InstrF becomes output
|
// *** put memory interface on here, InstrF becomes output
|
||||||
//assign InstrPAdrF = PCF; // *** no MMU
|
//assign InstrPAdrF = PCF; // *** no MMU
|
||||||
//assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
|
//assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
|
||||||
@ -89,10 +98,48 @@ module ifu (
|
|||||||
assign PrivilegedChangePCM = RetM | TrapM;
|
assign PrivilegedChangePCM = RetM | TrapM;
|
||||||
|
|
||||||
|
|
||||||
mux3 #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
|
//mux3 #(`XLEN) pcmux(PCPlus2or4F, PCCorrectE, PrivilegedNextPCM, {PrivilegedChangePCM, BPPredWrongE}, UnalignedPCNextF);
|
||||||
|
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F),
|
||||||
|
.d1(BPPredPCF),
|
||||||
|
.s(SelBPPredF),
|
||||||
|
.y(PCNext0F));
|
||||||
|
|
||||||
|
mux2 #(`XLEN) pcmux1(.d0(PCNext0F),
|
||||||
|
.d1(PCCorrectE),
|
||||||
|
.s(BPPredWrongE),
|
||||||
|
.y(PCNext1F));
|
||||||
|
|
||||||
|
mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
|
||||||
|
.d1(PrivilegedNextPCM),
|
||||||
|
.s(PrivilegedChangePCM),
|
||||||
|
.y(UnalignedPCNextF));
|
||||||
|
|
||||||
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||||
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
|
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
|
||||||
|
|
||||||
|
// branch and jump predictor
|
||||||
|
// I am making the port connection explicit for now as I want to see them and they will be changing.
|
||||||
|
bpred bpred(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.StallF(StallF),
|
||||||
|
.StallD(StallD),
|
||||||
|
.StallE(1'b0), // *** may need this eventually
|
||||||
|
.FlushF(FlushF),
|
||||||
|
.FlushD(FlushD),
|
||||||
|
.FlushE(FlushE),
|
||||||
|
.PCNextF(PCNextF),
|
||||||
|
.BPPredPCF(BPPredPCF),
|
||||||
|
.SelBPPredF(SelBPPredF),
|
||||||
|
.PCE(PCE),
|
||||||
|
.PCSrcE(PCSrcE),
|
||||||
|
.PCTargetE(PCTargetE),
|
||||||
|
.PCD(PCD),
|
||||||
|
.PCLinkE(PCLinkE),
|
||||||
|
.InstrClassE(InstrClassE),
|
||||||
|
.BPPredWrongE(BPPredWrongE));
|
||||||
|
// The true correct target is PCTargetE if PCSrcE is 1 else it is the fall through PCLinkE.
|
||||||
|
assign PCCorrectE = PCSrcE ? PCTargetE : PCLinkE;
|
||||||
|
|
||||||
// pcadder
|
// pcadder
|
||||||
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
||||||
assign CompressedF = (InstrF[1:0] != 2'b11); // is it a 16-bit compressed instruction?
|
assign CompressedF = (InstrF[1:0] != 2'b11); // is it a 16-bit compressed instruction?
|
||||||
@ -124,6 +171,14 @@ module ifu (
|
|||||||
assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
assign IllegalIEUInstrFaultD = IllegalBaseInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
||||||
// *** combine these with others in better way, including M, F
|
// *** combine these with others in better way, including M, F
|
||||||
|
|
||||||
|
|
||||||
|
// the branch predictor needs a compact decoding of the instruction class.
|
||||||
|
// *** consider adding in the alternate return address x5 for returns.
|
||||||
|
assign InstrClassD[3] = InstrD[6:0] == 7'h67 && InstrD[19:15] == 5'h01; // return
|
||||||
|
assign InstrClassD[2] = InstrD[6:0] == 7'h67 && InstrD[19:15] != 5'h01; // jump register, but not return
|
||||||
|
assign InstrClassD[1] = InstrD[6:0] == 7'h6F; // jump
|
||||||
|
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
|
||||||
|
|
||||||
// Misaligned PC logic
|
// Misaligned PC logic
|
||||||
|
|
||||||
generate
|
generate
|
||||||
@ -147,6 +202,13 @@ module ifu (
|
|||||||
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
|
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
|
||||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later
|
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later
|
||||||
|
|
||||||
|
flopenrc #(4) InstrClassRegE(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(~StallD),
|
||||||
|
.clear(FlushD),
|
||||||
|
.d(InstrClassD),
|
||||||
|
.q(InstrClassE));
|
||||||
|
|
||||||
// seems like there should be a lower-cost way of doing this PC+2 or PC+4 for JAL.
|
// seems like there should be a lower-cost way of doing this PC+2 or PC+4 for JAL.
|
||||||
// either have ALU compute PC+2/4 and feed into ALUResult input of ResultMux or
|
// either have ALU compute PC+2/4 and feed into ALUResult input of ResultMux or
|
||||||
// have dedicated adder in Mem stage based on PCM + 2 or 4
|
// have dedicated adder in Mem stage based on PCM + 2 or 4
|
||||||
|
57
wally-pipelined/src/ifu/satCounter2.sv
Normal file
57
wally-pipelined/src/ifu/satCounter2.sv
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// satCounter2.sv
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 13, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: 2 bit starting counter
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module satCounter2
|
||||||
|
(input logic BrDir,
|
||||||
|
input logic [1:0] OldState,
|
||||||
|
output logic [1:0] NewState
|
||||||
|
);
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
case(OldState)
|
||||||
|
2'b00: begin
|
||||||
|
if(BrDir) NewState = 2'b01;
|
||||||
|
else NewState = 2'b00;
|
||||||
|
end
|
||||||
|
2'b01: begin
|
||||||
|
if(BrDir) NewState = 2'b10;
|
||||||
|
else NewState = 2'b00;
|
||||||
|
end
|
||||||
|
2'b10: begin
|
||||||
|
if(BrDir) NewState = 2'b11;
|
||||||
|
else NewState = 2'b01;
|
||||||
|
end
|
||||||
|
2'b11: begin
|
||||||
|
if(BrDir) NewState = 2'b11;
|
||||||
|
else NewState = 2'b10;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
84
wally-pipelined/src/ifu/twoBitPredictor.sv
Normal file
84
wally-pipelined/src/ifu/twoBitPredictor.sv
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// twoBitPredictor.sv
|
||||||
|
//
|
||||||
|
// Written: Ross Thomposn
|
||||||
|
// Email: ross1728@gmail.com
|
||||||
|
// Created: February 14, 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: 2 bit saturating counter predictor with parameterized table depth.
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module twoBitPredictor
|
||||||
|
#(parameter int Depth = 10
|
||||||
|
)
|
||||||
|
(input logic clk,
|
||||||
|
input logic reset,
|
||||||
|
input logic [`XLEN-1:0] LookUpPC,
|
||||||
|
output logic [1:0] Prediction,
|
||||||
|
// update
|
||||||
|
input logic [`XLEN-1:0] UpdatePC,
|
||||||
|
input logic UpdateEN,
|
||||||
|
input logic [1:0] UpdatePrediction
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [Depth-1:0] LookUpPCIndex, UpdatePCIndex;
|
||||||
|
logic [1:0] PredictionMemory;
|
||||||
|
logic DoForwarding, DoForwardingF;
|
||||||
|
logic [1:0] UpdatePredictionF;
|
||||||
|
|
||||||
|
|
||||||
|
// hashing function for indexing the PC
|
||||||
|
// We have Depth bits to index, but XLEN bits as the input.
|
||||||
|
// bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
|
||||||
|
// using compressed instructions. XOR bit 1 with the MSB of index.
|
||||||
|
assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
|
||||||
|
assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};
|
||||||
|
|
||||||
|
|
||||||
|
SRAM2P1R1W #(Depth, 2) memory(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.RA1(LookUpPCIndex),
|
||||||
|
.RD1(PredictionMemory),
|
||||||
|
.REN1(1'b1),
|
||||||
|
.WA1(UpdatePCIndex),
|
||||||
|
.WD1(UpdatePrediction),
|
||||||
|
.WEN1(UpdateEN),
|
||||||
|
.BitWEN1(2'b11));
|
||||||
|
|
||||||
|
// need to forward when updating to the same address as reading.
|
||||||
|
// first we compare to see if the update and lookup addreses are the same
|
||||||
|
assign DoForwarding = UpdatePCIndex == LookUpPCIndex;
|
||||||
|
|
||||||
|
// register the update value and the forwarding signal into the Fetch stage
|
||||||
|
flopr #(1) DoForwardingReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.d(DoForwarding),
|
||||||
|
.q(DoForwardingF));
|
||||||
|
|
||||||
|
flopr #(2) UpdatePredictionReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.d(UpdatePrediction),
|
||||||
|
.q(UpdatePredictionF));
|
||||||
|
|
||||||
|
assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
|
||||||
|
|
||||||
|
endmodule
|
@ -55,7 +55,7 @@ module wallypipelinedhart (
|
|||||||
|
|
||||||
// logic [1:0] ForwardAE, ForwardBE;
|
// logic [1:0] ForwardAE, ForwardBE;
|
||||||
logic StallF, StallD, StallE, StallM, StallW;
|
logic StallF, StallD, StallE, StallM, StallW;
|
||||||
logic FlushD, FlushE, FlushM, FlushW;
|
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||||
logic RetM, TrapM;
|
logic RetM, TrapM;
|
||||||
|
|
||||||
// new signals that must connect through DP
|
// new signals that must connect through DP
|
||||||
@ -66,7 +66,7 @@ module wallypipelinedhart (
|
|||||||
logic [2:0] Funct3E;
|
logic [2:0] Funct3E;
|
||||||
// logic [31:0] InstrF;
|
// logic [31:0] InstrF;
|
||||||
logic [31:0] InstrD, InstrM;
|
logic [31:0] InstrD, InstrM;
|
||||||
logic [`XLEN-1:0] PCE, PCM, PCLinkW;
|
logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
|
||||||
logic [`XLEN-1:0] PCTargetE;
|
logic [`XLEN-1:0] PCTargetE;
|
||||||
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
|
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
|
||||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||||
@ -101,13 +101,14 @@ module wallypipelinedhart (
|
|||||||
logic InstrReadF;
|
logic InstrReadF;
|
||||||
logic DataStall, InstrStall;
|
logic DataStall, InstrStall;
|
||||||
logic InstrAckD, MemAckW;
|
logic InstrAckD, MemAckW;
|
||||||
|
logic BPPredWrongE;
|
||||||
|
|
||||||
|
|
||||||
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
|
ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||||
|
|
||||||
ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
|
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
|
||||||
dmem dmem(.*); // data cache unit
|
dmem dmem(.*); // data cache unit
|
||||||
|
|
||||||
|
|
||||||
ahblite ebu(
|
ahblite ebu(
|
||||||
//.InstrReadF(1'b0),
|
//.InstrReadF(1'b0),
|
||||||
//.InstrRData(InstrF), // hook up InstrF later
|
//.InstrRData(InstrF), // hook up InstrF later
|
||||||
|
84
wally-pipelined/testbench/function_radix.sv
Normal file
84
wally-pipelined/testbench/function_radix.sv
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Ross Thompson
|
||||||
|
// November 05, 2019
|
||||||
|
// Oklahoma State University
|
||||||
|
|
||||||
|
module function_radix();
|
||||||
|
|
||||||
|
parameter PRELOAD_FILE = "funct_addr.txt";
|
||||||
|
|
||||||
|
integer memory_bank [];
|
||||||
|
integer index;
|
||||||
|
|
||||||
|
logic [`XLEN-1:0] pc;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$init_signal_spy("/riscv_mram_tb/dut/pc", "/riscv_mram_tb/function_radix/pc");
|
||||||
|
end
|
||||||
|
|
||||||
|
task automatic bin_search_min;
|
||||||
|
input integer pc;
|
||||||
|
input integer length;
|
||||||
|
ref integer array [];
|
||||||
|
output integer minval;
|
||||||
|
|
||||||
|
integer left, right;
|
||||||
|
integer mid;
|
||||||
|
|
||||||
|
begin
|
||||||
|
left = 0;
|
||||||
|
right = length;
|
||||||
|
while (left <= right) begin
|
||||||
|
mid = left + ((right - left) / 2);
|
||||||
|
if (array[mid] == pc) begin
|
||||||
|
minval = array[mid];
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
if (array[mid] < pc) begin
|
||||||
|
left = mid + 1;
|
||||||
|
end else begin
|
||||||
|
right = mid -1;
|
||||||
|
end
|
||||||
|
end // while (left <= right)
|
||||||
|
// if the element pc is now found, right and left will be equal at this point.
|
||||||
|
// we need to check if pc is less than the array at left or greather.
|
||||||
|
// if it is less than pc, then we select left as the index.
|
||||||
|
// if it is greather we want 1 less than left.
|
||||||
|
if (array[left] < pc) begin
|
||||||
|
minval = array[left];
|
||||||
|
return;
|
||||||
|
end else begin
|
||||||
|
minval = array[left-1];
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
|
||||||
|
// preload
|
||||||
|
initial $readmemh(PRELOAD_FILE, memory_bank);
|
||||||
|
|
||||||
|
// we need to count the number of lines in the file so we can set line_count.
|
||||||
|
integer fp;
|
||||||
|
integer line_count = 0;
|
||||||
|
logic [31:0] line;
|
||||||
|
initial begin
|
||||||
|
fp = $fopen(PRELOAD_FILE, "r");
|
||||||
|
// read line by line to count lines
|
||||||
|
if (fp) begin
|
||||||
|
while (! $feof(fp)) begin
|
||||||
|
$fscanf(fp, "%h\n", line);
|
||||||
|
line_count = line_count + 1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
$display("Cannot open file %s for reading.", PRELOAD_FILE);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(pc) begin
|
||||||
|
bin_search_min(pc, line_count, memory_bank, index);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule // function_radix
|
||||||
|
|
@ -368,7 +368,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);
|
||||||
reset = 1; # 22; reset = 0;
|
reset = 1; # 42; reset = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
// generate clock to sequence tests
|
// generate clock to sequence tests
|
||||||
@ -444,7 +444,11 @@ string tests32i[] = {
|
|||||||
reset = 1; # 17; reset = 0;
|
reset = 1; # 17; reset = 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end // always @ (negedge clk)
|
||||||
|
|
||||||
|
// track the current function or label
|
||||||
|
//function_rfunction_radix function_radix();
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
/* verilator lint_on STMTDLY */
|
/* verilator lint_on STMTDLY */
|
||||||
|
Loading…
Reference in New Issue
Block a user