forked from Github_Repos/cvw
		
	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 
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
-- 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(
 | 
			
		||||
  // Detect hazards
 | 
			
		||||
  input  logic       PCSrcE, CSRWritePendingDEM, RetM, TrapM,
 | 
			
		||||
  input  logic       BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
 | 
			
		||||
  input  logic       LoadStallD, MulDivStallD, CSRRdStallD,
 | 
			
		||||
  input  logic       InstrStall, DataStall,
 | 
			
		||||
  // Stall & flush outputs
 | 
			
		||||
  output logic       StallF, StallD, StallE, StallM, StallW,
 | 
			
		||||
  output logic       FlushD, FlushE, FlushM, FlushW
 | 
			
		||||
  output logic       FlushF, FlushD, FlushE, FlushM, FlushW
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic BranchFlushDE;
 | 
			
		||||
@ -51,7 +51,7 @@ module hazard(
 | 
			
		||||
  // A stage must stall if the next stage is stalled
 | 
			
		||||
  // If any stages are stalled, the first stage that isn't stalled must flush.
 | 
			
		||||
 | 
			
		||||
  assign BranchFlushDE = PCSrcE | RetM | TrapM;
 | 
			
		||||
  assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
 | 
			
		||||
 | 
			
		||||
  assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);  
 | 
			
		||||
  assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE);    // stall in decode if instruction is a load/mul/csr dependent on previous
 | 
			
		||||
@ -62,6 +62,7 @@ module hazard(
 | 
			
		||||
 | 
			
		||||
  // Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
 | 
			
		||||
  assign StallF = StallD | StallFCause;
 | 
			
		||||
 | 
			
		||||
  assign StallD = StallE | StallDCause;
 | 
			
		||||
  assign StallE = StallM | StallECause;
 | 
			
		||||
  assign StallM = StallW | StallMCause;
 | 
			
		||||
@ -73,6 +74,7 @@ module hazard(
 | 
			
		||||
  assign FirstUnstalledW = (~StallW & StallM);;
 | 
			
		||||
  
 | 
			
		||||
  // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
 | 
			
		||||
  assign FlushF = BPPredWrongE;
 | 
			
		||||
  assign FlushD = FirstUnstalledD || BranchFlushDE;  //  PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
 | 
			
		||||
  assign FlushE = FirstUnstalledE || BranchFlushDE; //LoadStallD | PCSrcE | RetM | TrapM;
 | 
			
		||||
  assign FlushM = FirstUnstalledM || RetM || TrapM;
 | 
			
		||||
 | 
			
		||||
@ -43,6 +43,7 @@ module controller(
 | 
			
		||||
  output logic       MemReadE, CSRReadE, // for Hazard Unit
 | 
			
		||||
  output logic [2:0] Funct3E,
 | 
			
		||||
  output logic       MulDivE, W64E,
 | 
			
		||||
  output logic       JumpE,		  
 | 
			
		||||
  // Memory stage control signals
 | 
			
		||||
  input  logic       StallM, FlushM,
 | 
			
		||||
  output logic [1:0] MemRWM,
 | 
			
		||||
@ -68,7 +69,7 @@ module controller(
 | 
			
		||||
  logic 	    RegWriteD, RegWriteE;
 | 
			
		||||
  logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
 | 
			
		||||
  logic [1:0] MemRWD, MemRWE;
 | 
			
		||||
  logic		    JumpD, JumpE;
 | 
			
		||||
  logic		    JumpD;
 | 
			
		||||
  logic		    BranchD, BranchE;
 | 
			
		||||
  logic	[1:0] ALUOpD;
 | 
			
		||||
  logic [4:0] ALUControlD;
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,9 @@ module datapath (
 | 
			
		||||
  input  logic [4:0]       ALUControlE,
 | 
			
		||||
  input  logic             ALUSrcAE, ALUSrcBE,
 | 
			
		||||
  input  logic             TargetSrcE, 
 | 
			
		||||
  input  logic             JumpE,
 | 
			
		||||
  input  logic [`XLEN-1:0] PCE,
 | 
			
		||||
  input  logic [`XLEN-1:0] PCLinkE,
 | 
			
		||||
  output logic [2:0]       FlagsE,
 | 
			
		||||
  output logic [`XLEN-1:0] PCTargetE,
 | 
			
		||||
  output logic [`XLEN-1:0] SrcAE, SrcBE,
 | 
			
		||||
@ -64,7 +66,9 @@ module datapath (
 | 
			
		||||
  // Execute stage signals
 | 
			
		||||
  logic [`XLEN-1:0] RD1E, RD2E;
 | 
			
		||||
  logic [`XLEN-1:0] ExtImmE;
 | 
			
		||||
  logic [`XLEN-1:0] PreSrcAE;
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] PreSrcAE, SrcAE2, SrcBE2;
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] ALUResultE;
 | 
			
		||||
  logic [`XLEN-1:0] WriteDataE;
 | 
			
		||||
  logic [`XLEN-1:0] TargetBaseE;
 | 
			
		||||
@ -93,8 +97,10 @@ module datapath (
 | 
			
		||||
  mux3  #(`XLEN)  faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE);
 | 
			
		||||
  mux3  #(`XLEN)  fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE);
 | 
			
		||||
  mux2  #(`XLEN)  srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
 | 
			
		||||
  mux2  #(`XLEN)  srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);  
 | 
			
		||||
  mux2  #(`XLEN)  srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);
 | 
			
		||||
  alu   #(`XLEN)  alu(SrcAE, SrcBE, ALUControlE, ALUResultE, FlagsE);
 | 
			
		||||
  mux2  #(`XLEN)  srcbmux2(SrcBE, {`XLEN{1'b0}}, JumpE, SrcBE2); // *** May be able to remove this mux.
 | 
			
		||||
  alu   #(`XLEN)  alu(SrcAE2, SrcBE2, ALUControlE, ALUResultE, FlagsE);
 | 
			
		||||
  mux2  #(`XLEN)  targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
 | 
			
		||||
  assign  PCTargetE = ExtImmE + TargetBaseE;
 | 
			
		||||
 | 
			
		||||
@ -109,6 +115,9 @@ module datapath (
 | 
			
		||||
  flopenrc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ~StallW, ALUResultM, ALUResultW);
 | 
			
		||||
  flopenrc #(5)    RdWEg(clk, reset, FlushW, ~StallW, RdM, RdW);
 | 
			
		||||
 | 
			
		||||
  // *** something is not right here.  Before the merge I found an issue with the jal instruction not writing
 | 
			
		||||
  // the link address through the alu.
 | 
			
		||||
  // not sure what changed.
 | 
			
		||||
  // handle Store Conditional result if atomic extension supported
 | 
			
		||||
  generate 
 | 
			
		||||
    if (`A_SUPPORTED)
 | 
			
		||||
@ -118,4 +127,11 @@ module datapath (
 | 
			
		||||
  endgenerate
 | 
			
		||||
 | 
			
		||||
  mux6  #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);	
 | 
			
		||||
/* -----\/----- EXCLUDED -----\/-----
 | 
			
		||||
  // This mux4:1 no longer needs to include PCLinkW.  This is set correctly in the execution stage.
 | 
			
		||||
  // *** need to look at how the decoder is coded to fix.
 | 
			
		||||
  mux4  #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, ResultSrcW, ResultW);	
 | 
			
		||||
>>>>>>> bp
 | 
			
		||||
 -----/\----- EXCLUDED -----/\----- */
 | 
			
		||||
 
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,7 @@ module ieu (
 | 
			
		||||
  output logic             IllegalBaseInstrFaultD,
 | 
			
		||||
  // Execute Stage interface
 | 
			
		||||
  input  logic [`XLEN-1:0] PCE, 
 | 
			
		||||
  input  logic [`XLEN-1:0] PCLinkE,
 | 
			
		||||
  output logic [`XLEN-1:0] PCTargetE,
 | 
			
		||||
  output logic             MulDivE, W64E,
 | 
			
		||||
  output logic [2:0]       Funct3E,
 | 
			
		||||
@ -72,6 +73,7 @@ module ieu (
 | 
			
		||||
  logic [1:0]       ForwardAE, ForwardBE;
 | 
			
		||||
  logic             RegWriteM, RegWriteW;
 | 
			
		||||
  logic             MemReadE, CSRReadE;
 | 
			
		||||
  logic             JumpE;
 | 
			
		||||
           
 | 
			
		||||
  controller c(.*);
 | 
			
		||||
  datapath   dp(.*);             
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										97
									
								
								wally-pipelined/src/ifu/BTBPredictor.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								wally-pipelined/src/ifu/BTBPredictor.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,97 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// SRAM2P1R1W
 | 
			
		||||
//
 | 
			
		||||
// Written: Ross Thomposn
 | 
			
		||||
// Email: ross1728@gmail.com
 | 
			
		||||
// Created: February 15, 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: BTB model.  Outputs type of instruction (currently 1 hot encoded. Probably want 
 | 
			
		||||
// to encode to reduce storage), valid, target PC.
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
 | 
			
		||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
 | 
			
		||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 | 
			
		||||
// is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 | 
			
		||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 | 
			
		||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module BTBPredictor
 | 
			
		||||
  #(parameter int Depth = 10
 | 
			
		||||
    )
 | 
			
		||||
  (input  logic clk,
 | 
			
		||||
   input logic 		    reset,
 | 
			
		||||
   input logic [`XLEN-1:0]  LookUpPC,
 | 
			
		||||
   output logic [`XLEN-1:0] TargetPC,
 | 
			
		||||
   output logic [3:0] 	    InstrClass,
 | 
			
		||||
   output logic 	    Valid,
 | 
			
		||||
   // update
 | 
			
		||||
   input logic 		    UpdateEN,
 | 
			
		||||
   input logic [`XLEN-1:0]  UpdatePC,
 | 
			
		||||
   input logic [`XLEN-1:0]  UpdateTarget,
 | 
			
		||||
   input logic [3:0] 	    UpdateInstrClass
 | 
			
		||||
   );
 | 
			
		||||
 | 
			
		||||
  localparam TotalDepth = 2 ** Depth;
 | 
			
		||||
  logic [TotalDepth-1:0]    ValidBits;
 | 
			
		||||
  logic [Depth-1:0] 	    LookUpPCIndex, UpdatePCIndex, LookUpPCIndexQ, UpdatePCIndexQ;
 | 
			
		||||
 | 
			
		||||
  // hashing function for indexing the PC
 | 
			
		||||
  // We have Depth bits to index, but XLEN bits as the input.
 | 
			
		||||
  // bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
 | 
			
		||||
  // using compressed instructions.  XOR bit 1 with the MSB of index.
 | 
			
		||||
  assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
 | 
			
		||||
  assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};  
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  flopenr #(Depth) UpdatePCIndexReg(.clk(clk),
 | 
			
		||||
				    .reset(reset),
 | 
			
		||||
				    .en(1'b1),
 | 
			
		||||
				    .d(UpdatePCIndex),
 | 
			
		||||
				    .q(UpdatePCIndexQ));
 | 
			
		||||
  
 | 
			
		||||
  // The valid bit must be resetable.
 | 
			
		||||
  always_ff @ (posedge clk) begin
 | 
			
		||||
    if (reset) begin
 | 
			
		||||
      ValidBits <= #1 {TotalDepth{1'b0}};
 | 
			
		||||
    end else if (UpdateEN) begin
 | 
			
		||||
      ValidBits[UpdatePCIndexQ] <= #1 1'b1;
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  flopenr #(Depth) LookupPCIndexReg(.clk(clk),
 | 
			
		||||
				    .reset(reset),
 | 
			
		||||
				    .en(1'b1),
 | 
			
		||||
				    .d(LookUpPCIndex),
 | 
			
		||||
				    .q(LookUpPCIndexQ));
 | 
			
		||||
 | 
			
		||||
  assign Valid = ValidBits[LookUpPCIndexQ];
 | 
			
		||||
 | 
			
		||||
  // the BTB contains the target address.
 | 
			
		||||
  // Another optimization may be using a PC relative address.
 | 
			
		||||
  // *** need to add forwarding.
 | 
			
		||||
 | 
			
		||||
  SRAM2P1R1W #(Depth, `XLEN+4) memory(.clk(clk),
 | 
			
		||||
				      .reset(reset),
 | 
			
		||||
				      .RA1(LookUpPCIndex),
 | 
			
		||||
				      .RD1({{InstrClass, TargetPC}}),
 | 
			
		||||
				      .REN1(1'b1),
 | 
			
		||||
				      .WA1(UpdatePCIndex),
 | 
			
		||||
				      .WD1({UpdateInstrClass, UpdateTarget}),
 | 
			
		||||
				      .WEN1(UpdateEN),
 | 
			
		||||
				      .BitWEN1({`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 (
 | 
			
		||||
  input  logic             clk, reset,
 | 
			
		||||
  input  logic             StallF, StallD, StallE, StallM, StallW,
 | 
			
		||||
  input  logic             FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
  input  logic             FlushF, FlushD, FlushE, FlushM, FlushW,
 | 
			
		||||
  // Fetch
 | 
			
		||||
  input  logic [`XLEN-1:0] InstrInF,
 | 
			
		||||
  output logic [`XLEN-1:0] PCF, 
 | 
			
		||||
@ -37,13 +37,15 @@ module ifu (
 | 
			
		||||
  output logic             InstrReadF,
 | 
			
		||||
  // Decode  
 | 
			
		||||
  // Execute
 | 
			
		||||
  input  logic             PCSrcE, 
 | 
			
		||||
  input  logic [`XLEN-1:0] PCTargetE,
 | 
			
		||||
  output logic [`XLEN-1:0] PCE, 
 | 
			
		||||
  output logic [`XLEN-1:0] PCLinkE,
 | 
			
		||||
  input logic 		   PCSrcE, 
 | 
			
		||||
  input logic [`XLEN-1:0]  PCTargetE,
 | 
			
		||||
  output logic [`XLEN-1:0] PCE,
 | 
			
		||||
  output logic 		   BPPredWrongE, 
 | 
			
		||||
  // Mem
 | 
			
		||||
  input  logic             RetM, TrapM, 
 | 
			
		||||
  input  logic [`XLEN-1:0] PrivilegedNextPCM, 
 | 
			
		||||
  output logic [31:0]      InstrD, InstrM,
 | 
			
		||||
  input logic 		   RetM, TrapM, 
 | 
			
		||||
  input logic [`XLEN-1:0]  PrivilegedNextPCM, 
 | 
			
		||||
  output logic [31:0] 	   InstrD, InstrM,
 | 
			
		||||
  output logic [`XLEN-1:0] PCM, 
 | 
			
		||||
  // Writeback
 | 
			
		||||
  output logic [`XLEN-1:0] PCLinkW,
 | 
			
		||||
@ -60,13 +62,14 @@ module ifu (
 | 
			
		||||
  output logic             ITLBMissF, ITLBHitF,
 | 
			
		||||
  // bogus
 | 
			
		||||
  input  logic [15:0] rd2
 | 
			
		||||
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN-1:0] UnalignedPCNextF, PCNextF;
 | 
			
		||||
  logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
 | 
			
		||||
  logic PrivilegedChangePCM;
 | 
			
		||||
  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 [31:0]     InstrF, InstrRawD, InstrE, InstrW;
 | 
			
		||||
  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,
 | 
			
		||||
    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
 | 
			
		||||
  //assign InstrPAdrF = PCF; // *** no MMU
 | 
			
		||||
  //assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
 | 
			
		||||
@ -89,10 +98,48 @@ module ifu (
 | 
			
		||||
  assign PrivilegedChangePCM = RetM | TrapM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  mux3    #(`XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
 | 
			
		||||
  //mux3    #(`XLEN) pcmux(PCPlus2or4F, PCCorrectE, PrivilegedNextPCM, {PrivilegedChangePCM, BPPredWrongE}, UnalignedPCNextF);
 | 
			
		||||
  mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F),
 | 
			
		||||
		       .d1(BPPredPCF),
 | 
			
		||||
		       .s(SelBPPredF),
 | 
			
		||||
		       .y(PCNext0F));
 | 
			
		||||
 | 
			
		||||
  mux2 #(`XLEN) pcmux1(.d0(PCNext0F),
 | 
			
		||||
		       .d1(PCCorrectE),
 | 
			
		||||
		       .s(BPPredWrongE),
 | 
			
		||||
		       .y(PCNext1F));
 | 
			
		||||
 | 
			
		||||
  mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
 | 
			
		||||
		       .d1(PrivilegedNextPCM),
 | 
			
		||||
		       .s(PrivilegedChangePCM),
 | 
			
		||||
		       .y(UnalignedPCNextF));
 | 
			
		||||
  
 | 
			
		||||
  assign  PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
 | 
			
		||||
  flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
 | 
			
		||||
 | 
			
		||||
  // branch and jump predictor
 | 
			
		||||
  // I am making the port connection explicit for now as I want to see them and they will be changing.
 | 
			
		||||
  bpred bpred(.clk(clk),
 | 
			
		||||
	      .reset(reset),
 | 
			
		||||
	      .StallF(StallF),
 | 
			
		||||
	      .StallD(StallD),
 | 
			
		||||
	      .StallE(1'b0),   // *** may need this eventually
 | 
			
		||||
	      .FlushF(FlushF),
 | 
			
		||||
	      .FlushD(FlushD),
 | 
			
		||||
	      .FlushE(FlushE),
 | 
			
		||||
	      .PCNextF(PCNextF),
 | 
			
		||||
	      .BPPredPCF(BPPredPCF),
 | 
			
		||||
	      .SelBPPredF(SelBPPredF),
 | 
			
		||||
	      .PCE(PCE),
 | 
			
		||||
	      .PCSrcE(PCSrcE),
 | 
			
		||||
	      .PCTargetE(PCTargetE),
 | 
			
		||||
	      .PCD(PCD),
 | 
			
		||||
	      .PCLinkE(PCLinkE),
 | 
			
		||||
	      .InstrClassE(InstrClassE),
 | 
			
		||||
	      .BPPredWrongE(BPPredWrongE));
 | 
			
		||||
  // The true correct target is PCTargetE if PCSrcE is 1 else it is the fall through PCLinkE.
 | 
			
		||||
  assign PCCorrectE =  PCSrcE ? PCTargetE : PCLinkE;
 | 
			
		||||
 | 
			
		||||
  // pcadder
 | 
			
		||||
  // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
 | 
			
		||||
  assign 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
 | 
			
		||||
  // *** combine these with others in better way, including M, F
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // the branch predictor needs a compact decoding of the instruction class.
 | 
			
		||||
  // *** consider adding in the alternate return address x5 for returns.
 | 
			
		||||
  assign InstrClassD[3] = InstrD[6:0] == 7'h67 && InstrD[19:15] == 5'h01; // return
 | 
			
		||||
  assign InstrClassD[2] = InstrD[6:0] == 7'h67 && InstrD[19:15] != 5'h01; // jump register, but not return
 | 
			
		||||
  assign InstrClassD[1] = InstrD[6:0] == 7'h6F; // jump
 | 
			
		||||
  assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
 | 
			
		||||
 | 
			
		||||
  // Misaligned PC logic
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
@ -147,6 +202,13 @@ module ifu (
 | 
			
		||||
  flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
 | 
			
		||||
  flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); // *** probably not needed; delete later
 | 
			
		||||
 | 
			
		||||
  flopenrc #(4) InstrClassRegE(.clk(clk),
 | 
			
		||||
			       .reset(reset),
 | 
			
		||||
			       .en(~StallD),
 | 
			
		||||
			       .clear(FlushD),
 | 
			
		||||
			       .d(InstrClassD),
 | 
			
		||||
			       .q(InstrClassE));
 | 
			
		||||
 | 
			
		||||
  // seems like there should be a lower-cost way of doing this PC+2 or PC+4 for JAL.  
 | 
			
		||||
  // either have ALU compute PC+2/4 and feed into ALUResult input of ResultMux or
 | 
			
		||||
  // have dedicated adder in Mem stage based on PCM + 2 or 4
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								wally-pipelined/src/ifu/satCounter2.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								wally-pipelined/src/ifu/satCounter2.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// satCounter2.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: Ross Thomposn
 | 
			
		||||
// Email: ross1728@gmail.com
 | 
			
		||||
// Created: February 13, 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: 2 bit starting counter
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
 | 
			
		||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
 | 
			
		||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 | 
			
		||||
// is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 | 
			
		||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 | 
			
		||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module satCounter2
 | 
			
		||||
  (input logic BrDir,
 | 
			
		||||
   input logic [1:0] OldState,
 | 
			
		||||
   output logic [1:0] NewState
 | 
			
		||||
   );
 | 
			
		||||
 | 
			
		||||
  always_comb begin
 | 
			
		||||
    case(OldState)
 | 
			
		||||
      2'b00: begin
 | 
			
		||||
	if(BrDir) NewState = 2'b01;
 | 
			
		||||
	else NewState = 2'b00;
 | 
			
		||||
      end
 | 
			
		||||
      2'b01: begin
 | 
			
		||||
	if(BrDir) NewState = 2'b10;
 | 
			
		||||
	else NewState = 2'b00;
 | 
			
		||||
      end
 | 
			
		||||
      2'b10: begin
 | 
			
		||||
	if(BrDir) NewState = 2'b11;
 | 
			
		||||
	else NewState = 2'b01;
 | 
			
		||||
      end
 | 
			
		||||
      2'b11: begin
 | 
			
		||||
	if(BrDir) NewState = 2'b11;
 | 
			
		||||
	else NewState = 2'b10;
 | 
			
		||||
      end
 | 
			
		||||
    endcase
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										84
									
								
								wally-pipelined/src/ifu/twoBitPredictor.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								wally-pipelined/src/ifu/twoBitPredictor.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// twoBitPredictor.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: Ross Thomposn
 | 
			
		||||
// Email: ross1728@gmail.com
 | 
			
		||||
// Created: February 14, 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: 2 bit saturating counter predictor with parameterized table depth.
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
 | 
			
		||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 
 | 
			
		||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 
 | 
			
		||||
// is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 | 
			
		||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 | 
			
		||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module twoBitPredictor
 | 
			
		||||
  #(parameter int Depth = 10
 | 
			
		||||
    )
 | 
			
		||||
  (input logic clk,
 | 
			
		||||
   input logic 		   reset,
 | 
			
		||||
   input logic [`XLEN-1:0] LookUpPC,
 | 
			
		||||
   output logic [1:0] 	   Prediction,
 | 
			
		||||
   // update
 | 
			
		||||
   input logic [`XLEN-1:0] UpdatePC,
 | 
			
		||||
   input logic 		   UpdateEN,
 | 
			
		||||
   input logic [1:0] 	   UpdatePrediction
 | 
			
		||||
   );
 | 
			
		||||
 | 
			
		||||
  logic [Depth-1:0] 	   LookUpPCIndex, UpdatePCIndex;
 | 
			
		||||
  logic [1:0] 		   PredictionMemory;
 | 
			
		||||
  logic 		   DoForwarding, DoForwardingF;
 | 
			
		||||
  logic [1:0] 		   UpdatePredictionF;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // hashing function for indexing the PC
 | 
			
		||||
  // We have Depth bits to index, but XLEN bits as the input.
 | 
			
		||||
  // bit 0 is always 0, bit 1 is 0 if using 4 byte instructions, but is not always 0 if
 | 
			
		||||
  // using compressed instructions.  XOR bit 1 with the MSB of index.
 | 
			
		||||
  assign UpdatePCIndex = {UpdatePC[Depth+1] ^ UpdatePC[1], UpdatePC[Depth:2]};
 | 
			
		||||
  assign LookUpPCIndex = {LookUpPC[Depth+1] ^ LookUpPC[1], LookUpPC[Depth:2]};  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  SRAM2P1R1W #(Depth, 2) memory(.clk(clk),
 | 
			
		||||
				.reset(reset),
 | 
			
		||||
				.RA1(LookUpPCIndex),
 | 
			
		||||
				.RD1(PredictionMemory),
 | 
			
		||||
				.REN1(1'b1),
 | 
			
		||||
				.WA1(UpdatePCIndex),
 | 
			
		||||
				.WD1(UpdatePrediction),
 | 
			
		||||
				.WEN1(UpdateEN),
 | 
			
		||||
				.BitWEN1(2'b11));
 | 
			
		||||
 | 
			
		||||
  // need to forward when updating to the same address as reading.
 | 
			
		||||
  // first we compare to see if the update and lookup addreses are the same
 | 
			
		||||
  assign DoForwarding = UpdatePCIndex == LookUpPCIndex;
 | 
			
		||||
 | 
			
		||||
  // register the update value and the forwarding signal into the Fetch stage
 | 
			
		||||
  flopr #(1) DoForwardingReg(.clk(clk),
 | 
			
		||||
			     .reset(reset),
 | 
			
		||||
			     .d(DoForwarding),
 | 
			
		||||
			     .q(DoForwardingF));
 | 
			
		||||
  
 | 
			
		||||
  flopr #(2) UpdatePredictionReg(.clk(clk),
 | 
			
		||||
				 .reset(reset),
 | 
			
		||||
				 .d(UpdatePrediction),
 | 
			
		||||
				 .q(UpdatePredictionF));
 | 
			
		||||
 | 
			
		||||
  assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
 | 
			
		||||
  
 | 
			
		||||
endmodule
 | 
			
		||||
@ -55,7 +55,7 @@ module wallypipelinedhart (
 | 
			
		||||
 | 
			
		||||
//  logic [1:0]  ForwardAE, ForwardBE;
 | 
			
		||||
  logic        StallF, StallD, StallE, StallM, StallW;
 | 
			
		||||
  logic        FlushD, FlushE, FlushM, FlushW;
 | 
			
		||||
  logic        FlushF, FlushD, FlushE, FlushM, FlushW;
 | 
			
		||||
  logic        RetM, TrapM;
 | 
			
		||||
 | 
			
		||||
  // new signals that must connect through DP
 | 
			
		||||
@ -66,7 +66,7 @@ module wallypipelinedhart (
 | 
			
		||||
  logic [2:0] Funct3E;
 | 
			
		||||
//  logic [31:0] InstrF;
 | 
			
		||||
  logic [31:0] InstrD, InstrM;
 | 
			
		||||
  logic [`XLEN-1:0] PCE, PCM, PCLinkW;
 | 
			
		||||
  logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
 | 
			
		||||
  logic [`XLEN-1:0] PCTargetE;
 | 
			
		||||
  logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
 | 
			
		||||
  logic [`XLEN-1:0] PrivilegedNextPCM;
 | 
			
		||||
@ -101,13 +101,14 @@ module wallypipelinedhart (
 | 
			
		||||
  logic             InstrReadF;
 | 
			
		||||
  logic             DataStall, InstrStall;
 | 
			
		||||
  logic             InstrAckD, MemAckW;
 | 
			
		||||
  logic 	    BPPredWrongE;
 | 
			
		||||
  
 | 
			
		||||
           
 | 
			
		||||
  ifu ifu(.InstrInF(InstrRData), .*); // instruction fetch unit: PC, branch prediction, instruction cache
 | 
			
		||||
 | 
			
		||||
  ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
 | 
			
		||||
  ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
 | 
			
		||||
  dmem dmem(.*); // data cache unit
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  ahblite ebu( 
 | 
			
		||||
    //.InstrReadF(1'b0),
 | 
			
		||||
    //.InstrRData(InstrF), // hook up InstrF later
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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"};
 | 
			
		||||
      $readmemh(memfilename, dut.imem.RAM);
 | 
			
		||||
      $readmemh(memfilename, dut.uncore.dtim.RAM);
 | 
			
		||||
      reset = 1; # 22; reset = 0;
 | 
			
		||||
      reset = 1; # 42; reset = 0;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  // generate clock to sequence tests
 | 
			
		||||
@ -444,7 +444,11 @@ string tests32i[] = {
 | 
			
		||||
          reset = 1; # 17; reset = 0;
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    end // always @ (negedge clk)
 | 
			
		||||
 | 
			
		||||
  // track the current function or label
 | 
			
		||||
  //function_rfunction_radix function_radix();
 | 
			
		||||
  
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
/* verilator lint_on STMTDLY */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user