From b91b54589e073909c2b88b882028a4270c14f9f1 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 24 May 2023 14:05:44 -0500 Subject: [PATCH] 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. --- config/rv32e/config.vh | 2 +- sim/wally-batch.do | 8 +-- sim/wave.do | 26 +++---- src/ieu/bmu/bmuctrl.sv | 30 ++++---- src/ieu/controller.sv | 43 ++++++------ src/ieu/datapath.sv | 108 ++++++++++++++-------------- src/ieu/extend.sv | 20 +++--- src/ieu/ieu.sv | 31 ++++----- src/ieu/regfile.sv | 12 ++-- src/ifu/ifu.sv | 120 ++++++++++++++++---------------- src/ifu/spill.sv | 27 ++++--- src/wally/wallypipelinedcore.sv | 71 +++++++++---------- 12 files changed, 236 insertions(+), 262 deletions(-) diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 242cc4edc..be5862f58 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -152,4 +152,4 @@ localparam ZBS_SUPPORTED = 0; localparam USE_SRAM = 0; `include "test-shared.vh" - \ No newline at end of file + diff --git a/sim/wally-batch.do b/sim/wally-batch.do index df49518c1..6b5acbb92 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -59,7 +59,7 @@ if {$argc >= 3} { # default to config/rv64ic, but allow this to be overridden at the command line. For example: # do wally-pipelined-batch.do ../config/rv32imc rv32imc 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 if { $coverage } { echo "wally-batch buildroot coverage" @@ -88,7 +88,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { exec ./slack-notifier/slack-notifier.py } 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 # 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 @@ -112,7 +112,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # **** fix this so we can pass any number of +defines. # 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 # 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 @@ -126,7 +126,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # power off -r /dut/core/* } 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 # remove +acc flag for faster sim during regressions if there is no need to access internal signals if {$coverage} { diff --git a/sim/wave.do b/sim/wave.do index 53d6eab21..b0cb91e3d 100644 --- a/sim/wave.do +++ b/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/STATUS_FS 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 -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 -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE -add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF -add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F +add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF +add wave -noupdate -expand -group Bpred -expand -group prediction -expand -group ex /testbench/dut/core/ifu/bpred/bpred/PCSrcE +add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF +add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE +add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCF +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 /testbench/dut/core/ieu/dp/regf/a1 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/FlushM 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/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/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/LHRNextW 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/LHRCommittedF +add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PHT/mem 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 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 @@ -625,3 +616,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update +WaveRestoreZoom {435627 ns} {435795 ns} diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index d1fa909d2..ad46ab728 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -27,9 +27,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module bmuctrl( +module bmuctrl import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Decode stage control signals input logic StallD, FlushD, // Stall, flush Decode stage @@ -76,13 +74,13 @@ module bmuctrl( always_comb begin // 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; - if (`ZBA_SUPPORTED) begin + if (P.ZBA_SUPPORTED) begin 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_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 endcase - if (`XLEN==64) + if (P.XLEN==64) 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_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 endcase end - if (`ZBB_SUPPORTED) begin + if (P.ZBB_SUPPORTED) begin 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_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])) 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 -// 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) // // coverage on 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_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 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 @@ -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_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu endcase - if (`XLEN==32) + if (P.XLEN==32) 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'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32) endcase - else if (`XLEN==64) + else if (P.XLEN==64) 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_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 endcase end - if (`ZBC_SUPPORTED) + if (P.ZBC_SUPPORTED) casez({OpD, Funct7D, Funct3D}) 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction endcase - if (`ZBS_SUPPORTED) begin // ZBS + if (P.ZBS_SUPPORTED) begin // ZBS 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_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_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset endcase - if (`XLEN==32) // ZBS 64-bit + if (P.XLEN==32) // ZBS 64-bit 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_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_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti endcase - else if (`XLEN==64) // ZBS 64-bit + else if (P.XLEN==64) // ZBS 64-bit 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?_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) endcase 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}) 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 @@ -176,5 +174,5 @@ module bmuctrl( assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); // 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 diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 25395825b..8839b9cad 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -27,10 +27,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - - -module controller( +module controller import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Decode stage control signals 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 // 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 Funct7ShiftZeroD, Funct7Shiftb5D; assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub - assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; - assign Funct7Shiftb5D = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D; + assign Funct7ShiftZeroD = (P.XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; + 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 INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101)); assign IFunctD = IShiftD | INoShiftD; 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 | - ((`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 | - ((`XLEN == 64) & (Funct3D == 3'b011)); + ((P.XLEN == 64) & (Funct3D == 3'b011)); assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches assign JFunctD = (Funct3D == 3'b000); assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101; end else begin:legalcheck2 assign IFunctD = 1; // Don't bother to separate out shift decoding 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 SFunctD = 1; // don't bother to check Funct3 for stores assign BFunctD = 1; // don't bother to check Funct3 for branches @@ -182,19 +179,19 @@ module controller( 7'b0000011: if (LFunctD) 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'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 else 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) 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'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 7'b0100011: if (SFunctD) 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'b0101111: if (`A_SUPPORTED) begin + 7'b0101111: if (P.A_SUPPORTED) begin 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 else if (InstrD[31:27] == 5'b00011) @@ -207,16 +204,16 @@ module controller( else if (MFunctD) 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'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 - 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 7'b1100011: if (BFunctD) ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches 7'b1100111: if (JFunctD) 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'b1110011: if (`ZICSR_SUPPORTED) begin + 7'b1110011: if (P.ZICSR_SUPPORTED) begin 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 else @@ -229,7 +226,7 @@ module controller( // Unswizzle control bits // 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. - 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 {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, @@ -247,17 +244,17 @@ module controller( assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // 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 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 BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor 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, .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 assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; end else assign sltD = (Funct3D == 3'b010); @@ -290,7 +287,7 @@ module controller( // Fences // Ordinary fence is presently a nop // 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; assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction? assign InvalidateICacheD = FenceID; @@ -338,5 +335,5 @@ module controller( // the synchronous DTIM cannot read immediately after 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 diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index df9216761..cb013ee9d 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -27,16 +27,14 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module datapath ( +module datapath import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Decode stage signals input logic [2:0] ImmSrcD, // Selects type of immediate extension input logic [31:0] InstrD, // Instruction in Decode stage // Execute stage signals - input logic [`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] PCE, // PC 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 StallE, FlushE, // Stall, flush Execute stage 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] BALUControlE, // ALU Control signals for B instructions in Execute Stage output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) - output logic [`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] IEUAdrE, // Address computed by ALU + 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 input logic StallM, FlushM, // Stall, flush Memory stage input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int - input logic [`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 [`XLEN-1:0] WriteDataM, // Write data in Memory stage + input logic [P.XLEN-1:0] FIntResM, // FPU integer result + output logic [P.XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes + output logic [P.XLEN-1:0] WriteDataM, // Write data in Memory stage // Writeback stage signals input logic StallW, FlushW, // Stall, flush Writeback stage input logic RegWriteW, IntDivW, // Write register file, integer divide instruction 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 [`XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result - input logic [`XLEN-1:0] ReadDataW, // Read data from LSU - input logic [`XLEN-1:0] CSRReadValW, // CSR read result - input logic [`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] FCvtIntResW, // FPU convert fp to integer result + input logic [P.XLEN-1:0] ReadDataW, // Read data from LSU + input logic [P.XLEN-1:0] CSRReadValW, // CSR read result + input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result + input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result // Hazard Unit signals 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 @@ -76,64 +74,64 @@ module datapath ( // Fetch stage signals // Decode stage signals - logic [`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] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2) + logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage logic [4:0] RdD; // Destination register in Decode stage // Execute stage signals - logic [`XLEN-1:0] R1E, R2E; // Source operands read from register file - logic [`XLEN-1:0] ImmExtE; // Extended immediate in Execute stage - logic [`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] R1E, R2E; // Source operands read from register file + logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage + logic [P.XLEN-1:0] SrcAE, SrcBE; // ALU operands + logic [P.XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ImmExtE or PC+4), result of execution stage // Memory stage signals - logic [`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] IEUResultM; // Result from execution stage + logic [P.XLEN-1:0] IFResultM; // Result from either IEU or single-cycle FPU op writing an integer register // Writeback stage signals - logic [`XLEN-1:0] SCResultW; // Store Conditional result - logic [`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 [`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] SCResultW; // Store Conditional result + logic [P.XLEN-1:0] ResultW; // Result to write to register file + logic [P.XLEN-1:0] IFResultW; // Result from either IEU or single-cycle FPU op writing an integer register + logic [P.XLEN-1:0] IFCvtResultW; // Result from IEU, signle-cycle FPU op, or 2-cycle FCVT float to int + 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 assign Rs1D = InstrD[19:15]; assign Rs2D = InstrD[24:20]; assign RdD = InstrD[11:7]; - regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); - extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD); + regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); + extend #(P.XLEN, P.A_SUPPORTED) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD); // Execute stage pipeline register and logic - flopenrc #(`XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); - flopenrc #(`XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); - flopenrc #(`XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); + flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); + flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); + flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E); flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); - mux3 #(`XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); - mux3 #(`XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); - comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); - mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); - mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); - alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE); - mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); - mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); + mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); + mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); + comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); + mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); + mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); + alu #(P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE); + mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); + mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); // Memory stage pipeline register - flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); - flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); - flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM); - flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); + flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); + flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); + flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM); + flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); // Writeback stage pipeline register and logic - flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); - flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); + flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); + flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); // floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt - if (`F_SUPPORTED) begin:fpmux - mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM); - mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW); - if (`IDIV_ON_FPU) begin - mux2 #(`XLEN) divresultmuxW(MDUResultW, FIntDivResultW, IntDivW, MulDivResultW); + if (P.F_SUPPORTED) begin:fpmux + mux2 #(P.XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM); + mux2 #(P.XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW); + if (P.IDIV_ON_FPU) begin + mux2 #(P.XLEN) divresultmuxW(MDUResultW, FIntDivResultW, IntDivW, MulDivResultW); end else begin assign MulDivResultW = MDUResultW; end @@ -142,9 +140,9 @@ module datapath ( assign IFCvtResultW = IFResultW; assign MulDivResultW = MDUResultW; 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 - 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; -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/extend.sv b/src/ieu/extend.sv index 51a10a46c..70a429b16 100644 --- a/src/ieu/extend.sv +++ b/src/ieu/extend.sv @@ -27,29 +27,27 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module extend ( +module extend #(parameter XLEN, A_SUPPORTED) ( 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 - 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 case(ImmSrcD) // 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) - 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) - 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) - 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) - 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 - 3'b101: if (`A_SUPPORTED) ImmExtD = 0; + 3'b101: if (A_SUPPORTED) ImmExtD = 0; else ImmExtD = undefined; default: ImmExtD = undefined; // undefined endcase diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 02fa1dd7c..daebc98f6 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -26,45 +26,44 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" -module ieu ( +module ieu import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Decode stage signals input logic [31:0] InstrD, // Instruction input logic IllegalIEUFPUInstrD, // Illegal instruction output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers // Execute stage signals - input logic [`XLEN-1:0] PCE, // PC - input logic [`XLEN-1:0] PCLinkE, // PC + 4 + input logic [P.XLEN-1:0] PCE, // PC + input logic [P.XLEN-1:0] PCLinkE, // PC + 4 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 - 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 [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 // Memory stage signals input logic SquashSCW, // Squash store conditional, from LSU output logic [1:0] MemRWM, // Read/write 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 [`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 - 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 InstrValidD, InstrValidE, InstrValidM,// Instruction is valid output logic BranchD, BranchE, output logic JumpD, JumpE, // Writeback stage signals - input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) - input logic [`XLEN-1:0] CSRReadValW, // CSR read value, - input logic [`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] FIntDivResultW, // Integer divide result from FPU fdivsqrt) + input logic [P.XLEN-1:0] CSRReadValW, // CSR read value, + input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result + input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result input logic FCvtIntW, // FPU converts float to int 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 input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic FlushD, FlushE, FlushM, FlushW, // Flush signals @@ -96,7 +95,7 @@ module ieu ( logic BranchSignedE; // Branch does signed comparison on operands logic MDUE; // Multiply/divide instruction -controller c( + controller #(P) c( .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, @@ -105,7 +104,7 @@ controller c( .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); - datapath dp( + datapath #(P) dp( .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, diff --git a/src/ieu/regfile.sv b/src/ieu/regfile.sv index 967a2101e..5eff24022 100644 --- a/src/ieu/regfile.sv +++ b/src/ieu/regfile.sv @@ -27,18 +27,16 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module regfile ( +module regfile #(parameter XLEN, E_SUPPORTED) ( input logic clk, reset, 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 [`XLEN-1:0] wd3, // Write data for port 3 - output logic [`XLEN-1:0] rd1, rd2); // Read data for ports 1, 2 + input logic [XLEN-1:0] wd3, // Write data for port 3 + 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; // Three ported register file diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 82e8a33b9..1b0c66ba5 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -25,9 +25,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module ifu ( +module ifu import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, input logic StallF, StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, @@ -39,31 +37,31 @@ module ifu ( input logic BranchD, BranchE, input logic JumpD, JumpE, // Bus interface - output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU - input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU + output logic [P.PA_BITS-1:0] IFUHADDR, // Bus address 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 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] IFUHBURST, // Bus burst 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 - 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 [`XLEN-1:0] IEUAdrE, // The branch/jump target address - input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address - output logic [`XLEN-1:0] PCE, // Execution stage instruction address + input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address + input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address + output logic [P.XLEN-1:0] PCE, // Execution stage instruction address output logic BPWrongE, // Prediction is wrong output logic BPWrongM, // Prediction is wrong // Mem 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. - output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence + input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. + 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] 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 [`XLEN-1:0] PCM, // Memory stage instruction address + output logic [P.XLEN-1:0] PCM, // Memory stage instruction address // branch predictor 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 @@ -79,10 +77,10 @@ module ifu ( output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) // mmu management 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 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_SUM, // Status CSR: Supervisor access to user memory 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 output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk 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 [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration 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 ICacheAccess, // Report I$ read 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 - 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 [`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 [`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 [`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 [`XLEN-1:0] PCF; // Fetch stage instruction address - logic [`PA_BITS-1:0] PCPF; // Physical address after address translation - logic [`XLEN+1:0] PCFExt; // + logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) + logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill + logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) + logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F + logic [P.XLEN-1:0] PCD; // Decode stage instruction address + logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence + logic [P.XLEN-1:0] PCF; // Fetch stage instruction address + logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation + logic [P.XLEN+1:0] PCFExt; // logic [31:0] IROMInstrF; // Instruction from the IROM 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 GatedStallD; // StallD gated by selected next spill // 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 CacheCommittedF; // I$ memory operation started, delay interrupts logic SelIROM; // PMA indicates instruction address is in the IROM @@ -145,8 +143,8 @@ module ifu ( // Spill Support ///////////////////////////////////////////////////////////////////////////////////////////// - if(`C_SUPPORTED) begin : Spill - spill #(`ICACHE_SUPPORTED) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, + if(P.C_SUPPORTED) begin : Spill + spill #(P) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, .InstrUpdateDAF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpill assign PCSpillNextF = PCNextF; @@ -159,7 +157,7 @@ module ifu ( // Memory management //////////////////////////////////////////////////////////////////////////////////////////////// - if(`ZICSR_SUPPORTED == 1) begin : immu + if(P.ZICSR_SUPPORTED == 1) begin : immu /////////////////////////////////////////// // sfence.vma causes TLB flushes /////////////////////////////////////////// @@ -172,7 +170,7 @@ module ifu ( flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(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, .PrivilegeModeW, .DisableTranslation(1'b0), .VAdr(PCFExt), @@ -193,7 +191,7 @@ module ifu ( end else begin 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 SelIROM = '0; end @@ -212,31 +210,31 @@ module ifu ( assign IgnoreRequest = ITLBMissF | FlushD; // 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; assign IROMce = ~GatedStallD | reset; 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 assign IFURWF = 2'b10; end - if (`BUS_SUPPORTED) begin : bus + if (P.BUS_SUPPORTED) begin : bus // **** must fix words per line vs beats per line as in lsu. - localparam WORDSPERLINE = `ICACHE_SUPPORTED ? `ICACHE_LINELENINBITS/`XLEN : 1; - localparam LOGBWPL = `ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1; - if(`ICACHE_SUPPORTED) begin : icache - localparam LINELEN = `ICACHE_SUPPORTED ? `ICACHE_LINELENINBITS : `XLEN; - localparam LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) + localparam WORDSPERLINE = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/P.XLEN : 1; + localparam LOGBWPL = P.ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1; + if(P.ICACHE_SUPPORTED) begin : icache + localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN; + 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 [`PA_BITS-1:0] ICacheBusAdr; + logic [P.PA_BITS-1:0] ICacheBusAdr; logic ICacheBusAck; logic [1:0] CacheBusRW, BusRW, CacheRWF; assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; - cache #(.LINELEN(`ICACHE_LINELENINBITS), - .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), - .NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) + cache #(.LINELEN(P.ICACHE_LINELENINBITS), + .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), + .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), .FetchBuffer, .CacheBusAck(ICacheBusAck), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), @@ -277,7 +275,7 @@ module ifu ( .Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer)); 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; assign IFUHBURST = 3'b0; assign {ICacheMiss, ICacheAccess, ICacheStallF} = '0; @@ -298,17 +296,17 @@ module ifu ( // PCNextF logic //////////////////////////////////////////////////////////////////////////////////////////////// - if(`ZICSR_SUPPORTED | `ZIFENCEI_SUPPORTED) - mux2 #(`XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF)); + if(P.ZICSR_SUPPORTED | P.ZIFENCEI_SUPPORTED) + mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF)); else assign PC2NextF = PC1NextF; - assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment - flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); + assign PCNextF = {UnalignedPCNextF[P.XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment + flopenl #(P.XLEN) pcreg(clk, reset, ~StallF, PCNextF, P.RESET_VECTOR[P.XLEN-1:0], PCF); // pcadder // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32 // *** 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. // Speeds up critical path as compared to selecting adder input based on CompressedF // *** consider gating PCPlus4F to provide the reset. @@ -320,14 +318,14 @@ module ifu ( if(reset) PCPlus2or4F = '0; else if (CompressedF) // add 2 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 //////////////////////////////////////////////////////////////////////////////////////////////// // Branch and Jump Predictor //////////////////////////////////////////////////////////////////////////////////////////////// - if (`BPRED_SUPPORTED) begin : bpred + if (P.BPRED_SUPPORTED) begin : bpred bpred bpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .InstrValidD, .InstrValidE, @@ -337,7 +335,7 @@ module ifu ( .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM); 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 {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0; assign NextValidPCE = PCE; @@ -348,10 +346,10 @@ module ifu ( // Decode stage pipeline register and compressed instruction decoding. //////////////////////////////////////////////////////////////////////////////////////////////// // 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 - if (`C_SUPPORTED) begin + if (P.C_SUPPORTED) begin logic IllegalCompInstrD; decompress decomp(.InstrRawD, .InstrD, .IllegalCompInstrD); 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. // 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. - assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE; + assign BranchMisalignedFaultE = (IEUAdrE[1] & ~P.C_SUPPORTED) & PCSrcE; flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM); // Instruction and PC/PCLink pipeline registers @@ -380,10 +378,10 @@ module ifu ( mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); - flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); - flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); - //flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); - //flopenr #(`XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE); + flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); + flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); + //flopenr #(P.XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); + //flopenr #(P.XLEN) PCPEReg(clk, reset, ~StallE, PCLinkD, PCLinkE); flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD); flopenrc #(1) CompressedEReg(clk, reset, FlushE, ~StallE, CompressedD, CompressedE); diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index 54c0f2261..27eaa4107 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -31,30 +31,29 @@ `include "wally-config.vh" -module spill #( - parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache -)(input logic clk, +module spill import cvw::*; #(parameter cvw_t P) ( + input logic clk, input logic reset, input logic StallD, FlushD, - input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage - input logic [`XLEN-1:2] PCPlus4F, // PCF + 4 - input logic [`XLEN-1:0] PCNextF, // The next PCF + input logic [P.XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage + input logic [P.XLEN-1:2] PCPlus4F, // PCF + 4 + 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 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 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 [`XLEN-1:0] PCSpillF, // 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 [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 [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 // 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; - localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1; + localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1; statetype CurrState, NextState; - logic [`XLEN-1:0] PCPlus2F; + logic [P.XLEN-1:0] PCPlus2F; logic TakeSpillF; logic SpillF; logic SelSpillF; @@ -66,11 +65,11 @@ module spill #( //////////////////////////////////////////////////////////////////////////////////////////////////// // 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 - 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 - 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 TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF)); + assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF)); always_ff @(posedge clk) if (reset | FlushD) CurrState <= #1 STATE_READY; diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index f6946ec60..343262e57 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -26,21 +26,18 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -//import cvw::*; // global CORE-V-Wally parameters -`include "wally-config.vh" - module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Privileged input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic [63:0] MTIME_CLINT, // Bus Interface - input logic [`AHBW-1:0] HRDATA, + input logic [P.AHBW-1:0] HRDATA, input logic HREADY, HRESP, output logic HCLK, HRESETn, - output logic [`PA_BITS-1:0] HADDR, - output logic [`AHBW-1:0] HWDATA, - output logic [`XLEN/8-1:0] HWSTRB, + output logic [P.PA_BITS-1:0] HADDR, + output logic [P.AHBW-1:0] HWDATA, + output logic [P.XLEN/8-1:0] HWSTRB, output logic HWRITE, output logic [2:0] HSIZE, output logic [2:0] HBURST, @@ -58,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic IntDivE, W64E; logic CSRReadM, CSRWriteM, PrivilegedM; logic [1:0] AtomicM; - logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; - logic [`XLEN-1:0] SrcAM; + logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; + logic [P.XLEN-1:0] SrcAM; logic [2:0] Funct3E; logic [31:0] InstrD; logic [31:0] InstrM, InstrOrigM; - logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE; - logic [`XLEN-1:0] PCM; - logic [`XLEN-1:0] CSRReadValW, MDUResultW; - logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF; + logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; + logic [P.XLEN-1:0] PCM; + logic [P.XLEN-1:0] CSRReadValW, MDUResultW; + logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [1:0] MemRWM; logic InstrValidD, InstrValidE, InstrValidM; logic InstrMisalignedFaultM; @@ -86,32 +83,32 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic [4:0] RdE, RdM, RdW; logic FPUStallD; logic FWriteIntE; - logic [`FLEN-1:0] FWriteDataM; - logic [`XLEN-1:0] FIntResM; - logic [`XLEN-1:0] FCvtIntResW; + logic [P.FLEN-1:0] FWriteDataM; + logic [P.XLEN-1:0] FIntResM; + logic [P.XLEN-1:0] FCvtIntResW; logic FCvtIntW; logic FDivBusyE; logic FRegWriteM; logic FCvtIntStallD; logic FpLoadStoreM; logic [4:0] SetFflagsM; - logic [`XLEN-1:0] FIntDivResultW; + logic [P.XLEN-1:0] FIntDivResultW; // memory management unit signals logic ITLBWriteF; logic ITLBMissF; - logic [`XLEN-1:0] SATP_REGW; + logic [P.XLEN-1:0] SATP_REGW; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] PrivilegeModeW; - logic [`XLEN-1:0] PTE; + logic [P.XLEN-1:0] PTE; logic [1:0] PageType; logic sfencevmaM; logic SelHPTW; // PMA checker signals - var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0]; - var logic [7:0] PMPCFG_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[P.PMP_ENTRIES-1:0]; // IMem stalls logic IFUStallF; @@ -119,14 +116,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( // cpu lsu interface logic [2:0] Funct3M; - logic [`XLEN-1:0] IEUAdrE; - logic [`XLEN-1:0] WriteDataM; - logic [`XLEN-1:0] IEUAdrM; - logic [`LLEN-1:0] ReadDataW; + logic [P.XLEN-1:0] IEUAdrE; + logic [P.XLEN-1:0] WriteDataM; + logic [P.XLEN-1:0] IEUAdrM; + logic [P.LLEN-1:0] ReadDataW; logic CommittedM; // AHB ifu interface - logic [`PA_BITS-1:0] IFUHADDR; + logic [P.PA_BITS-1:0] IFUHADDR; logic [2:0] IFUHBURST; logic [1:0] IFUHTRANS; logic [2:0] IFUHSIZE; @@ -134,9 +131,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic IFUHREADY; // AHB LSU interface - logic [`PA_BITS-1:0] LSUHADDR; - logic [`XLEN-1:0] LSUHWDATA; - logic [`XLEN/8-1:0] LSUHWSTRB; + logic [P.PA_BITS-1:0] LSUHADDR; + logic [P.XLEN-1:0] LSUHWDATA; + logic [P.XLEN/8-1:0] LSUHWSTRB; logic LSUHWRITE; logic LSUHREADY; @@ -165,7 +162,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic wfiM, IntPendingM; // 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, .InstrValidM, .InstrValidE, .InstrValidD, .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); // integer execution unit: integer register file, datapath and controller - ieu ieu(.clk, .reset, + ieu #(P) ieu(.clk, .reset, // Decode Stage interface .InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, // Execute Stage interface @@ -204,7 +201,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .RdE, .RdM, .FIntResM, .FlushDCacheM, .BranchD, .BranchE, .JumpD, .JumpE, // 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, // hazards .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, .LSUStallM); - if(`BUS_SUPPORTED) begin : ebu + if(P.BUS_SUPPORTED) begin : ebu ebu ebu(// IFU connections .clk, .reset, // IFU interface @@ -272,7 +269,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .FlushD, .FlushE, .FlushM, .FlushW); // privileged unit - if (`ZICSR_SUPPORTED) begin:priv + if (P.ZICSR_SUPPORTED) begin:priv privileged priv( .clk, .reset, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, @@ -306,7 +303,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // 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, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .IntDivE, .W64E, @@ -317,12 +314,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // floating point unit - if (`F_SUPPORTED) begin:fpu + if (P.F_SUPPORTED) begin:fpu fpu fpu( .clk, .reset, .FRM_REGW, // Rounding mode from CSR .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) .StallE, .StallM, .StallW, // stall signals from HZU .FlushE, .FlushM, .FlushW, // flush signals from HZU