1
0
mirror of https://github.com/openhwgroup/cvw synced 2025-02-11 06:05:49 +00:00
This commit is contained in:
Madeleine Masser-Frye 2023-02-01 05:23:04 +00:00
commit a8ed39ecbe
16 changed files with 799 additions and 136 deletions

2
.gitignore vendored
View File

@ -134,3 +134,5 @@ fpga/src/CopiedFiles_do_not_add_to_repo/*
/fpga/generator/sim/imp-timesim.sdf /fpga/generator/sim/imp-timesim.sdf
/fpga/generator/sim/imp-timesim.v /fpga/generator/sim/imp-timesim.v
/fpga/generator/sim/syn-funcsim.v /fpga/generator/sim/syn-funcsim.v
external
pipelined/regression/results

54
bin/imperas-one-time.sh Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
###########################################
## imperas-one-time.sh
##
## Written: Ross Thompson (ross1728@gmail.com) and Lee Moore (moore@imperas.com)
## Created: 31 January 2023
## Modified: 31 January 2023
##
## Purpose: One time setup script for running imperas.
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https://solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
IMP_HASH=56b1479
# clone the Imperas repo
cd $WALY
if [ ! -d external ]; then
mkdir -p external
fi
pushd external
if [ ! -d ImperasDV-HMC ]; then
git clone git@github.com:Imperas/ImperasDV-HMC.git
fi
pushd ImperasDV-HMC
git checkout $IMP_HASH
popd
popd
# Setup Imperas
source ${WALLY}/external/ImperasDV-HMC/Imperas/bin/setup.sh
setupImperas ${WALLY}/external/ImperasDV-HMC/Imperas
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
# setup QUESTA (Imperas only command, YMMV)
#svsetup -questa

View File

@ -0,0 +1,26 @@
#--showoverrides
--override cpu/show_c_prefix=T
--override cpu/unaligned=F
--override cpu/mstatus_FS=1
# Enable the Imperas instruction coverage
-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
-override refRoot/cpu/cv/cover=basic
-override refRoot/cpu/cv/extensions=RV32I
# Add Imperas simulator application instruction tracing
--trace
--tracechange
--traceshowicount
--tracemode
--monitornetschange
# Turn on verbose output for Imperas simulator
--verbose
# Turn on verbose output for RISCV model
--override cpu/verbose=1
# Store simulator output to logfile
--output imperas.log

View File

@ -0,0 +1,22 @@
#!/bin/bash
if [ -d results ]; then
rm -rf results
fi
mkdir -p results
ALL=$(find ${WALLY}/external/ImperasDV-HMC/tests/riscof/work/riscv-arch-test/rv64i_m -name "ref" -type d)
export IMPERAS_TOOLS=$(pwd)/imperas.ic
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1"
for t in $ALL; do
export TESTDIR=$(dirname ${t})
OUTLOG=$(echo ${TESTDIR} | sed "s|${WALLY}/external/ImperasDV-HMC/tests/riscof/work|results|").log
OUTDIR=$(dirname ${OUTLOG})
echo "Running test ${TESTDIR} -> ${OUTDIR} :: ${OUTLOG}"
mkdir -p ${OUTDIR}
vsim -c -do "do wally-pipelined-imperas.do rv64gc"
mv transcript ${OUTLOG}
done

View File

@ -0,0 +1,32 @@
#!/bin/bash
###########################################
## imperas-one-time.sh
##
## Written: Ross Thompson (ross1728@gmail.com) and Lee Moore (moore@imperas.com)
## Created: 31 January 2023
## Modified: 31 January 2023
##
## Purpose: Run wally with imperas
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https://solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
IMPERAS_TOOLS=$(pwd)/imperas.ic \
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
TESTDIR=${WALLY}/external/ImperasDV-HMC/tests/riscof/work/riscv-arch-test/rv64i_m/F/src/fadd_b1-01.S \
vsim -c -do "do wally-pipelined-imperas.do rv64gc"

View File

@ -0,0 +1,55 @@
# wally-pipelined.do
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m"
# Use this wally-pipelined.do file to run this example.
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
# do wally-pipelined.do
# or, to run from a shell, type the following at the shell prompt:
# vsim -do wally-pipelined.do -c
# (omit the "-c" to see the GUI while running from the shell)
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 \
+incdir+../config/shared \
../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv \
../testbench/testbench_imperas.sv \
../testbench/common/*.sv \
../src/*/*.sv \
../src/*/*/*.sv \
-suppress 2583 \
-suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave
#-- display input and output signals as hexidecimal values
add log -recursive /*
do wave.do
run -all
noview ../testbench/testbench_imperas.sv
view wave

View File

@ -0,0 +1,63 @@
# wally-pipelined.do
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m"
# Use this wally-pipelined.do file to run this example.
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
# do wally-pipelined.do
# or, to run from a shell, type the following at the shell prompt:
# vsim -do wally-pipelined.do -c
# (omit the "-c" to see the GUI while running from the shell)
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 \
+incdir+../config/shared \
+define+USE_IMPERAS_DV \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-api-pkg.sv \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-trace.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/rvvi-pkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2api.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2log.sv \
../testbench/testbench_imperas.sv \
../testbench/common/*.sv \
../src/*/*.sv \
../src/*/*/*.sv \
-suppress 2583 \
-suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave
#-- display input and output signals as hexidecimal values
add log -recursive /*
do wave.do
run -all
noview ../testbench/testbench_imperas.sv
view wave

View File

@ -6,28 +6,28 @@ add wave -noupdate /testbench/reset
add wave -noupdate /testbench/reset_ext add wave -noupdate /testbench/reset_ext
add wave -noupdate /testbench/memfilename add wave -noupdate /testbench/memfilename
add wave -noupdate /testbench/dut/core/SATP_REGW add wave -noupdate /testbench/dut/core/SATP_REGW
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPPredWrongE add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/BPPredWrongE
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/RetM
add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM add wave -noupdate -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LoadStallD add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallF add wave -noupdate -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/MDUStallD add wave -noupdate -group HDU -group hazards /testbench/dut/core/MDUStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM
add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InterruptM add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InterruptM
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushD add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushD
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushE add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushE
add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushM add wave -noupdate -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushM

View File

@ -42,7 +42,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
logic CounterEn; logic CounterEn;
localparam Depth = $clog2(StackSize); localparam Depth = $clog2(StackSize);
logic [Depth-1:0] PtrD, PtrQ, PtrP1, PtrM1; logic [Depth-1:0] NextPtr, CurrPtr, PtrP1, PtrM1;
logic [StackSize-1:0] [`XLEN-1:0] memory; logic [StackSize-1:0] [`XLEN-1:0] memory;
integer index; integer index;
@ -52,30 +52,31 @@ module RASPredictor #(parameter int StackSize = 16 )(
logic IncrRepairD, DecRepairD; logic IncrRepairD, DecRepairD;
logic DecrementPtr; logic DecrementPtr;
logic FlushedRetDE;
logic WrongPredRetD;
assign PopF = PredInstrClassF[2] & ~StallD & ~FlushD; assign PopF = PredInstrClassF[2] & ~StallD & ~FlushD;
assign RepairD = ((WrongPredInstrClassD[2]) & ~StallE & ~FlushE) | // Wrong class undo increment or decrement.
(~StallE & FlushE & InstrClassD[2]) | // ret in decode flushed
(~StallM & FlushM & InstrClassE[2]) ; // ret in execution flushed
assign IncrRepairD = (~StallE & FlushE & InstrClassD[2]) | // ret in decode flushed
(~StallM & FlushM & InstrClassE[2]) | // ret in execution flushed
(WrongPredInstrClassD[2] & ~InstrClassD[2] & ~StallE & ~FlushE); // Guessed it was a ret, but its not
assign DecRepairD = (WrongPredInstrClassD[2] & InstrClassD[2] & ~StallE & ~FlushE); // Guessed non ret but is a ret.
assign PushE = InstrClassE[3] & ~StallM & ~FlushM; assign PushE = InstrClassE[3] & ~StallM & ~FlushM;
assign WrongPredRetD = (WrongPredInstrClassD[2]) & ~StallE & ~FlushE;
assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); // flushed ret
assign RepairD = WrongPredRetD | FlushedRetDE ;
assign IncrRepairD = FlushedRetDE | (WrongPredRetD & ~InstrClassD[2]); // Guessed it was a ret, but its not
assign DecRepairD = WrongPredRetD & InstrClassD[2]; // Guessed non ret but is a ret.
assign CounterEn = PopF | PushE | RepairD; assign CounterEn = PopF | PushE | RepairD;
assign DecrementPtr = (PopF | DecRepairD) & ~IncrRepairD; assign DecrementPtr = (PopF | DecRepairD) & ~IncrRepairD;
mux2 #(Depth) PtrMux(PtrP1, PtrM1, DecrementPtr, PtrD); mux2 #(Depth) PtrMux(PtrP1, PtrM1, DecrementPtr, NextPtr);
assign PtrM1 = PtrQ - 1'b1; assign PtrM1 = CurrPtr - 1'b1;
assign PtrP1 = PtrQ + 1'b1; assign PtrP1 = CurrPtr + 1'b1;
flopenr #(Depth) PTR(clk, reset, CounterEn, PtrD, PtrQ); flopenr #(Depth) PTR(clk, reset, CounterEn, NextPtr, CurrPtr);
// RAS must be reset. // RAS must be reset.
always_ff @ (posedge clk) begin always_ff @ (posedge clk) begin
@ -87,7 +88,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
end end
end end
assign RASPCF = memory[PtrQ]; assign RASPCF = memory[CurrPtr];
endmodule endmodule

View File

@ -117,8 +117,7 @@ module bpred (
end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor
speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE,
.BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), .PredInstrClassF, .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE);
.BranchInstrW(InstrClassW[0]), .WrongPredInstrClassD, .PCSrcE);
end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor
// *** Fix me // *** Fix me
@ -152,15 +151,6 @@ module bpred (
.IEUAdrE, .IEUAdrE,
.InstrClassE); .InstrClassE);
// Part 3 RAS
// *** need to add the logic to restore RAS on flushes. We will use incr for this.
// *** needs to include flushX
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.PredInstrClassF, .InstrClassD, .InstrClassE,
.WrongPredInstrClassD, .RASPCF, .PCLinkE);
assign BPPredPCF = PredInstrClassF[2] ? RASPCF : PredPCF;
// the branch predictor needs a compact decoding of the instruction class. // the branch predictor needs a compact decoding of the instruction class.
if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode
logic [4:0] CompressedOpcF; logic [4:0] CompressedOpcF;
@ -197,12 +187,19 @@ module bpred (
(PredInstrClassF[1] & PredValidF) ; (PredInstrClassF[1] & PredValidF) ;
end end
// Part 3 RAS
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.PredInstrClassF, .InstrClassD, .InstrClassE,
.WrongPredInstrClassD, .RASPCF, .PCLinkE);
assign BPPredPCF = PredInstrClassF[2] ? RASPCF : PredPCF;
assign InstrClassD[3] = (InstrD[6:0] & 7'h77) == 7'h67 & (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5 assign InstrClassD[3] = (InstrD[6:0] & 7'h77) == 7'h67 & (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or x5
assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5 assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5
assign InstrClassD[1] = (InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01) | // jump register, but not return assign InstrClassD[1] = (InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01) | // jump register, but not return
(InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01); // jump, RD != x1 or x5 (InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01); // jump, RD != x1 or x5
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE); flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM); flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
flopenrc #(4) InstrClassRegW(clk, reset, FlushW, ~StallW, InstrClassM, InstrClassW); flopenrc #(4) InstrClassRegW(clk, reset, FlushW, ~StallW, InstrClassM, InstrClassW);

View File

@ -29,37 +29,33 @@
`include "wally-config.vh" `include "wally-config.vh"
module speculativegshare #(parameter int k = 10 ) ( module speculativegshare #(parameter int k = 10 ) (
input logic clk, input logic clk,
input logic reset, input logic 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,
output logic [1:0] DirPredictionF, output logic [1:0] DirPredictionF,
output logic DirPredictionWrongE, output logic DirPredictionWrongE,
// update // update
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,
input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE,
input logic [3:0] WrongPredInstrClassD, input logic [3:0] WrongPredInstrClassD,
input logic PCSrcE input logic PCSrcE
); );
logic MatchF, MatchD, MatchE; logic MatchF, MatchD, MatchE;
logic MatchNextX, MatchXF; logic MatchNextX, MatchXF;
logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE;
logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE; logic [1:0] NewDirPredictionE;
logic [k-1:0] GHRF;
logic GHRExtraF;
logic [k-1:0] GHRD, GHRE, GHRM, GHRW;
logic [k-1:0] GHRNextF;
logic [k-1:0] GHRNextD;
logic [k-1:0] GHRNextE, GHRNextM, GHRNextW;
logic [k-1:0] IndexNextF, IndexF;
logic [k-1:0] IndexD, IndexE;
logic [k-1:0] GHRF, GHRD, GHRE;
logic GHRLastF;
logic [k-1:0] GHRNextF, GHRNextD, GHRNextE;
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE;
logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF; logic [1:0] ForwardNewDirPrediction, ForwardDirPredictionF;
logic FlushDOrDirWrong;
assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]}; assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]};
assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]}; assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]};
@ -71,20 +67,20 @@ module speculativegshare #(parameter int k = 10 ) (
.rd1(TableDirPredictionF), .rd1(TableDirPredictionF),
.wa2(IndexE), .wa2(IndexE),
.wd2(NewDirPredictionE), .wd2(NewDirPredictionE),
.we2(BranchInstrE & ~StallM & ~FlushM), .we2(InstrClassE[0]),
.bwe2(1'b1)); .bwe2(1'b1));
// if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage
// and then register for use in the Fetch stage. // and then register for use in the Fetch stage.
assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); assign MatchF = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF);
assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD);
assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE);
assign MatchNextX = MatchF | MatchD | MatchE; assign MatchNextX = MatchF | MatchD | MatchE;
flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF);
assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} :
MatchD ? NewDirPredictionD : MatchD ? {2{DirPredictionD[1]}} :
NewDirPredictionE ; NewDirPredictionE ;
flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF);
@ -95,49 +91,37 @@ module speculativegshare #(parameter int k = 10 ) (
flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD);
flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE); flopenr #(2) PredictionRegE(clk, reset, ~StallE, DirPredictionD, DirPredictionE);
// New prediction pipeline
assign NewDirPredictionF = {DirPredictionF[1], DirPredictionF[1]};
flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD);
satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE));
// GHR pipeline // GHR pipeline
// this version fails the regression test do to pessimistic x propagation.
// assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextD[k-1:0] :
// BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} :
// GHRF;
always_comb begin // If Fetch has a branch, speculatively insert prediction into the GHR
if(FlushD | DirPredictionWrongE) begin // If the front end is flushed or the direction prediction is wrong, reset to
GHRNextF = GHRNextD[k-1:0]; // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in.
end else if(BranchInstrF) GHRNextF = {DirPredictionF[1], GHRF[k-1:1]}; // For FlushE this is GHRE. GHRNextE is both.
else GHRNextF = GHRF; assign FlushDOrDirWrong = FlushD | DirPredictionWrongE;
end mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0],
{FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF);
flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift.
flopenr #(1) GHRFExtraReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRExtraF); flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF);
flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF);
// use with out instruction class prediction // With instruction class prediction, the class could be wrong and is checked in Decode.
//assign GHRNextD = FlushD ? GHRNextE[k-1:0] : GHRF[k-1:0]; // If it is wrong and branch does exist then shift right and insert the prediction.
// with instruction class prediction // If the branch does not exist then shift left and use GHRLastF to restore the LSB.
assign GHRNextD = (FlushD | DirPredictionWrongE) ? GHRNextE[k-1:0] : logic [k-1:0] GHRClassWrong;
WrongPredInstrClassD[0] & BranchInstrD ? {DirPredictionD[1], GHRF[k-1:1]} : // shift right mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, InstrClassD[0], GHRClassWrong);
WrongPredInstrClassD[0] & ~BranchInstrD ? {GHRF[k-2:0], GHRExtraF}: // shift left // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE.
GHRF[k-1:0]; mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD);
flopenr #(k) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); flopenr #(k) GHRDReg(clk, reset, ~StallD | FlushDOrDirWrong, GHRNextD, GHRD);
assign GHRNextE = BranchInstrE & ~FlushM ? {PCSrcE, GHRD[k-2:0]} : // if the branch is not flushed mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE);
FlushE ? GHRE : // branch is flushed
GHRD;
flopenr #(k) GHREReg(clk, reset, (BranchInstrE & ~StallE) | FlushE, GHRNextE, GHRE);
//assign GHRNextM = FlushM ? GHRM : GHRE; flopenr #(k) GHREReg(clk, reset, ((InstrClassE[0] & ~FlushM) & ~StallE) | FlushE, GHRNextE, GHRE);
//flopenr #(k) GHRMReg(clk, reset, (BranchInstrM & ~StallM) | FlushM, GHRNextM, GHRM);
//assign GHRNextW = FlushW ? GHRW : GHRM; assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0];
//flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW);
assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE;
endmodule endmodule

View File

@ -68,6 +68,7 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
end else begin: csrsr32 // RV32 end else begin: csrsr32 // RV32
assign MSTATUS_REGW = {STATUS_SD, 8'b0, assign MSTATUS_REGW = {STATUS_SD, 8'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,

View File

@ -0,0 +1,291 @@
`include "wally-config.vh"
`define NUM_REGS 32
`define NUM_CSRS 4096
`define PRINT_PC_INSTR 0
`define PRINT_MOST 0
`define PRINT_ALL 0
`define PRINT_CSRS 0
module wallyTracer(rvviTrace rvvi);
localparam NUMREGS = `E_SUPPORTED ? 16 : 32;
// wally specific signals
logic reset;
logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW;
logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW;
logic InstrValidM, InstrValidW;
logic StallE, StallM, StallW;
logic FlushD, FlushE, FlushM, FlushW;
logic TrapM, TrapW;
logic IntrF, IntrD, IntrE, IntrM, IntrW;
logic HaltM, HaltW;
logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] rf[NUMREGS];
logic [NUMREGS-1:0] rf_wb;
logic [4:0] rf_a3;
logic rf_we3;
logic [`XLEN-1:0] frf[32];
logic [`NUM_REGS-1:0] frf_wb;
logic [4:0] frf_a4;
logic frf_we4;
logic [`XLEN-1:0] CSRArray [logic[11:0]];
logic [`XLEN-1:0] CSRArrayOld [logic[11:0]];
logic [`NUM_CSRS-1:0] CSR_W;
logic CSRWriteM, CSRWriteW;
logic [11:0] CSRAdrM, CSRAdrW;
assign clk = testbench.dut.clk;
// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet
assign InstrValidD = testbench.dut.core.ieu.c.InstrValidD;
assign InstrValidE = testbench.dut.core.ieu.c.InstrValidE;
assign InstrValidM = testbench.dut.core.ieu.InstrValidM;
assign InstrRawD = testbench.dut.core.ifu.InstrRawD;
assign PCNextF = testbench.dut.core.ifu.PCNextF;
assign PCF = testbench.dut.core.ifu.PCF;
assign PCD = testbench.dut.core.ifu.PCD;
assign PCE = testbench.dut.core.ifu.PCE;
assign PCM = testbench.dut.core.ifu.PCM;
assign reset = testbench.reset;
assign StallF = testbench.dut.core.StallF;
assign StallD = testbench.dut.core.StallD;
assign StallE = testbench.dut.core.StallE;
assign StallM = testbench.dut.core.StallM;
assign StallW = testbench.dut.core.StallW;
assign FlushD = testbench.dut.core.FlushD;
assign FlushE = testbench.dut.core.FlushE;
assign FlushM = testbench.dut.core.FlushM;
assign FlushW = testbench.dut.core.FlushW;
assign TrapM = testbench.dut.core.TrapM;
assign HaltM = testbench.DCacheFlushStart;
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL;
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
logic valid;
always_comb begin
// Since we are detected the CSR change by comparing the old value we need to
// ensure the CSR is detected when the pipeline's Writeback stage is not
// stalled. If it is stalled we want CSRArray to hold the old value.
if(valid) begin
// machine CSRs
// *** missing PMP and performance counters.
CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW;
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW;
CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
CSRArray[12'h341] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW;
CSRArray[12'h306] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW;
CSRArray[12'h320] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW;
CSRArray[12'h302] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW;
CSRArray[12'h303] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW;
CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW;
CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW;
CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW;
CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW;
CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW;
CSRArray[12'h343] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW;
CSRArray[12'hF11] = 0;
CSRArray[12'hF12] = 0;
CSRArray[12'hF13] = `XLEN'h100;
CSRArray[12'hF15] = 0;
CSRArray[12'h34A] = 0;
// MCYCLE and MINSTRET
CSRArray[12'hB00] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0];
CSRArray[12'hB02] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2];
// supervisor CSRs
CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW;
CSRArray[12'h104] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222;
CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW;
CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW;
CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW;
CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW;
CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW;
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
// user CSRs
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
end else begin // hold the old value if the pipeline is stalled.
CSRArray[12'h300] = CSRArrayOld[12'h300];
CSRArray[12'h310] = CSRArrayOld[12'h310];
CSRArray[12'h305] = CSRArrayOld[12'h305];
CSRArray[12'h341] = CSRArrayOld[12'h341];
CSRArray[12'h306] = CSRArrayOld[12'h306];
CSRArray[12'h320] = CSRArrayOld[12'h320];
CSRArray[12'h302] = CSRArrayOld[12'h302];
CSRArray[12'h303] = CSRArrayOld[12'h303];
CSRArray[12'h344] = CSRArrayOld[12'h344];
CSRArray[12'h304] = CSRArrayOld[12'h304];
CSRArray[12'h301] = CSRArrayOld[12'h301];
CSRArray[12'hF14] = CSRArrayOld[12'hF14];
CSRArray[12'h340] = CSRArrayOld[12'h340];
CSRArray[12'h342] = CSRArrayOld[12'h342];
CSRArray[12'h343] = CSRArrayOld[12'h343];
CSRArray[12'hF11] = CSRArrayOld[12'hF11];
CSRArray[12'hF12] = CSRArrayOld[12'hF12];
CSRArray[12'hF13] = CSRArrayOld[12'hF13];
CSRArray[12'hF15] = CSRArrayOld[12'hF15];
CSRArray[12'h34A] = CSRArrayOld[12'h34A];
// MCYCLE and MINSTRET
CSRArray[12'hB00] = CSRArrayOld[12'hB00];
CSRArray[12'hB02] = CSRArrayOld[12'hB02];
// supervisor CSRs
CSRArray[12'h100] = CSRArrayOld[12'h100];
CSRArray[12'h104] = CSRArrayOld[12'h104];
CSRArray[12'h105] = CSRArrayOld[12'h105];
CSRArray[12'h141] = CSRArrayOld[12'h141];
CSRArray[12'h106] = CSRArrayOld[12'h106];
CSRArray[12'h180] = CSRArrayOld[12'h180];
CSRArray[12'h140] = CSRArrayOld[12'h140];
CSRArray[12'h143] = CSRArrayOld[12'h143];
CSRArray[12'h142] = CSRArrayOld[12'h142];
CSRArray[12'h144] = CSRArrayOld[12'h144];
// user CSRs
CSRArray[12'h001] = CSRArrayOld[12'h001];
CSRArray[12'h002] = CSRArrayOld[12'h002];
CSRArray[12'h003] = CSRArrayOld[12'h003];
end
end
genvar index;
assign rf[0] = '0;
for(index = 1; index < NUMREGS; index += 1)
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3;
assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3;
always_comb begin
rf_wb <= '0;
if(rf_we3)
rf_wb[rf_a3] <= 1'b1;
end
for(index = 0; index < NUMREGS; index += 1)
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
always_comb begin
frf_wb <= '0;
if(frf_we4)
frf_wb[frf_a4] <= 1'b1;
end
assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM;
assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM;
// pipeline to writeback stage
flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE);
flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM);
flopenrc #(`XLEN) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW);
flopenrc #(`XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW);
flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW);
flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW);
flopenrc #(1) HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW);
flopenrc #(1) IntrFReg (clk, reset, 1'b0, ~StallF, TrapM, IntrF);
flopenrc #(1) IntrDReg (clk, reset, FlushD, ~StallD, IntrF, IntrD);
flopenrc #(1) IntrEReg (clk, reset, FlushE, ~StallE, IntrD, IntrE);
flopenrc #(1) IntrMReg (clk, reset, FlushM, ~StallM, IntrE, IntrM);
flopenrc #(1) IntrWReg (clk, reset, FlushW, ~StallW, IntrM, IntrW);
flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
// Initially connecting the writeback stage signals, but may need to use M stage
// and gate on ~FlushW.
assign valid = InstrValidW & ~StallW;
assign rvvi.clk = clk;
assign #1 rvvi.valid[0][0] = valid;
assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order
assign rvvi.insn[0][0] = InstrRawW;
assign rvvi.pc_rdata[0][0] = PCW;
assign rvvi.trap[0][0] = 0; // TODO: IMPERAS TrapW;
assign rvvi.halt[0][0] = HaltW;
assign rvvi.intr[0][0] = IntrW;
assign rvvi.mode[0][0] = PrivilegeModeW;
assign rvvi.ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
assign rvvi.pc_wdata[0][0] = ~FlushW ? PCM :
~FlushM ? PCE :
~FlushE ? PCD :
~FlushD ? PCF : PCNextF;
for(index = 0; index < `NUM_REGS; index += 1) begin
assign rvvi.x_wdata[0][0][index] = rf[index];
assign rvvi.x_wb[0][0][index] = rf_wb[index];
assign rvvi.f_wdata[0][0][index] = frf[index];
assign rvvi.f_wb[0][0][index] = frf_wb[index];
end
// record previous csr value.
integer index4;
always_ff @(posedge clk) begin
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin
// IMPERAS
//CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0;
CSRArrayOld[index4] = CSRArray[index4];
end
end
// check for csr value change.
genvar index5;
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin
// CSR_W should only indicate the change when the Writeback stage is not stalled and valid.
assign #2 CSR_W[index5] = (CSRArrayOld[index5] != CSRArray[index5]) ? 1 : 0;
assign rvvi.csr_wb[0][0][index5] = CSR_W[index5];
assign rvvi.csr[0][0][index5] = CSRArray[index5];
end
// always @rvvi.clk $display("%t @rvvi.clk=%X", $time, rvvi.clk);
// always @rvvi.csr[0][0]['h300] $display("%t rvvi.csr[0][0]['h300]=%X", $time, rvvi.csr[0][0]['h300]);
// always @rvvi.csr_wb[0][0]['h300] $display("%t rvvi.csr_wb[0][0]['h300]=%X", $time, rvvi.csr_wb[0][0]['h300]);
// always @rvvi.valid[0][0] $display("%t rvvi.valid[0][0]=%X", $time, rvvi.valid[0][0]);
// *** implementation only cancel? so sc does not clear?
assign rvvi.lrsc_cancel[0][0] = '0;
integer index2;
always_ff @(posedge clk) begin
if(rvvi.valid[0][0]) begin
if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
$display("order = %08d, PC = %08x, insn = %08x", rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0]);
else if(`PRINT_MOST & !`PRINT_ALL)
$display("order = %08d, PC = %010x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %010x, x%02d = %016x, f%02d = %016x, csr%03x = %016x",
rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0], rvvi.trap[0][0], rvvi.halt[0][0], rvvi.intr[0][0], rvvi.mode[0][0], rvvi.ixl[0][0], rvvi.pc_wdata[0][0], rf_a3, rvvi.x_wdata[0][0][rf_a3], frf_a4, rvvi.f_wdata[0][0][frf_a4], CSRAdrW, rvvi.csr[0][0][CSRAdrW]);
else if(`PRINT_ALL) begin
$display("order = %08d, PC = %08x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x",
rvvi.order[0][0], rvvi.pc_rdata[0][0], rvvi.insn[0][0], rvvi.trap[0][0], rvvi.halt[0][0], rvvi.intr[0][0], rvvi.mode[0][0], rvvi.ixl[0][0], rvvi.pc_wdata[0][0]);
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
$display("x%02d = %08x", index2, rvvi.x_wdata[0][0][index2]);
end
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
$display("f%02d = %08x", index2, rvvi.f_wdata[0][0][index2]);
end
end
if (`PRINT_CSRS) begin
for(index2 = 0; index2 < `NUM_CSRS; index2 += 1) begin
if(CSR_W[index2]) begin
$display("%t: CSR %03x = %x", $time(), index2, CSRArray[index2]);
end
end
end
end
if(HaltW) $finish;
end
endmodule

View File

@ -471,15 +471,20 @@ logic [3:0] dummy;
genvar adrindex; genvar adrindex;
// Initializing all zeroes into the branch predictor memory. // Initializing all zeroes into the branch predictor memory.
for(adrindex = 0; adrindex < 1024; adrindex++) begin for(adrindex = 0; adrindex < 2**10; adrindex++) begin
initial begin initial begin
force dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0;
force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0;
#1; #1;
release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex];
release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex]; release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex];
end end
end end
for(adrindex = 0; adrindex < 2**`BPRED_SIZE; adrindex++) begin
initial begin
force dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0;
#1;
release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex];
end
end
if (`BPRED_LOGGER) begin if (`BPRED_LOGGER) begin
string direction; string direction;

View File

@ -31,10 +31,21 @@
`include "wally-config.vh" `include "wally-config.vh"
// This is set from the commsnd line script
// `define USE_IMPERAS_DV
`ifdef USE_IMPERAS_DV
`include "rvvi/imperasDV.svh"
`endif
module testbench; module testbench;
parameter DEBUG=0; parameter DEBUG=0;
`ifdef USE_IMPERAS_DV
import rvviPkg::*;
import rvviApiPkg::*;
`endif
logic clk; logic clk;
logic reset_ext, reset; logic reset_ext, reset;
@ -63,7 +74,7 @@ module testbench;
integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 }; integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 };
logic DCacheFlushDone, DCacheFlushStart; logic DCacheFlushDone, DCacheFlushStart;
string testName; string testName;
string memfilename, pathname, adrstr; string memfilename, testDir, adrstr, elffilename;
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
logic UARTSin, UARTSout; logic UARTSin, UARTSout;
@ -92,28 +103,90 @@ module testbench;
testadr = 0; testadr = 0;
testadrNoBase = 0; testadrNoBase = 0;
//testName = "rv64i_m/I/src/add-01.S"; if ($value$plusargs("testDir=%s", testDir)) begin
testName = "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S"; memfilename = {testDir, "/ref/ref.elf.memfile"};
elffilename = {testDir, "/ref/ref.elf"};
$display($sformatf("%m @ t=%0t: loading testDir %0s", $time, testDir));
end else begin
$error("Must specify test directory using plusarg testDir");
end
//pathname = "../../tests/riscof/work/riscv-arch-test/";
pathname = "../../tests/riscof/work/wally-riscv-arch-test/";
memfilename = {pathname, testName, "/ref/ref.elf.memfile"};
if (`BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); if (`BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
else $error("Imperas test bench requires BUS_SUPPORTED."); else $error("Imperas test bench requires BUS.");
ProgramAddrMapFile = {pathname, testName, "/ref/ref.elf.objdump.addr"}; ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"};
ProgramLabelMapFile = {pathname, testName, "/ref/ref.elf.objdump.lab"}; ProgramLabelMapFile = {testDir, "/ref/ref.elf.objdump.lab"};
// declare memory labels that interest us, the updateProgramAddrLabelArray task will find the addr of each label and fill the array // declare memory labels that interest us, the updateProgramAddrLabelArray task will find the addr of each label and fill the array
// to expand, add more elements to this array and initialize them to zero (also initilaize them to zero at the start of the next test) // to expand, add more elements to this array and initialize them to zero (also initilaize them to zero at the start of the next test)
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename); $display("Read memfile %s", memfilename);
end end
rvviTrace rvviTrace(); rvviTrace #(.XLEN(`XLEN), .FLEN(`FLEN)) rvvi();
wallyTracer wallyTracer(rvvi);
`ifdef USE_IMPERAS_DV
trace2log idv_trace2log(rvvi);
// enabling of comparison types
trace2api #(.CMP_PC (1),
.CMP_INS (1),
.CMP_GPR (1),
.CMP_FPR (1),
.CMP_VR (0),
.CMP_CSR (1)
) idv_trace2api(rvvi);
initial begin
MAX_ERRS = 3;
// Initialize REF (do this before initializing the DUT)
if (!rvviVersionCheck(RVVI_API_VERSION)) begin
msgfatal($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION));
end
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"));
if (!rvviRefInit(elffilename)) begin
msgfatal($sformatf("%m @ t=%0t: rvviRefInit failed", $time));
end
// Volatile CSRs
void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE
void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
if(`XLEN==32) begin
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH
void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
end
// // Temporary fix for inexact difference
// void'(rvviRefCsrSetVolatile(0, 32'h001)); // fflags
// void'(rvviRefCsrSetVolatile(0, 32'h003)); // fcsr
// Enable the trace2log module
if ($value$plusargs("TRACE2LOG_ENABLE=%d", TRACE2LOG_ENABLE)) begin
msgnote($sformatf("%m @ t=%0t: TRACE2LOG_ENABLE is %0d", $time, TRACE2LOG_ENABLE));
end
if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin
msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE));
end
end
final begin
void'(rvviRefShutdown());
end
`endif
flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW);
flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW);
@ -158,7 +231,7 @@ module testbench;
// Track names of instructions // Track names of instructions
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
dut.core.ifu.FinalInstrRawF[31:0], dut.core.ifu.InstrRawF[31:0],
dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrD, dut.core.ifu.InstrE,
dut.core.ifu.InstrM, InstrW, dut.core.ifu.InstrM, InstrW,
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
@ -254,7 +327,6 @@ module testbench;
end end
end end
endmodule endmodule
module riscvassertions; module riscvassertions;
@ -267,17 +339,17 @@ module riscvassertions;
assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
assert (`FLEN<=`XLEN | `DCACHE | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported");
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACH_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size");
assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size");
assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE)) else $error("DCACHE_LINELENINBITS must be a power of 2"); assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2");
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE)) else $error("ICACHE_LINELENINBITS must be a power of 2"); assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2");
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2");
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2");
assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF"); assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF");
@ -288,7 +360,7 @@ module riscvassertions;
assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache");
assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS."); assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS.");
assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally."); assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally.");
assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
@ -311,7 +383,7 @@ module DCacheFlushFSM
logic [`XLEN-1:0] ShadowRAM[`UNCORE_RAM_BASE>>(1+`XLEN/32):(`UNCORE_RAM_RANGE+`UNCORE_RAM_BASE)>>1+(`XLEN/32)]; logic [`XLEN-1:0] ShadowRAM[`UNCORE_RAM_BASE>>(1+`XLEN/32):(`UNCORE_RAM_RANGE+`UNCORE_RAM_BASE)>>1+(`XLEN/32)];
if(`DCACHE) begin if(`DCACHE_SUPPORTED) begin
localparam integer numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES; localparam integer numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES;
localparam integer numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS; localparam integer numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS;
localparam integer linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN; localparam integer linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN;
@ -413,6 +485,7 @@ module copyShadow
end end
end end
endmodule endmodule
task automatic updateProgramAddrLabelArray; task automatic updateProgramAddrLabelArray;

57
setup.imperas.sh Normal file
View File

@ -0,0 +1,57 @@
#!/bin/bash
IMP_HASH=56b1479
REPO=davidharrishmc
REPO=eroom1966
git clone https://github.com/${REPO}/riscv-wally -b imperas
cd riscv-wally
WALLY=$(dirname ${BASH_SOURCE[0]:-$0})
export WALLY=$(cd "$WALLY" && pwd)
# clone the Imperas repo
if [ ! -d external ]; then
mkdir -p external
fi
pushd external
if [ ! -f ImperasDV-HMC ]; then
git clone git@github.com:Imperas/ImperasDV-HMC.git
fi
pushd ImperasDV-HMC
git checkout $IMP_HASH
popd
popd
# Setup Imperas
source ${WALLY}/external/ImperasDV-HMC/Imperas/bin/setup.sh
setupImperas ${WALLY}/external/ImperasDV-HMC/Imperas
export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
# setup QUESTA (Imperas only command, YMMV)
svsetup -questa
pushd pipelined/regression
# With IDV
IMPERAS_TOOLS=$(pwd)/imperas.ic \
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
TESTDIR=${WALLY}/external/ImperasDV-HMC/tests/riscof/work/riscv-arch-test/rv64i_m/F/src/fadd_b1-01.S \
vsim -c -do "do wally-pipelined-imperas.do rv64gc"
popd
# notes
# run the pushd external code
#source external/ImperasDV-HMC/Imperas/bin/setup.sh
# setupImperas /home/ross/repos/active-wally/riscv-wally/external/ImperasDV-HMC/Imperas
# env | grep IMPERAS
# export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC
IMPERAS_TOOLS=$(pwd)/imperas.ic \
OTHERFLAGS="+TRACE2LOG_ENABLE=1 VERBOSE=1" \
TESTDIR=../../tests/riscof_lee/work/riscv-arch-test/rv64i_m/F/src/fadd_b1-01.S \
vsim -c -do "do wally-pipelined-imperas.do rv64gc"
# getting library issue.
# try switching to modelsim 2022.01