Partially got linux imperas boot working in the main testbench.

This commit is contained in:
Rose Thompson 2024-02-07 15:38:18 -06:00
parent d82ee04533
commit 2acbc95b72
4 changed files with 185 additions and 82 deletions

View File

@ -3,8 +3,8 @@
#export RISCV=/scratch/moore/RISCV
export IMPERAS_TOOLS=$(pwd)/imperas.ic
export OTHERFLAGS="+TRACE2LOG_ENABLE=1"
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100"
#export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
export OTHERFLAGS=""
#export OTHERFLAGS=""
vsim -c -do "do wally-linux-imperas.do buildroot buildroot-no-trace $::env(RISCV) 0 0 0"
vsim -do "do wally-linux-imperas.do buildroot buildroot $::env(RISCV) 0 0 0"

View File

@ -33,6 +33,9 @@ mkdir -p cov
# if the do file isd called from questa sim directly. This chunk of code uses the $4 through $n
# variables and compacts into a single list for passing to vopt.
set coverage 0
set CoverageVoptArg ""
set CoverageVsimArg ""
set configOptions ""
set from 4
set step 1
@ -47,6 +50,8 @@ for {set i 0} true {incr i} {
if {$argc >= 3} {
if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
set coverage 1
set CoverageVoptArg "+cover=sbecf"
set CoverageVsimArg "-coverage"
} elseif {$3 eq "configOptions"} {
set configOptions $lst
puts $configOptions
@ -66,8 +71,9 @@ vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/der
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$coverage} {
# vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbecf
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage
puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt ${CoverageVoptArg}
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg}
} else {
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 ${configOptions} -o testbenchopt
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
@ -80,6 +86,7 @@ run -all
if {$coverage} {
puts "???????????????????????????"
echo "Saving coverage to ${1}_${2}.ucdb"
do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration
coverage save -instance /testbench/dut/core cov/${1}_${2}.ucdb

View File

@ -32,25 +32,10 @@ vlib work
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation
#run -all
run 7000 ms
add log -recursive /*
do linux-wave.do
run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "buildroot-no-trace"} {
if {$2 eq "buildroot"} {
vlog -lint -work work_${1}_${2} \
+define+USE_IMPERAS_DV \
+incdir+../config/$1 \
+incdir+../config/deriv/$1 \
+incdir+../config/shared \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
@ -64,7 +49,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
../src/cvw.sv \
../testbench/testbench-linux-imperas.sv \
../testbench/testbench.sv \
../testbench/common/*.sv ../src/*/*.sv \
../src/*/*/*.sv -suppress 2583
@ -75,8 +60,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
# vsim -fprofile+perf
# visualizer -fprofile+perf+dir=fprofile
#
eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
-G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt
eval vopt work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
-G INSTR_LIMIT=1000000 -G TEST=$2 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt
eval vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
$env(OTHERFLAGS)
@ -88,68 +73,12 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
#run 100 ns
#force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
#force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
run 9800 ms
add log -recursive /testbench/dut/*
do wave.do
run 9800 ms
run 200 ms
#run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "fpga"} {
echo "hello"
vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286
vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt
vsim workopt +nowarn3829 -fatal 7
do fpga-wave.do
add log -r /*
run 20 ms
} else {
if {$2 eq "ahb"} {
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
} else {
# *** 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 ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
}
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7
view wave
#-- display input and output signals as hexidecimal values
#do ./wave-dos/peripheral-waves.do
add log -recursive /*
do wave.do
#do wave-bus.do
# power add generates the logging necessary for saif generation.
#power add -r /dut/core/*
#-- Run the Simulation
run -all
#power off -r /dut/core/*
#power report -all -bsaif power.saif
noview ../testbench/testbench.sv
view wave
}
#elseif {$2 eq "buildroot-no-trace""} {
# vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
# vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt
# vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
#-- Run the Simulation
# run 100 ns
# force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
# force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
# add log -recursive /*
# do linux-wave.do
# run -all
# exec ./slack-notifier/slack-notifier.py
#}

View File

@ -29,6 +29,10 @@
`include "tests.vh"
`include "BranchPredictorType.vh"
`ifdef USE_IMPERAS_DV
`include "idv/idv.svh"
`endif
import cvw::*;
module testbench;
@ -43,6 +47,12 @@ module testbench;
parameter RISCV_DIR = "/opt/riscv";
parameter INSTR_LIMIT = 0;
`ifdef USE_IMPERAS_DV
import idvPkg::*;
import rvviApiPkg::*;
import idvApiPkg::*;
`endif
`include "parameter-defs.vh"
logic clk;
@ -547,8 +557,165 @@ module testbench;
if((Minstret != 0) && (Minstret % 'd100000 == 0)) $display("Reached %d instructions", Minstret);
if((Minstret == INSTR_LIMIT) & (INSTR_LIMIT!=0)) begin $stop; $stop; end
end
end
////////////////////////////////////////////////////////////////////////////////
// ImperasDV Co-simulator hooks
////////////////////////////////////////////////////////////////////////////////
`ifdef USE_IMPERAS_DV
rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi();
wallyTracer #(P) wallyTracer(rvvi);
trace2log idv_trace2log(rvvi);
// trace2cov idv_trace2cov(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
int iter;
#1;
IDV_MAX_ERRORS = 3;
// Initialize REF (do this before initializing the DUT)
if (!rvviVersionCheck(RVVI_API_VERSION)) begin
$display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION));
$fatal;
end
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"));
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56));
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
if (!rvviRefInit("")) begin
$display($sformatf("%m @ t=%0t: rvviRefInit failed", $time));
$fatal;
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
// User HPMCOUNTER3 - HPMCOUNTER31
for (iter='hC03; iter<='hC1F; iter++) begin
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
end
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
for (iter='hB03; iter<='hB1F; iter++) begin
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
end
// cannot predict this register due to latency between
// pending and taken
void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP
void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP
// Privileges for PMA are set in the imperas.ic
// volatile (IO) regions are defined here
// only real ROM/RAM areas are BOOTROM and UNCORE_RAM
if (P.CLINT_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE)));
end
if (P.GPIO_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE)));
end
if (P.UART_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE)));
end
if (P.PLIC_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE)));
end
if (P.SDC_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE)));
end
if (P.SPI_SUPPORTED) begin
void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE)));
end
if(P.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
void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!!
// Load memory
begin
longint x64;
int x32[2];
longint index;
string memfilenameImperasDV, bootmemfilenameImperasDV;
memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"};
bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"};
$display("RVVI Loading bootmem.bin");
memFile = $fopen(bootmemfilenameImperasDV, "rb");
index = 'h1000 - 8;
while(!$feof(memFile)) begin
index+=8;
readResult = $fread(x64, memFile);
if (x64 == 0) continue;
x32[0] = x64 & 'hffffffff;
x32[1] = x64 >> 32;
rvviRefMemoryWrite(0, index+0, x32[0], 4);
rvviRefMemoryWrite(0, index+4, x32[1], 4);
//$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]);
end
$fclose(memFile);
$display("RVVI Loading ram.bin");
memFile = $fopen(memfilenameImperasDV, "rb");
index = 'h80000000 - 8;
while(!$feof(memFile)) begin
index+=8;
readResult = $fread(x64, memFile);
if (x64 == 0) continue;
x32[0] = x64 & 'hffffffff;
x32[1] = x64 >> 32;
rvviRefMemoryWrite(0, index+0, x32[0], 4);
rvviRefMemoryWrite(0, index+4, x32[1], 4);
//$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]);
end
$fclose(memFile);
$display("RVVI Loading Complete");
void'(rvviRefPcSet(0, 'h1000)); // set BOOTROM address
end
end
always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
final begin
void'(rvviRefShutdown());
end
`endif
////////////////////////////////////////////////////////////////////////////////
// END of ImperasDV Co-simulator hooks
////////////////////////////////////////////////////////////////////////////////
task automatic CheckSignature;
// This task must be declared inside this module as it needs access to parameter P. There is
// no way to pass P to the task unless we convert it to a module.