mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
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:
parent
930fb67308
commit
b91b54589e
@ -152,4 +152,4 @@ localparam ZBS_SUPPORTED = 0;
|
|||||||
localparam USE_SRAM = 0;
|
localparam USE_SRAM = 0;
|
||||||
|
|
||||||
`include "test-shared.vh"
|
`include "test-shared.vh"
|
||||||
|
|
||||||
|
@ -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} {
|
||||||
|
26
sim/wave.do
26
sim/wave.do
@ -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}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
120
src/ifu/ifu.sv
120
src/ifu/ifu.sv
@ -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: Can’t 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: Can’t 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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user