Updated a large number of the source files to use parameters rather than `defines. Based on Lim's work. So far there is no simulation slow down.

This commit is contained in:
Ross Thompson 2023-05-24 14:05:44 -05:00
parent 930fb67308
commit b91b54589e
12 changed files with 236 additions and 262 deletions

View File

@ -152,4 +152,4 @@ localparam ZBS_SUPPORTED = 0;
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "test-shared.vh"

View File

@ -59,7 +59,7 @@ if {$argc >= 3} {
# default to config/rv64ic, but allow this to be overridden at the command line. For example: # default to config/rv64ic, but allow this to be overridden at the command line. For example:
# do wally-pipelined-batch.do ../config/rv32imc rv32imc # do wally-pipelined-batch.do ../config/rv32imc rv32imc
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation # start and run simulation
if { $coverage } { if { $coverage } {
echo "wally-batch buildroot coverage" echo "wally-batch buildroot coverage"
@ -88,7 +88,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
exec ./slack-notifier/slack-notifier.py exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "ahb"} { } elseif {$2 eq "ahb"} {
vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +define+RAM_LATENCY=$3 +define+BURST_EN=$4 vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt wkdir/work_${1}_${2}_${3}_${4}.testbench -work wkdir/work_${1}_${2}_${3}_${4} -G TEST=$2 -o testbenchopt vopt wkdir/work_${1}_${2}_${3}_${4}.testbench -work wkdir/work_${1}_${2}_${3}_${4} -G TEST=$2 -o testbenchopt
@ -112,7 +112,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# **** fix this so we can pass any number of +defines. # **** fix this so we can pass any number of +defines.
# only allows 3 right now # only allows 3 right now
vlog -lint -work wkdir/work_${1}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 $5 $6 $7 vlog -lint -work wkdir/work_${1}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 $5 $6 $7
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt wkdir/work_${1}_${3}_${4}.testbench -work wkdir/work_${1}_${3}_${4} -G TEST=$4 -o testbenchopt vopt wkdir/work_${1}_${3}_${4}.testbench -work wkdir/work_${1}_${3}_${4} -G TEST=$4 -o testbenchopt
@ -126,7 +126,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# power off -r /dut/core/* # power off -r /dut/core/*
} else { } else {
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$coverage} { if {$coverage} {

View File

@ -95,12 +95,12 @@ add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/
add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/FFLAGS_REGW add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/FFLAGS_REGW
add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/STATUS_FS add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/STATUS_FS
add wave -noupdate -expand -group Bpred -expand -group {branch update selection inputs} -divider {class check} add wave -noupdate -expand -group Bpred -expand -group {branch update selection inputs} -divider {class check}
add wave -noupdate -expand -group Bpred -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF
add wave -noupdate -expand -group Bpred -group prediction -expand -group ex /testbench/dut/core/ifu/bpred/bpred/PCSrcE add wave -noupdate -expand -group Bpred -expand -group prediction -expand -group ex /testbench/dut/core/ifu/bpred/bpred/PCSrcE
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCF
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F
add wave -noupdate -group RegFile -expand /testbench/dut/core/ieu/dp/regf/rf add wave -noupdate -group RegFile -expand /testbench/dut/core/ieu/dp/regf/rf
add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a1 add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a1
add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a2 add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a2
@ -593,23 +593,14 @@ add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred
add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/StallM add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/StallM
add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCNextF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCNextF
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRNextF
add wave -noupdate /testbench/dut/core/ifu/PCF add wave -noupdate /testbench/dut/core/ifu/PCF
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRF
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRD
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRE
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRM
add wave -noupdate -label BHT /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BHT/mem
add wave -noupdate /testbench/reset add wave -noupdate /testbench/reset
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BPDirPredD add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BPDirPredD
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCW
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BranchM add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BranchM
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRNextW
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewBPDirPredM add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewBPDirPredM
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PHT/mem
add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/LHRCommittedF
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 4} {12208 ns} 1} {{Cursor 4} {30 ns} 0} WaveRestoreCursors {{Cursor 4} {12208 ns} 1} {{Cursor 4} {435726 ns} 0}
quietly wave cursor active 2 quietly wave cursor active 2
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 194 configure wave -valuecolwidth 194
@ -625,3 +616,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {435627 ns} {435795 ns}

View File

@ -27,9 +27,7 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module bmuctrl import cvw::*; #(parameter cvw_t P) (
module bmuctrl(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage input logic StallD, FlushD, // Stall, flush Decode stage
@ -76,13 +74,13 @@ module bmuctrl(
always_comb begin always_comb begin
// BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD // BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction; BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction;
if (`ZBA_SUPPORTED) begin if (P.ZBA_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add
endcase endcase
if (`XLEN==64) if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw
@ -91,7 +89,7 @@ module bmuctrl(
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw
endcase endcase
end end
if (`ZBB_SUPPORTED) begin if (P.ZBB_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror
@ -100,13 +98,13 @@ module bmuctrl(
else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0]))
BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction
// // coverage off: This case can't occur in RV64 // // coverage off: This case can't occur in RV64
// 17'b0110011_0000100_100: if (`XLEN == 32) // 17'b0110011_0000100_100: if (P.XLEN == 32)
// BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) // BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
// // coverage on // // coverage on
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor
17'b0010011_011010?_101: if ((`XLEN == 32 ^ Funct7D[0]) & (Rs2D == 5'b11000)) 17'b0010011_011010?_101: if ((P.XLEN == 32 ^ Funct7D[0]) & (Rs2D == 5'b11000))
BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8 BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8
17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111) 17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111)
BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b
@ -115,12 +113,12 @@ module bmuctrl(
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // min 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu
endcase endcase
if (`XLEN==32) if (P.XLEN==32)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) 17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32) 17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32)
endcase endcase
else if (`XLEN==64) else if (P.XLEN==64)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64) 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64)
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw
@ -131,25 +129,25 @@ module bmuctrl(
BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction
endcase endcase
end end
if (`ZBC_SUPPORTED) if (P.ZBC_SUPPORTED)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction
endcase endcase
if (`ZBS_SUPPORTED) begin // ZBS if (P.ZBS_SUPPORTED) begin // ZBS
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset
endcase endcase
if (`XLEN==32) // ZBS 64-bit if (P.XLEN==32) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti
endcase endcase
else if (`XLEN==64) // ZBS 64-bit else if (P.XLEN==64) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64) 17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64)
17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64) 17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64)
@ -157,7 +155,7 @@ module bmuctrl(
17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) 17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64)
endcase endcase
end end
if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli 17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli
@ -176,5 +174,5 @@ module bmuctrl(
assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000);
// BMU Execute stage pipieline control register // BMU Execute stage pipieline control register
flopenrc#(9) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE}); flopenrc #(9) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE});
endmodule endmodule

View File

@ -27,10 +27,7 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module controller import cvw::*; #(parameter cvw_t P) (
module controller(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage input logic StallD, FlushD, // Stall, flush Decode stage
@ -142,30 +139,30 @@ module controller(
// Be rigorous about detecting illegal instructions if CSRs or bit manipulation is supported // Be rigorous about detecting illegal instructions if CSRs or bit manipulation is supported
// otherwise be cheap // otherwise be cheap
if (`ZICSR_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED | `ZBS_SUPPORTED) begin:legalcheck // Exact integer decoding if (P.ZICSR_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED | P.ZBC_SUPPORTED | P.ZBS_SUPPORTED) begin:legalcheck // Exact integer decoding
logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD; logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD;
logic Funct7ShiftZeroD, Funct7Shiftb5D; logic Funct7ShiftZeroD, Funct7Shiftb5D;
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub
assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; assign Funct7ShiftZeroD = (P.XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD;
assign Funct7Shiftb5D = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D; assign Funct7Shiftb5D = (P.XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D;
assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101)); assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
assign IFunctD = IShiftD | INoShiftD; assign IFunctD = IShiftD | INoShiftD;
assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD; assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD;
assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv assign MFunctD = (Funct7D == 7'b0000001) & (P.M_SUPPORTED | (P.ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 | assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 |
((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110)); ((P.XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 |
((`XLEN == 64) & (Funct3D == 3'b011)); ((P.XLEN == 64) & (Funct3D == 3'b011));
assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches
assign JFunctD = (Funct3D == 3'b000); assign JFunctD = (Funct3D == 3'b000);
assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101; assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101;
end else begin:legalcheck2 end else begin:legalcheck2
assign IFunctD = 1; // Don't bother to separate out shift decoding assign IFunctD = 1; // Don't bother to separate out shift decoding
assign RFunctD = ~Funct7D[0]; // Not a multiply assign RFunctD = ~Funct7D[0]; // Not a multiply
assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv assign MFunctD = Funct7D[0] & (P.M_SUPPORTED | (P.ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
assign LFunctD = 1; // don't bother to check Funct3 for loads assign LFunctD = 1; // don't bother to check Funct3 for loads
assign SFunctD = 1; // don't bother to check Funct3 for stores assign SFunctD = 1; // don't bother to check Funct3 for stores
assign BFunctD = 1; // don't bother to check Funct3 for branches assign BFunctD = 1; // don't bother to check Funct3 for branches
@ -182,19 +179,19 @@ module controller(
7'b0000011: if (LFunctD) 7'b0000011: if (LFunctD)
ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // loads ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // loads
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
7'b0001111: if (`ZIFENCEI_SUPPORTED) 7'b0001111: if (P.ZIFENCEI_SUPPORTED)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
7'b0010011: if (IFunctD) 7'b0010011: if (IFunctD)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
7'b0011011: if (IFunctD & IWValidFunct3D & `XLEN == 64) 7'b0011011: if (IFunctD & IWValidFunct3D & P.XLEN == 64)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
7'b0100011: if (SFunctD) 7'b0100011: if (SFunctD)
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores
7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_1; // fsw - only legal if FP supported 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_1; // fsw - only legal if FP supported
7'b0101111: if (`A_SUPPORTED) begin 7'b0101111: if (P.A_SUPPORTED) begin
if (InstrD[31:27] == 5'b00010) if (InstrD[31:27] == 5'b00010)
ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr
else if (InstrD[31:27] == 5'b00011) else if (InstrD[31:27] == 5'b00011)
@ -207,16 +204,16 @@ module controller(
else if (MFunctD) else if (MFunctD)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
7'b0111011: if (RFunctD & (`XLEN == 64)) 7'b0111011: if (RFunctD & (P.XLEN == 64))
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
else if (MFunctD & (`XLEN == 64)) else if (MFunctD & (P.XLEN == 64))
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
7'b1100011: if (BFunctD) 7'b1100011: if (BFunctD)
ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
7'b1100111: if (JFunctD) 7'b1100111: if (JFunctD)
ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal 7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal
7'b1110011: if (`ZICSR_SUPPORTED) begin 7'b1110011: if (P.ZICSR_SUPPORTED) begin
if (Funct3D == 3'b000) if (Funct3D == 3'b000)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
else else
@ -229,7 +226,7 @@ module controller(
// Unswizzle control bits // Unswizzle control bits
// Squash control signals if coming from an illegal compressed instruction // Squash control signals if coming from an illegal compressed instruction
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; assign IllegalERegAdrD = P.E_SUPPORTED & P.ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
//assign IllegalBaseInstrD = 1'b0; //assign IllegalBaseInstrD = 1'b0;
assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD,
@ -247,17 +244,17 @@ module controller(
assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD); assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD);
// bit manipulation Configuration Block // bit manipulation Configuration Block
if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags if (P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED | P.ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags
logic IllegalBitmanipInstrD; // Unrecognized B instruction logic IllegalBitmanipInstrD; // Unrecognized B instruction
logic BRegWriteD; // Indicates if it is a R type BMU instruction in decode stage logic BRegWriteD; // Indicates if it is a R type BMU instruction in decode stage
logic BW64D; // Indicates if it is a W type BMU instruction in decode stage logic BW64D; // Indicates if it is a W type BMU instruction in decode stage
logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor
logic BALUSrcBD; // BMU alu src select signal logic BALUSrcBD; // BMU alu src select signal
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, bmuctrl #(P) bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE); .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE);
if (`ZBA_SUPPORTED) begin if (P.ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ;
end else assign sltD = (Funct3D == 3'b010); end else assign sltD = (Funct3D == 3'b010);
@ -290,7 +287,7 @@ module controller(
// Fences // Fences
// Ordinary fence is presently a nop // Ordinary fence is presently a nop
// fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented // fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
if (`ZIFENCEI_SUPPORTED & `ICACHE_SUPPORTED) begin:fencei if (P.ZIFENCEI_SUPPORTED & P.ICACHE_SUPPORTED) begin:fencei
logic FenceID; logic FenceID;
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction? assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
assign InvalidateICacheD = FenceID; assign InvalidateICacheD = FenceID;
@ -338,5 +335,5 @@ module controller(
// the synchronous DTIM cannot read immediately after write // the synchronous DTIM cannot read immediately after write
// a cache cannot read or write immediately after a write // a cache cannot read or write immediately after a write
assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & `DCACHE_SUPPORTED)) | (|AtomicD)); assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & P.DCACHE_SUPPORTED)) | (|AtomicD));
endmodule endmodule

View File

@ -27,16 +27,14 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module datapath import cvw::*; #(parameter cvw_t P) (
module datapath (
input logic clk, reset, input logic clk, reset,
// Decode stage signals // Decode stage signals
input logic [2:0] ImmSrcD, // Selects type of immediate extension input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
// Execute stage signals // Execute stage signals
input logic [`XLEN-1:0] PCE, // PC in Execute stage input logic [P.XLEN-1:0] PCE, // PC in Execute stage
input logic [`XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage) input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage)
input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
@ -51,24 +49,24 @@ module datapath (
input logic [2:0] ZBBSelectE, // ZBB mux select signal input logic [2:0] ZBBSelectE, // ZBB mux select signal
input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [`XLEN-1:0] IEUAdrE, // Address computed by ALU output logic [P.XLEN-1:0] IEUAdrE, // Address computed by ALU
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B
// Memory stage signals // Memory stage signals
input logic StallM, FlushM, // Stall, flush Memory stage input logic StallM, FlushM, // Stall, flush Memory stage
input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int
input logic [`XLEN-1:0] FIntResM, // FPU integer result input logic [P.XLEN-1:0] FIntResM, // FPU integer result
output logic [`XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes output logic [P.XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes
output logic [`XLEN-1:0] WriteDataM, // Write data in Memory stage output logic [P.XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals // Writeback stage signals
input logic StallW, FlushW, // Stall, flush Writeback stage input logic StallW, FlushW, // Stall, flush Writeback stage
input logic RegWriteW, IntDivW, // Write register file, integer divide instruction input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic SquashSCW, // Squash a store conditional when a conflict arose input logic SquashSCW, // Squash a store conditional when a conflict arose
input logic [2:0] ResultSrcW, // Select source of result to write back to register file input logic [2:0] ResultSrcW, // Select source of result to write back to register file
input logic [`XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result input logic [P.XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result
input logic [`XLEN-1:0] ReadDataW, // Read data from LSU input logic [P.XLEN-1:0] ReadDataW, // Read data from LSU
input logic [`XLEN-1:0] CSRReadValW, // CSR read result input logic [P.XLEN-1:0] CSRReadValW, // CSR read result
input logic [`XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result
input logic [`XLEN-1:0] FIntDivResultW, // FPU's integer divide result input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
@ -76,64 +74,64 @@ module datapath (
// Fetch stage signals // Fetch stage signals
// Decode stage signals // Decode stage signals
logic [`XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2) logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [`XLEN-1:0] ImmExtD; // Extended immediate in Decode stage logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage
logic [4:0] RdD; // Destination register in Decode stage logic [4:0] RdD; // Destination register in Decode stage
// Execute stage signals // Execute stage signals
logic [`XLEN-1:0] R1E, R2E; // Source operands read from register file logic [P.XLEN-1:0] R1E, R2E; // Source operands read from register file
logic [`XLEN-1:0] ImmExtE; // Extended immediate in Execute stage logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage
logic [`XLEN-1:0] SrcAE, SrcBE; // ALU operands logic [P.XLEN-1:0] SrcAE, SrcBE; // ALU operands
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ImmExtE or PC+4), result of execution stage logic [P.XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ImmExtE or PC+4), result of execution stage
// Memory stage signals // Memory stage signals
logic [`XLEN-1:0] IEUResultM; // Result from execution stage logic [P.XLEN-1:0] IEUResultM; // Result from execution stage
logic [`XLEN-1:0] IFResultM; // Result from either IEU or single-cycle FPU op writing an integer register logic [P.XLEN-1:0] IFResultM; // Result from either IEU or single-cycle FPU op writing an integer register
// Writeback stage signals // Writeback stage signals
logic [`XLEN-1:0] SCResultW; // Store Conditional result logic [P.XLEN-1:0] SCResultW; // Store Conditional result
logic [`XLEN-1:0] ResultW; // Result to write to register file logic [P.XLEN-1:0] ResultW; // Result to write to register file
logic [`XLEN-1:0] IFResultW; // Result from either IEU or single-cycle FPU op writing an integer register logic [P.XLEN-1:0] IFResultW; // Result from either IEU or single-cycle FPU op writing an integer register
logic [`XLEN-1:0] IFCvtResultW; // Result from IEU, signle-cycle FPU op, or 2-cycle FCVT float to int logic [P.XLEN-1:0] IFCvtResultW; // Result from IEU, signle-cycle FPU op, or 2-cycle FCVT float to int
logic [`XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division) logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division)
// Decode stage // Decode stage
assign Rs1D = InstrD[19:15]; assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20]; assign Rs2D = InstrD[24:20];
assign RdD = InstrD[11:7]; assign RdD = InstrD[11:7];
regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD); extend #(P.XLEN, P.A_SUPPORTED) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD);
// Execute stage pipeline register and logic // Execute stage pipeline register and logic
flopenrc #(`XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
flopenrc #(`XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E);
flopenrc #(`XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE);
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E); flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
mux3 #(`XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE);
mux3 #(`XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE);
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE); alu #(P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
// Memory stage pipeline register // Memory stage pipeline register
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM);
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM); flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
// Writeback stage pipeline register and logic // Writeback stage pipeline register and logic
flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt // floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt
if (`F_SUPPORTED) begin:fpmux if (P.F_SUPPORTED) begin:fpmux
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM); mux2 #(P.XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW); mux2 #(P.XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
if (`IDIV_ON_FPU) begin if (P.IDIV_ON_FPU) begin
mux2 #(`XLEN) divresultmuxW(MDUResultW, FIntDivResultW, IntDivW, MulDivResultW); mux2 #(P.XLEN) divresultmuxW(MDUResultW, FIntDivResultW, IntDivW, MulDivResultW);
end else begin end else begin
assign MulDivResultW = MDUResultW; assign MulDivResultW = MDUResultW;
end end
@ -142,9 +140,9 @@ module datapath (
assign IFCvtResultW = IFResultW; assign IFCvtResultW = IFResultW;
assign MulDivResultW = MDUResultW; assign MulDivResultW = MDUResultW;
end end
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW); mux5 #(P.XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, ResultW);
// handle Store Conditional result if atomic extension supported // handle Store Conditional result if atomic extension supported
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW}; if (P.A_SUPPORTED) assign SCResultW = {{(P.XLEN-1){1'b0}}, SquashSCW};
else assign SCResultW = 0; else assign SCResultW = 0;
endmodule endmodule

View File

@ -27,29 +27,27 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module extend #(parameter XLEN, A_SUPPORTED) (
module extend (
input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits) input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits)
input logic [2:0] ImmSrcD, // Select what kind of extension to perform input logic [2:0] ImmSrcD, // Select what kind of extension to perform
output logic [`XLEN-1:0 ] ImmExtD); // Extended immediate output logic [XLEN-1:0 ] ImmExtD); // Extended immediate
localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug localparam [XLEN-1:0] undefined = {(XLEN){1'bx}}; // could change to 0 after debug
always_comb always_comb
case(ImmSrcD) case(ImmSrcD)
// I-type // I-type
3'b000: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:20]}; 3'b000: ImmExtD = {{(XLEN-12){InstrD[31]}}, InstrD[31:20]};
// S-type (stores) // S-type (stores)
3'b001: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:25], InstrD[11:7]}; 3'b001: ImmExtD = {{(XLEN-12){InstrD[31]}}, InstrD[31:25], InstrD[11:7]};
// B-type (branches) // B-type (branches)
3'b010: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[7], InstrD[30:25], InstrD[11:8], 1'b0}; 3'b010: ImmExtD = {{(XLEN-12){InstrD[31]}}, InstrD[7], InstrD[30:25], InstrD[11:8], 1'b0};
// J-type (jal) // J-type (jal)
3'b011: ImmExtD = {{(`XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0}; 3'b011: ImmExtD = {{(XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0};
// U-type (lui, auipc) // U-type (lui, auipc)
3'b100: ImmExtD = {{(`XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0}; 3'b100: ImmExtD = {{(XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0};
// Store Conditional: zero offset // Store Conditional: zero offset
3'b101: if (`A_SUPPORTED) ImmExtD = 0; 3'b101: if (A_SUPPORTED) ImmExtD = 0;
else ImmExtD = undefined; else ImmExtD = undefined;
default: ImmExtD = undefined; // undefined default: ImmExtD = undefined; // undefined
endcase endcase

View File

@ -26,45 +26,44 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module ieu ( module ieu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
// Decode stage signals // Decode stage signals
input logic [31:0] InstrD, // Instruction input logic [31:0] InstrD, // Instruction
input logic IllegalIEUFPUInstrD, // Illegal instruction input logic IllegalIEUFPUInstrD, // Illegal instruction
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
// Execute stage signals // Execute stage signals
input logic [`XLEN-1:0] PCE, // PC input logic [P.XLEN-1:0] PCE, // PC
input logic [`XLEN-1:0] PCLinkE, // PC + 4 input logic [P.XLEN-1:0] PCLinkE, // PC + 4
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE) output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
output logic [`XLEN-1:0] IEUAdrE, // Memory address output logic [P.XLEN-1:0] IEUAdrE, // Memory address
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, // Funct3 instruction field output logic [2:0] Funct3E, // Funct3 instruction field
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
output logic [4:0] RdE, // Destination register output logic [4:0] RdE, // Destination register
// Memory stage signals // Memory stage signals
input logic SquashSCW, // Squash store conditional, from LSU input logic SquashSCW, // Squash store conditional, from LSU
output logic [1:0] MemRWM, // Read/write control goes to LSU output logic [1:0] MemRWM, // Read/write control goes to LSU
output logic [1:0] AtomicM, // Atomic control goes to LSU output logic [1:0] AtomicM, // Atomic control goes to LSU
output logic [`XLEN-1:0] WriteDataM, // Write data to LSU output logic [P.XLEN-1:0] WriteDataM, // Write data to LSU
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU output logic [P.XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
output logic [4:0] RdM, // Destination register output logic [4:0] RdM, // Destination register
input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) input logic [P.XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidD, InstrValidE, InstrValidM,// Instruction is valid output logic InstrValidD, InstrValidE, InstrValidM,// Instruction is valid
output logic BranchD, BranchE, output logic BranchD, BranchE,
output logic JumpD, JumpE, output logic JumpD, JumpE,
// Writeback stage signals // Writeback stage signals
input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) input logic [P.XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt)
input logic [`XLEN-1:0] CSRReadValW, // CSR read value, input logic [P.XLEN-1:0] CSRReadValW, // CSR read value,
input logic [`XLEN-1:0] MDUResultW, // multiply/divide unit result input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result
input logic [`XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result
input logic FCvtIntW, // FPU converts float to int input logic FCvtIntW, // FPU converts float to int
output logic [4:0] RdW, // Destination register output logic [4:0] RdW, // Destination register
input logic [`XLEN-1:0] ReadDataW, // LSU's read data input logic [P.XLEN-1:0] ReadDataW, // LSU's read data
// Hazard unit signals // Hazard unit signals
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
@ -96,7 +95,7 @@ module ieu (
logic BranchSignedE; // Branch does signed comparison on operands logic BranchSignedE; // Branch does signed comparison on operands
logic MDUE; // Multiply/divide instruction logic MDUE; // Multiply/divide instruction
controller c( controller #(P) c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
@ -105,7 +104,7 @@ controller c(
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);
datapath dp( datapath #(P) dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE,

View File

@ -27,18 +27,16 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module regfile #(parameter XLEN, E_SUPPORTED) (
module regfile (
input logic clk, reset, input logic clk, reset,
input logic we3, // Write enable input logic we3, // Write enable
input logic [4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3) input logic [4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3)
input logic [`XLEN-1:0] wd3, // Write data for port 3 input logic [XLEN-1:0] wd3, // Write data for port 3
output logic [`XLEN-1:0] rd1, rd2); // Read data for ports 1, 2 output logic [XLEN-1:0] rd1, rd2); // Read data for ports 1, 2
localparam NUMREGS = `E_SUPPORTED ? 16 : 32; // only 16 registers in E mode localparam NUMREGS = E_SUPPORTED ? 16 : 32; // only 16 registers in E mode
logic [`XLEN-1:0] rf[NUMREGS-1:1]; logic [XLEN-1:0] rf[NUMREGS-1:1];
integer i; integer i;
// Three ported register file // Three ported register file

View File

@ -25,9 +25,7 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module ifu import cvw::*; #(parameter cvw_t P) (
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 FlushD, FlushE, FlushM, FlushW,
@ -39,31 +37,31 @@ module ifu (
input logic BranchD, BranchE, input logic BranchD, BranchE,
input logic JumpD, JumpE, input logic JumpD, JumpE,
// Bus interface // Bus interface
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU output logic [P.PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU input logic [P.XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
input logic IFUHREADY, // Bus ready from IFU to EBU input logic IFUHREADY, // Bus ready from IFU to EBU
output logic IFUHWRITE, // Bus write operation from IFU to EBU output logic IFUHWRITE, // Bus write operation from IFU to EBU
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
output logic [`XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
// Execute // Execute
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic PCSrcE, // Executation stage branch is taken input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
output logic [`XLEN-1:0] PCE, // Execution stage instruction address output logic [P.XLEN-1:0] PCE, // Execution stage instruction address
output logic BPWrongE, // Prediction is wrong output logic BPWrongE, // Prediction is wrong
output logic BPWrongM, // Prediction is wrong output logic BPWrongM, // Prediction is wrong
// Mem // Mem
output logic CommittedF, // I$ or bus memory operation started, delay interrupts output logic CommittedF, // I$ or bus memory operation started, delay interrupts
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence output logic [P.XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
output logic [31:0] InstrD, // The decoded instruction in Decode stage output logic [31:0] InstrD, // The decoded instruction in Decode stage
output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [31:0] InstrM, // The decoded instruction in Memory stage
output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
output logic [`XLEN-1:0] PCM, // Memory stage instruction address output logic [P.XLEN-1:0] PCM, // Memory stage instruction address
// branch predictor // branch predictor
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
output logic BPDirPredWrongM, // Prediction direction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong
@ -79,10 +77,10 @@ module ifu (
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
// mmu management // mmu management
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
input logic ITLBWriteF, // Writes PTE and PageType to ITLB input logic ITLBWriteF, // Writes PTE and PageType to ITLB
input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration input logic [P.XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
input logic STATUS_MXR, // Status CSR: make executable page readable input logic STATUS_MXR, // Status CSR: make executable page readable
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
@ -90,8 +88,8 @@ module ifu (
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP address from privileged unit
output logic InstrAccessFaultF, // Instruction access fault output logic InstrAccessFaultF, // Instruction access fault
output logic ICacheAccess, // Report I$ read to performance counters output logic ICacheAccess, // Report I$ read to performance counters
output logic ICacheMiss // Report I$ miss to performance counters output logic ICacheMiss // Report I$ miss to performance counters
@ -99,17 +97,17 @@ module ifu (
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
logic [`XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill
logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
logic [`XLEN-1:0] PCD; // Decode stage instruction address logic [P.XLEN-1:0] PCD; // Decode stage instruction address
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
logic [`XLEN-1:0] PCF; // Fetch stage instruction address logic [P.XLEN-1:0] PCF; // Fetch stage instruction address
logic [`PA_BITS-1:0] PCPF; // Physical address after address translation logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation
logic [`XLEN+1:0] PCFExt; // logic [P.XLEN+1:0] PCFExt; //
logic [31:0] IROMInstrF; // Instruction from the IROM logic [31:0] IROMInstrF; // Instruction from the IROM
logic [31:0] ICacheInstrF; // Instruction from the I$ logic [31:0] ICacheInstrF; // Instruction from the I$
@ -133,7 +131,7 @@ module ifu (
logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation
logic GatedStallD; // StallD gated by selected next spill logic GatedStallD; // StallD gated by selected next spill
// branch predictor signal // branch predictor signal
logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF
logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic BusCommittedF; // Bus memory operation in flight, delay interrupts
logic CacheCommittedF; // I$ memory operation started, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts
logic SelIROM; // PMA indicates instruction address is in the IROM logic SelIROM; // PMA indicates instruction address is in the IROM
@ -145,8 +143,8 @@ module ifu (
// Spill Support // Spill Support
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if(`C_SUPPORTED) begin : Spill if(P.C_SUPPORTED) begin : Spill
spill #(`ICACHE_SUPPORTED) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, spill #(P) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF,
.InstrUpdateDAF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); .InstrUpdateDAF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpill end else begin : NoSpill
assign PCSpillNextF = PCNextF; assign PCSpillNextF = PCNextF;
@ -159,7 +157,7 @@ module ifu (
// Memory management // Memory management
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
if(`ZICSR_SUPPORTED == 1) begin : immu if(P.ZICSR_SUPPORTED == 1) begin : immu
/////////////////////////////////////////// ///////////////////////////////////////////
// sfence.vma causes TLB flushes // sfence.vma causes TLB flushes
/////////////////////////////////////////// ///////////////////////////////////////////
@ -172,7 +170,7 @@ module ifu (
flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ)); flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ));
assign TLBFlush = sfencevmaM & ~StallMQ; assign TLBFlush = sfencevmaM & ~StallMQ;
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) mmu #(.TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1))
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation(1'b0), .PrivilegeModeW, .DisableTranslation(1'b0),
.VAdr(PCFExt), .VAdr(PCFExt),
@ -193,7 +191,7 @@ module ifu (
end else begin end else begin
assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateDAF} = '0; assign {ITLBMissF, InstrAccessFaultF, InstrPageFaultF, InstrUpdateDAF} = '0;
assign PCPF = PCFExt[`PA_BITS-1:0]; assign PCPF = PCFExt[P.PA_BITS-1:0];
assign CacheableF = '1; assign CacheableF = '1;
assign SelIROM = '0; assign SelIROM = '0;
end end
@ -212,31 +210,31 @@ module ifu (
assign IgnoreRequest = ITLBMissF | FlushD; assign IgnoreRequest = ITLBMissF | FlushD;
// The IROM uses untranslated addresses, so it is not compatible with virtual memory. // The IROM uses untranslated addresses, so it is not compatible with virtual memory.
if (`IROM_SUPPORTED) begin : irom if (P.IROM_SUPPORTED) begin : irom
logic IROMce; logic IROMce;
assign IROMce = ~GatedStallD | reset; assign IROMce = ~GatedStallD | reset;
assign IFURWF = 2'b10; assign IFURWF = 2'b10;
irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[`XLEN-1:0]), .IROMInstrF); irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[P.XLEN-1:0]), .IROMInstrF);
end else begin end else begin
assign IFURWF = 2'b10; assign IFURWF = 2'b10;
end end
if (`BUS_SUPPORTED) begin : bus if (P.BUS_SUPPORTED) begin : bus
// **** must fix words per line vs beats per line as in lsu. // **** must fix words per line vs beats per line as in lsu.
localparam WORDSPERLINE = `ICACHE_SUPPORTED ? `ICACHE_LINELENINBITS/`XLEN : 1; localparam WORDSPERLINE = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/P.XLEN : 1;
localparam LOGBWPL = `ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1; localparam LOGBWPL = P.ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1;
if(`ICACHE_SUPPORTED) begin : icache if(P.ICACHE_SUPPORTED) begin : icache
localparam LINELEN = `ICACHE_SUPPORTED ? `ICACHE_LINELENINBITS : `XLEN; localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN;
localparam LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
logic [LINELEN-1:0] FetchBuffer; logic [LINELEN-1:0] FetchBuffer;
logic [`PA_BITS-1:0] ICacheBusAdr; logic [P.PA_BITS-1:0] ICacheBusAdr;
logic ICacheBusAck; logic ICacheBusAck;
logic [1:0] CacheBusRW, BusRW, CacheRWF; logic [1:0] CacheBusRW, BusRW, CacheRWF;
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0; assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
cache #(.LINELEN(`ICACHE_LINELENINBITS), cache #(.LINELEN(P.ICACHE_LINELENINBITS),
.NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
.NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD),
.FetchBuffer, .CacheBusAck(ICacheBusAck), .FetchBuffer, .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
@ -277,7 +275,7 @@ module ifu (
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer)); .Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
assign CacheCommittedF = '0; assign CacheCommittedF = '0;
if(`IROM_SUPPORTED) mux2 #(32) UnCachedDataMux2(FetchBuffer, IROMInstrF, SelIROM, InstrRawF); if(P.IROM_SUPPORTED) mux2 #(32) UnCachedDataMux2(FetchBuffer, IROMInstrF, SelIROM, InstrRawF);
else assign InstrRawF = FetchBuffer; else assign InstrRawF = FetchBuffer;
assign IFUHBURST = 3'b0; assign IFUHBURST = 3'b0;
assign {ICacheMiss, ICacheAccess, ICacheStallF} = '0; assign {ICacheMiss, ICacheAccess, ICacheStallF} = '0;
@ -298,17 +296,17 @@ module ifu (
// PCNextF logic // PCNextF logic
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED) if(P.ZICSR_SUPPORTED | P.ZIFENCEI_SUPPORTED)
mux2 #(`XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF)); mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
else assign PC2NextF = PC1NextF; else assign PC2NextF = PC1NextF;
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment assign PCNextF = {UnalignedPCNextF[P.XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); flopenl #(P.XLEN) pcreg(clk, reset, ~StallF, PCNextF, P.RESET_VECTOR[P.XLEN-1:0], PCF);
// 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
// *** consider using PCPlus2or4F = PCF + CompressedF ? 2 : 4; // *** consider using PCPlus2or4F = PCF + CompressedF ? 2 : 4;
assign PCPlus4F = PCF[`XLEN-1:2] + 1; // add 4 to PC assign PCPlus4F = PCF[P.XLEN-1:2] + 1; // add 4 to PC
// choose PC+2 or PC+4 based on CompressedF, which arrives later. // choose PC+2 or PC+4 based on CompressedF, which arrives later.
// Speeds up critical path as compared to selecting adder input based on CompressedF // Speeds up critical path as compared to selecting adder input based on CompressedF
// *** consider gating PCPlus4F to provide the reset. // *** consider gating PCPlus4F to provide the reset.
@ -320,14 +318,14 @@ module ifu (
if(reset) PCPlus2or4F = '0; if(reset) PCPlus2or4F = '0;
else if (CompressedF) // add 2 else if (CompressedF) // add 2
if (PCF[1]) PCPlus2or4F = {PCPlus4F, 2'b00}; if (PCF[1]) PCPlus2or4F = {PCPlus4F, 2'b00};
else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10};
else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4 else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Branch and Jump Predictor // Branch and Jump Predictor
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
if (`BPRED_SUPPORTED) begin : bpred if (P.BPRED_SUPPORTED) begin : bpred
bpred bpred(.clk, .reset, bpred bpred(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE, .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE,
@ -337,7 +335,7 @@ module ifu (
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM); .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM);
end else begin : bpred end else begin : bpred
mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF)); mux2 #(P.XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF));
assign BPWrongE = PCSrcE; assign BPWrongE = PCSrcE;
assign {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0; assign {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0;
assign NextValidPCE = PCE; assign NextValidPCE = PCE;
@ -348,10 +346,10 @@ module ifu (
// Decode stage pipeline register and compressed instruction decoding. // Decode stage pipeline register and compressed instruction decoding.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Decode stage pipeline register and logic // Decode stage pipeline register and logic
flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
// expand 16-bit compressed instructions to 32 bits // expand 16-bit compressed instructions to 32 bits
if (`C_SUPPORTED) begin if (P.C_SUPPORTED) begin
logic IllegalCompInstrD; logic IllegalCompInstrD;
decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD); decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD);
assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
@ -371,7 +369,7 @@ module ifu (
// only IALIGN=32, the two low bits (mepc[1:0]) are always zero. // only IALIGN=32, the two low bits (mepc[1:0]) are always zero.
// Spec 3.1.14 // Spec 3.1.14
// Traps: Cant happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec. // Traps: Cant happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec.
assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE; assign BranchMisalignedFaultE = (IEUAdrE[1] & ~P.C_SUPPORTED) & PCSrcE;
flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM); flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
// Instruction and PC/PCLink pipeline registers // Instruction and PC/PCLink pipeline registers
@ -380,10 +378,10 @@ module ifu (
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
//flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); //flopenr #(P.XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);
//flopenr #(`XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE); //flopenr #(P.XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE);
flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD); flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD);
flopenrc #(1) CompressedEReg(clk, reset, FlushE, ~StallE, CompressedD, CompressedE); flopenrc #(1) CompressedEReg(clk, reset, FlushE, ~StallE, CompressedD, CompressedE);

View File

@ -31,30 +31,29 @@
`include "wally-config.vh" `include "wally-config.vh"
module spill #( module spill import cvw::*; #(parameter cvw_t P) (
parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache input logic clk,
)(input logic clk,
input logic reset, input logic reset,
input logic StallD, FlushD, input logic StallD, FlushD,
input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage input logic [P.XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage
input logic [`XLEN-1:2] PCPlus4F, // PCF + 4 input logic [P.XLEN-1:2] PCPlus4F, // PCF + 4
input logic [`XLEN-1:0] PCNextF, // The next PCF input logic [P.XLEN-1:0] PCNextF, // The next PCF
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
input logic ITLBMissF, // ITLB miss, ignore memory request input logic ITLBMissF, // ITLB miss, ignore memory request
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
output logic [`XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill
output logic [`XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill
output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
output logic CompressedF); // The fetched instruction is compressed output logic CompressedF); // The fetched instruction is compressed
// Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1] // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1]
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1; localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1;
statetype CurrState, NextState; statetype CurrState, NextState;
logic [`XLEN-1:0] PCPlus2F; logic [P.XLEN-1:0] PCPlus2F;
logic TakeSpillF; logic TakeSpillF;
logic SpillF; logic SpillF;
logic SelSpillF; logic SelSpillF;
@ -66,11 +65,11 @@ module spill #(
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// compute PCF+2 from the raw PC+4 // compute PCF+2 from the raw PC+4
mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlus4F, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); mux2 #(P.XLEN) pcplus2mux(.d0({PCF[P.XLEN-1:2], 2'b10}), .d1({PCPlus4F, 2'b00}), .s(PCF[1]), .y(PCPlus2F));
// select between PCNextF and PCF+2 // select between PCNextF and PCF+2
mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelSpillNextF & ~FlushD), .y(PCSpillNextF)); mux2 #(P.XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelSpillNextF & ~FlushD), .y(PCSpillNextF));
// select between PCF and PCF+2 // select between PCF and PCF+2
mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCSpillF)); mux2 #(P.XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCSpillF));
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -78,7 +77,7 @@ module spill #(
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF));
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset | FlushD) CurrState <= #1 STATE_READY; if (reset | FlushD) CurrState <= #1 STATE_READY;

View File

@ -26,21 +26,18 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
//import cvw::*; // global CORE-V-Wally parameters
`include "wally-config.vh"
module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
// Privileged // Privileged
input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic MTimerInt, MExtInt, SExtInt, MSwInt,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
// Bus Interface // Bus Interface
input logic [`AHBW-1:0] HRDATA, input logic [P.AHBW-1:0] HRDATA,
input logic HREADY, HRESP, input logic HREADY, HRESP,
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
output logic [`PA_BITS-1:0] HADDR, output logic [P.PA_BITS-1:0] HADDR,
output logic [`AHBW-1:0] HWDATA, output logic [P.AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB, output logic [P.XLEN/8-1:0] HWSTRB,
output logic HWRITE, output logic HWRITE,
output logic [2:0] HSIZE, output logic [2:0] HSIZE,
output logic [2:0] HBURST, output logic [2:0] HBURST,
@ -58,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IntDivE, W64E; logic IntDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM; logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM; logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
logic [`XLEN-1:0] SrcAM; logic [P.XLEN-1:0] SrcAM;
logic [2:0] Funct3E; logic [2:0] Funct3E;
logic [31:0] InstrD; logic [31:0] InstrD;
logic [31:0] InstrM, InstrOrigM; logic [31:0] InstrM, InstrOrigM;
logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE; logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE;
logic [`XLEN-1:0] PCM; logic [P.XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW; logic [P.XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidD, InstrValidE, InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
@ -86,32 +83,32 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic [4:0] RdE, RdM, RdW; logic [4:0] RdE, RdM, RdW;
logic FPUStallD; logic FPUStallD;
logic FWriteIntE; logic FWriteIntE;
logic [`FLEN-1:0] FWriteDataM; logic [P.FLEN-1:0] FWriteDataM;
logic [`XLEN-1:0] FIntResM; logic [P.XLEN-1:0] FIntResM;
logic [`XLEN-1:0] FCvtIntResW; logic [P.XLEN-1:0] FCvtIntResW;
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic FRegWriteM; logic FRegWriteM;
logic FCvtIntStallD; logic FCvtIntStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [`XLEN-1:0] FIntDivResultW; logic [P.XLEN-1:0] FIntDivResultW;
// memory management unit signals // memory management unit signals
logic ITLBWriteF; logic ITLBWriteF;
logic ITLBMissF; logic ITLBMissF;
logic [`XLEN-1:0] SATP_REGW; logic [P.XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] STATUS_MPP, STATUS_FS;
logic [1:0] PrivilegeModeW; logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PTE; logic [P.XLEN-1:0] PTE;
logic [1:0] PageType; logic [1:0] PageType;
logic sfencevmaM; logic sfencevmaM;
logic SelHPTW; logic SelHPTW;
// PMA checker signals // PMA checker signals
var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0]; var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0];
// IMem stalls // IMem stalls
logic IFUStallF; logic IFUStallF;
@ -119,14 +116,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// cpu lsu interface // cpu lsu interface
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [`XLEN-1:0] IEUAdrE; logic [P.XLEN-1:0] IEUAdrE;
logic [`XLEN-1:0] WriteDataM; logic [P.XLEN-1:0] WriteDataM;
logic [`XLEN-1:0] IEUAdrM; logic [P.XLEN-1:0] IEUAdrM;
logic [`LLEN-1:0] ReadDataW; logic [P.LLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
logic [`PA_BITS-1:0] IFUHADDR; logic [P.PA_BITS-1:0] IFUHADDR;
logic [2:0] IFUHBURST; logic [2:0] IFUHBURST;
logic [1:0] IFUHTRANS; logic [1:0] IFUHTRANS;
logic [2:0] IFUHSIZE; logic [2:0] IFUHSIZE;
@ -134,9 +131,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IFUHREADY; logic IFUHREADY;
// AHB LSU interface // AHB LSU interface
logic [`PA_BITS-1:0] LSUHADDR; logic [P.PA_BITS-1:0] LSUHADDR;
logic [`XLEN-1:0] LSUHWDATA; logic [P.XLEN-1:0] LSUHWDATA;
logic [`XLEN/8-1:0] LSUHWSTRB; logic [P.XLEN/8-1:0] LSUHWSTRB;
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
@ -165,7 +162,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic wfiM, IntPendingM; logic wfiM, IntPendingM;
// instruction fetch unit: PC, branch prediction, instruction cache // instruction fetch unit: PC, branch prediction, instruction cache
ifu ifu(.clk, .reset, ifu #(P) ifu(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.InstrValidM, .InstrValidE, .InstrValidD, .InstrValidM, .InstrValidE, .InstrValidD,
.BranchD, .BranchE, .JumpD, .JumpE, .ICacheStallF, .BranchD, .BranchE, .JumpD, .JumpE, .ICacheStallF,
@ -188,7 +185,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF);
// integer execution unit: integer register file, datapath and controller // integer execution unit: integer register file, datapath and controller
ieu ieu(.clk, .reset, ieu #(P) ieu(.clk, .reset,
// Decode Stage interface // Decode Stage interface
.InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD,
// Execute Stage interface // Execute Stage interface
@ -204,7 +201,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.RdE, .RdM, .FIntResM, .FlushDCacheM, .RdE, .RdM, .FIntResM, .FlushDCacheM,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
// Writeback stage // Writeback stage
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[P.XLEN-1:0]),
.InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW, .InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
@ -244,7 +241,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); .LSUStallM);
if(`BUS_SUPPORTED) begin : ebu if(P.BUS_SUPPORTED) begin : ebu
ebu ebu(// IFU connections ebu ebu(// IFU connections
.clk, .reset, .clk, .reset,
// IFU interface // IFU interface
@ -272,7 +269,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.FlushD, .FlushE, .FlushM, .FlushW); .FlushD, .FlushE, .FlushM, .FlushW);
// privileged unit // privileged unit
if (`ZICSR_SUPPORTED) begin:priv if (P.ZICSR_SUPPORTED) begin:priv
privileged priv( privileged priv(
.clk, .reset, .clk, .reset,
.FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW,
@ -306,7 +303,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
end end
// multiply/divide unit // multiply/divide unit
if (`M_SUPPORTED | `ZMMUL_SUPPORTED) begin:mdu if (P.M_SUPPORTED | P.ZMMUL_SUPPORTED) begin:mdu
mdu mdu(.clk, .reset, .StallM, .StallW, .FlushE, .FlushM, .FlushW, mdu mdu(.clk, .reset, .StallM, .StallW, .FlushE, .FlushM, .FlushW,
.ForwardedSrcAE, .ForwardedSrcBE, .ForwardedSrcAE, .ForwardedSrcBE,
.Funct3E, .Funct3M, .IntDivE, .W64E, .Funct3E, .Funct3M, .IntDivE, .W64E,
@ -317,12 +314,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
end end
// floating point unit // floating point unit
if (`F_SUPPORTED) begin:fpu if (P.F_SUPPORTED) begin:fpu
fpu fpu( fpu fpu(
.clk, .reset, .clk, .reset,
.FRM_REGW, // Rounding mode from CSR .FRM_REGW, // Rounding mode from CSR
.InstrD, // instruction from IFU .InstrD, // instruction from IFU
.ReadDataW(ReadDataW[`FLEN-1:0]),// Read data from memory .ReadDataW(ReadDataW[P.FLEN-1:0]),// Read data from memory
.ForwardedSrcAE, // Integer input being processed (from IEU) .ForwardedSrcAE, // Integer input being processed (from IEU)
.StallE, .StallM, .StallW, // stall signals from HZU .StallE, .StallM, .StallW, // stall signals from HZU
.FlushE, .FlushM, .FlushW, // flush signals from HZU .FlushE, .FlushM, .FlushW, // flush signals from HZU