mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Code refactor and addition of rvvi interface
This commit is contained in:
parent
aea9cc1a75
commit
f4e7e54abe
102
external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv
vendored
Normal file
102
external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2005-2023 Imperas Software Ltd., www.imperas.com
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
`define NUM_REGS 32
|
||||||
|
`define NUM_CSRS 4096
|
||||||
|
|
||||||
|
interface rvviTrace
|
||||||
|
#(
|
||||||
|
parameter int ILEN = 32, // Instruction length in bits
|
||||||
|
parameter int XLEN = 32, // GPR length in bits
|
||||||
|
parameter int FLEN = 32, // FPR length in bits
|
||||||
|
parameter int VLEN = 256, // Vector register size in bits
|
||||||
|
parameter int NHART = 1, // Number of harts reported
|
||||||
|
parameter int RETIRE = 1 // Number of instructions that can retire during valid event
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// RISCV output signals
|
||||||
|
//
|
||||||
|
wire clk; // Interface clock
|
||||||
|
|
||||||
|
wire valid [(NHART-1):0][(RETIRE-1):0]; // Retired instruction
|
||||||
|
wire [63:0] order [(NHART-1):0][(RETIRE-1):0]; // Unique instruction order count (no gaps or reuse)
|
||||||
|
wire [(ILEN-1):0] insn [(NHART-1):0][(RETIRE-1):0]; // Instruction bit pattern
|
||||||
|
wire trap [(NHART-1):0][(RETIRE-1):0]; // Trapped instruction (External to Core, eg Memory Subsystem)
|
||||||
|
wire halt [(NHART-1):0][(RETIRE-1):0]; // Halted instruction
|
||||||
|
wire intr [(NHART-1):0][(RETIRE-1):0]; // (RVFI Legacy) Flag first instruction of trap handler
|
||||||
|
wire [1:0] mode [(NHART-1):0][(RETIRE-1):0]; // Privilege mode of operation
|
||||||
|
wire [1:0] ixl [(NHART-1):0][(RETIRE-1):0]; // XLEN mode 32/64 bit
|
||||||
|
|
||||||
|
wire [(XLEN-1):0] pc_rdata [(NHART-1):0][(RETIRE-1):0]; // PC of insn
|
||||||
|
wire [(XLEN-1):0] pc_wdata [(NHART-1):0][(RETIRE-1):0]; // PC of next instruction
|
||||||
|
|
||||||
|
// X Registers
|
||||||
|
wire [31:0][(XLEN-1):0] x_wdata [(NHART-1):0][(RETIRE-1):0]; // X data value
|
||||||
|
wire [31:0] x_wb [(NHART-1):0][(RETIRE-1):0]; // X data writeback (change) flag
|
||||||
|
|
||||||
|
// F Registers
|
||||||
|
wire [31:0][(FLEN-1):0] f_wdata [(NHART-1):0][(RETIRE-1):0]; // F data value
|
||||||
|
wire [31:0] f_wb [(NHART-1):0][(RETIRE-1):0]; // F data writeback (change) flag
|
||||||
|
|
||||||
|
// V Registers
|
||||||
|
wire [31:0][(VLEN-1):0] v_wdata [(NHART-1):0][(RETIRE-1):0]; // V data value
|
||||||
|
wire [31:0] v_wb [(NHART-1):0][(RETIRE-1):0]; // V data writeback (change) flag
|
||||||
|
|
||||||
|
// Control & State Registers
|
||||||
|
wire [4095:0][(XLEN-1):0] csr [(NHART-1):0][(RETIRE-1):0]; // Full CSR Address range
|
||||||
|
wire [4095:0] csr_wb [(NHART-1):0][(RETIRE-1):0]; // CSR writeback (change) flag
|
||||||
|
|
||||||
|
wire lrsc_cancel[(NHART-1):0][(RETIRE-1):0]; // Implementation defined cancel
|
||||||
|
|
||||||
|
//
|
||||||
|
// Synchronization of NETs
|
||||||
|
//
|
||||||
|
wire clkD;
|
||||||
|
assign #1 clkD = clk;
|
||||||
|
|
||||||
|
longint vslot;
|
||||||
|
always @(posedge clk) vslot++;
|
||||||
|
|
||||||
|
string name[$];
|
||||||
|
int value[$];
|
||||||
|
longint tslot[$];
|
||||||
|
int nets[string];
|
||||||
|
|
||||||
|
function automatic void net_push(input string vname, input int vvalue);
|
||||||
|
name.push_front(vname);
|
||||||
|
value.push_front(vvalue);
|
||||||
|
tslot.push_front(vslot);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic int net_pop(output string vname, output int vvalue, output longint vslot);
|
||||||
|
int ok;
|
||||||
|
string msg;
|
||||||
|
if (name.size() > 0) begin
|
||||||
|
vname = name.pop_back();
|
||||||
|
vvalue = value.pop_back();
|
||||||
|
vslot = tslot.pop_back();
|
||||||
|
nets[vname] = vvalue;
|
||||||
|
ok = 1;
|
||||||
|
end else begin
|
||||||
|
ok = 0;
|
||||||
|
end
|
||||||
|
return ok;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endinterface
|
20
pipelined/regression/imperas.ic
Normal file
20
pipelined/regression/imperas.ic
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#--showoverrides
|
||||||
|
--override cpu/unaligned=F
|
||||||
|
--override refRoot/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
|
||||||
|
|
55
pipelined/regression/wally-pipelined-imperas-no-idv.do
Normal file
55
pipelined/regression/wally-pipelined-imperas-no-idv.do
Normal 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/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
|
@ -32,14 +32,32 @@ vlib work
|
|||||||
# start and run simulation
|
# start and run simulation
|
||||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||||
# *** 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.
|
# *** 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 ../testbench/testbench_imperas.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063
|
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
|
vopt +acc work.testbench -G DEBUG=1 -o workopt
|
||||||
vsim workopt +nowarn3829 -fatal 7
|
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
|
view wave
|
||||||
#-- display input and output signals as hexidecimal values
|
#-- display input and output signals as hexidecimal values
|
||||||
add log -recursive /*
|
add log -recursive /*
|
||||||
do wave.do
|
do wave.do
|
||||||
|
|
||||||
run -all
|
run -all
|
||||||
|
|
||||||
noview ../testbench/testbench_imperas.sv
|
noview ../testbench/testbench_imperas.sv
|
||||||
view wave
|
view wave
|
||||||
|
@ -3,18 +3,11 @@
|
|||||||
`define NUM_REGS 32
|
`define NUM_REGS 32
|
||||||
`define NUM_CSRS 4096
|
`define NUM_CSRS 4096
|
||||||
|
|
||||||
`define PRINT_PC_INSTR 1
|
`define PRINT_PC_INSTR 0
|
||||||
`define PRINT_MOST 1
|
`define PRINT_MOST 0
|
||||||
`define PRINT_ALL 0
|
`define PRINT_ALL 0
|
||||||
|
|
||||||
module rvviTrace #(
|
module wallyTracer(rvviTrace rvvi);
|
||||||
parameter int ILEN = `XLEN, // Instruction length in bits
|
|
||||||
parameter int XLEN = `XLEN, // GPR length in bits
|
|
||||||
parameter int FLEN = `FLEN, // FPR length in bits
|
|
||||||
parameter int VLEN = 0, // Vector register size in bits
|
|
||||||
parameter int NHART = 1, // Number of harts reported
|
|
||||||
parameter int RETIRE = 1) // Number of instructions that can retire during valid event
|
|
||||||
();
|
|
||||||
|
|
||||||
localparam NUMREGS = `E_SUPPORTED ? 16 : 32;
|
localparam NUMREGS = `E_SUPPORTED ? 16 : 32;
|
||||||
|
|
||||||
@ -38,55 +31,36 @@ module rvviTrace #(
|
|||||||
logic [`NUM_REGS-1:0] frf_wb;
|
logic [`NUM_REGS-1:0] frf_wb;
|
||||||
logic [4:0] frf_a4;
|
logic [4:0] frf_a4;
|
||||||
logic frf_we4;
|
logic frf_we4;
|
||||||
logic [`XLEN-1:0] CSRArray [logic[11:0]];
|
logic [`XLEN-1:0] CSRArray [logic[11:0]];
|
||||||
logic [`XLEN-1:0] CSRArrayOld [logic[11:0]];
|
logic [`XLEN-1:0] CSRArrayOld [logic[11:0]];
|
||||||
|
logic [`XLEN-1:0] CSR_W [logic[11:0]];
|
||||||
logic CSRWriteM, CSRWriteW;
|
logic CSRWriteM, CSRWriteW;
|
||||||
logic [11:0] CSRAdrM, CSRAdrW;
|
logic [11:0] CSRAdrM, CSRAdrW;
|
||||||
|
|
||||||
// tracer signals
|
|
||||||
logic clk;
|
|
||||||
logic valid;
|
|
||||||
logic [63:0] order [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [ILEN-1:0] insn [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic intr [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [(XLEN-1):0] pc_rdata [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [(XLEN-1):0] pc_wdata [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic trap [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic halt [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [1:0] mode [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [1:0] ixl [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [`NUM_REGS-1:0][(XLEN-1):0] x_wdata [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [`NUM_REGS-1:0] x_wb [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [`NUM_REGS-1:0][(XLEN-1):0] f_wdata [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [`NUM_REGS-1:0] f_wb [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [4095:0][(XLEN-1):0] csr [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic [4095:0] csr_wb [(NHART-1):0][(RETIRE-1):0];
|
|
||||||
logic lrsc_cancel[(NHART-1):0][(RETIRE-1):0];
|
|
||||||
|
|
||||||
assign clk = testbench.dut.clk;
|
assign clk = testbench.dut.clk;
|
||||||
// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet
|
// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet
|
||||||
assign InstrValidD = testbench.dut.core.ieu.c.InstrValidD;
|
assign InstrValidD = testbench.dut.core.ieu.c.InstrValidD;
|
||||||
assign InstrValidE = testbench.dut.core.ieu.c.InstrValidE;
|
assign InstrValidE = testbench.dut.core.ieu.c.InstrValidE;
|
||||||
assign InstrValidM = testbench.dut.core.ieu.InstrValidM;
|
assign InstrValidM = testbench.dut.core.ieu.InstrValidM;
|
||||||
assign InstrRawD = testbench.dut.core.ifu.InstrRawD;
|
assign InstrRawD = testbench.dut.core.ifu.InstrRawD;
|
||||||
assign PCNextF = testbench.dut.core.ifu.PCNextF;
|
assign PCNextF = testbench.dut.core.ifu.PCNextF;
|
||||||
assign PCF = testbench.dut.core.ifu.PCF;
|
assign PCF = testbench.dut.core.ifu.PCF;
|
||||||
assign PCD = testbench.dut.core.ifu.PCD;
|
assign PCD = testbench.dut.core.ifu.PCD;
|
||||||
assign PCE = testbench.dut.core.ifu.PCE;
|
assign PCE = testbench.dut.core.ifu.PCE;
|
||||||
assign PCM = testbench.dut.core.ifu.PCM;
|
assign PCM = testbench.dut.core.ifu.PCM;
|
||||||
assign reset = testbench.reset;
|
assign reset = testbench.reset;
|
||||||
assign StallE = testbench.dut.core.StallE;
|
assign StallE = testbench.dut.core.StallE;
|
||||||
assign StallM = testbench.dut.core.StallM;
|
assign StallM = testbench.dut.core.StallM;
|
||||||
assign StallW = testbench.dut.core.StallW;
|
assign StallW = testbench.dut.core.StallW;
|
||||||
assign FlushD = testbench.dut.core.FlushD;
|
assign FlushD = testbench.dut.core.FlushD;
|
||||||
assign FlushE = testbench.dut.core.FlushE;
|
assign FlushE = testbench.dut.core.FlushE;
|
||||||
assign FlushM = testbench.dut.core.FlushM;
|
assign FlushM = testbench.dut.core.FlushM;
|
||||||
assign FlushW = testbench.dut.core.FlushW;
|
assign FlushW = testbench.dut.core.FlushW;
|
||||||
assign TrapM = testbench.dut.core.TrapM;
|
assign TrapM = testbench.dut.core.TrapM;
|
||||||
assign HaltM = testbench.DCacheFlushStart;
|
assign HaltM = testbench.DCacheFlushStart;
|
||||||
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
|
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
|
||||||
assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL;
|
assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL;
|
||||||
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
|
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
// machine CSRs
|
// machine CSRs
|
||||||
@ -136,7 +110,7 @@ module rvviTrace #(
|
|||||||
for(index = 1; index < NUMREGS; index += 1)
|
for(index = 1; index < NUMREGS; index += 1)
|
||||||
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
|
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
|
||||||
|
|
||||||
assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3;
|
assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3;
|
||||||
assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3;
|
assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -148,7 +122,7 @@ module rvviTrace #(
|
|||||||
for(index = 0; index < NUMREGS; index += 1)
|
for(index = 0; index < NUMREGS; index += 1)
|
||||||
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
|
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
|
||||||
|
|
||||||
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
|
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
|
||||||
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
|
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -157,7 +131,7 @@ module rvviTrace #(
|
|||||||
frf_wb[frf_a4] <= 1'b1;
|
frf_wb[frf_a4] <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM;
|
assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM;
|
||||||
assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM;
|
assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM;
|
||||||
|
|
||||||
// pipeline to writeback stage
|
// pipeline to writeback stage
|
||||||
@ -175,89 +149,77 @@ module rvviTrace #(
|
|||||||
flopenrc #(1) IntrMReg (clk, reset, FlushM, ~StallM, IntrE, IntrM);
|
flopenrc #(1) IntrMReg (clk, reset, FlushM, ~StallM, IntrE, IntrM);
|
||||||
flopenrc #(1) IntrWReg (clk, reset, FlushW, ~StallW, IntrM, IntrW);
|
flopenrc #(1) IntrWReg (clk, reset, FlushW, ~StallW, IntrM, IntrW);
|
||||||
|
|
||||||
flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
|
flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
|
||||||
flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
|
flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
|
||||||
|
|
||||||
// Initially connecting the writeback stage signals, but may need to use M stage
|
// Initially connecting the writeback stage signals, but may need to use M stage
|
||||||
// and gate on ~FlushW.
|
// and gate on ~FlushW.
|
||||||
|
|
||||||
assign valid = InstrValidW & ~StallW & ~FlushW;
|
assign rvvi.clk = clk;
|
||||||
assign order[0][0] = CSRArray[12'hB02];
|
assign rvvi.valid[0][0] = InstrValidW & ~StallW & ~FlushW;
|
||||||
assign insn[0][0] = InstrRawW;
|
assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order
|
||||||
assign pc_rdata[0][0] = PCW;
|
assign rvvi.insn[0][0] = InstrRawW;
|
||||||
assign trap[0][0] = TrapW;
|
assign rvvi.pc_rdata[0][0] = PCW;
|
||||||
assign halt[0][0] = HaltW;
|
assign rvvi.trap[0][0] = 0; // TODO: IMPERAS TrapW;
|
||||||
assign intr[0][0] = IntrW;
|
assign rvvi.halt[0][0] = HaltW;
|
||||||
assign mode[0][0] = PrivilegeModeW;
|
assign rvvi.intr[0][0] = IntrW;
|
||||||
assign ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
|
assign rvvi.mode[0][0] = PrivilegeModeW;
|
||||||
PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
|
assign rvvi.ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 :
|
||||||
assign pc_wdata[0][0] = ~FlushW ? PCM :
|
PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL;
|
||||||
~FlushM ? PCE :
|
assign rvvi.pc_wdata[0][0] = ~FlushW ? PCM :
|
||||||
~FlushE ? PCD :
|
~FlushM ? PCE :
|
||||||
~FlushD ? PCF : PCNextF;
|
~FlushE ? PCD :
|
||||||
|
~FlushD ? PCF : PCNextF;
|
||||||
|
|
||||||
for(index = 0; index < `NUM_REGS; index += 1) begin
|
for(index = 0; index < `NUM_REGS; index += 1) begin
|
||||||
assign x_wdata[0][0][index] = rf[index];
|
assign rvvi.x_wdata[0][0][index] = rf[index];
|
||||||
assign x_wb[0][0][index] = rf_wb[index];
|
assign rvvi.x_wb[0][0][index] = rf_wb[index];
|
||||||
assign f_wdata[0][0][index] = frf[index];
|
assign rvvi.f_wdata[0][0][index] = frf[index];
|
||||||
assign f_wb[0][0][index] = frf_wb[index];
|
assign rvvi.f_wb[0][0][index] = frf_wb[index];
|
||||||
end
|
end
|
||||||
|
|
||||||
// record previous csr value.
|
// record previous csr value.
|
||||||
integer index4;
|
integer index4;
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin
|
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin
|
||||||
if(CSRArray.exists(index4)) begin
|
CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0;
|
||||||
CSRArrayOld[index4] = CSRArray[index4];
|
CSRArrayOld[index4] = CSRArray[index4];
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// check for csr value change.
|
// check for csr value change.
|
||||||
integer index5;
|
genvar index5;
|
||||||
always_comb begin
|
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin
|
||||||
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin
|
assign rvvi.csr_wb[0][0][index5] = CSR_W[index5];
|
||||||
if(CSRArray.exists(index5)) begin
|
assign rvvi.csr[0][0][index5] = CSRArray[index5];
|
||||||
csr_wb[0][0][index5] = CSRArrayOld[index5] != CSRArray[index5] ? 1'b1 : 1'b0;
|
|
||||||
end else csr_wb[0][0][index5] = '0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
integer index3;
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
for(index3 = 0; index3 < `NUM_CSRS; index3 += 1) begin
|
|
||||||
if(CSRArray.exists(index3))
|
|
||||||
csr[0][0][index3] = CSRArray[index3];
|
|
||||||
else
|
|
||||||
csr[0][0][index3] = '0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// *** implementation only cancel? so sc does not clear?
|
// *** implementation only cancel? so sc does not clear?
|
||||||
assign lrsc_cancel[0][0] = '0;
|
assign rvvi.lrsc_cancel[0][0] = '0;
|
||||||
|
|
||||||
integer index2;
|
integer index2;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if(valid) begin
|
if(rvvi.valid[0][0]) begin
|
||||||
if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
|
if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST))
|
||||||
$display("order = %08d, PC = %08x, insn = %08x", order[0][0], pc_rdata[0][0], insn[0][0]);
|
$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)
|
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",
|
$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",
|
||||||
order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0], rf_a3, x_wdata[0][0][rf_a3], frf_a4, f_wdata[0][0][frf_a4], CSRAdrW, csr[0][0][CSRAdrW]);
|
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
|
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",
|
$display("order = %08d, PC = %08x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x",
|
||||||
order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0]);
|
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
|
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
|
||||||
$display("x%02d = %08x", index2, x_wdata[0][0][index2]);
|
$display("x%02d = %08x", index2, rvvi.x_wdata[0][0][index2]);
|
||||||
end
|
end
|
||||||
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
|
for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin
|
||||||
$display("f%02d = %08x", index2, f_wdata[0][0][index2]);
|
$display("f%02d = %08x", index2, rvvi.f_wdata[0][0][index2]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if(HaltW) $stop();
|
if(HaltW) $finish;
|
||||||
|
// if(HaltW) $stop;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -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,53 @@ module testbench;
|
|||||||
testadr = 0;
|
testadr = 0;
|
||||||
testadrNoBase = 0;
|
testadrNoBase = 0;
|
||||||
|
|
||||||
//testName = "rv64i_m/I/src/add-01.S";
|
`ifdef USE_IMPERAS_DV
|
||||||
testName = "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S";
|
// 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
|
||||||
|
`endif
|
||||||
|
|
||||||
//pathname = "../../tests/riscof/work/riscv-arch-test/";
|
if ($value$plusargs("testDir=%s", testDir)) begin
|
||||||
pathname = "../../tests/riscof/work/wally-riscv-arch-test/";
|
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
|
||||||
|
|
||||||
memfilename = {pathname, testName, "/ref/ref.elf.memfile"};
|
|
||||||
if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
if (`BUS) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
||||||
else $error("Imperas test bench requires BUS.");
|
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);
|
||||||
|
`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);
|
||||||
@ -254,6 +290,47 @@ module testbench;
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
`ifdef USE_IMPERAS_DV
|
||||||
|
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'(rvviRefCsrSetVolatileMask(0, 32'h001, 'h1)); // fflags
|
||||||
|
// void'(rvviRefCsrSetVolatileMask(0, 32'h003, 'h1)); // fcsr
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'h001)); // fflags
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'h003)); // fcsr
|
||||||
|
end
|
||||||
|
|
||||||
|
final begin
|
||||||
|
void'(rvviRefShutdown());
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
@ -413,6 +490,7 @@ module copyShadow
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
task automatic updateProgramAddrLabelArray;
|
task automatic updateProgramAddrLabelArray;
|
||||||
|
26
setup.imperas.sh
Normal file
26
setup.imperas.sh
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Imperas Environment to setup Wally"
|
||||||
|
|
||||||
|
# Path to Wally repository
|
||||||
|
WALLY=$(dirname ${BASH_SOURCE[0]:-$0})
|
||||||
|
export WALLY=$(cd "$WALLY" && pwd)
|
||||||
|
echo \$WALLY set to ${WALLY}
|
||||||
|
|
||||||
|
isetup -dv
|
||||||
|
svsetup -questa
|
||||||
|
|
||||||
|
pushd pipelined/regression
|
||||||
|
# With IDV
|
||||||
|
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"
|
||||||
|
|
||||||
|
# Without IDV
|
||||||
|
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-no-idv.do rv64gc"
|
||||||
|
popd
|
||||||
|
|
Loading…
Reference in New Issue
Block a user