From f4e7e54abe208c859c7d69591f17971504cdb66e Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Tue, 17 Jan 2023 12:47:38 +0000 Subject: [PATCH] Code refactor and addition of rvvi interface --- .../ImpPublic/source/host/rvvi/rvvi-trace.sv | 102 +++++++++++ pipelined/regression/imperas.ic | 20 +++ .../wally-pipelined-imperas-no-idv.do | 55 ++++++ .../regression/wally-pipelined-imperas.do | 22 ++- .../common/{rvvitrace.sv => wallyTracer.sv} | 170 +++++++----------- pipelined/testbench/testbench_imperas.sv | 106 +++++++++-- setup.imperas.sh | 26 +++ 7 files changed, 381 insertions(+), 120 deletions(-) create mode 100644 external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv create mode 100644 pipelined/regression/imperas.ic create mode 100644 pipelined/regression/wally-pipelined-imperas-no-idv.do rename pipelined/testbench/common/{rvvitrace.sv => wallyTracer.sv} (57%) create mode 100644 setup.imperas.sh diff --git a/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv b/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv new file mode 100644 index 000000000..1dfe24cd5 --- /dev/null +++ b/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv @@ -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 diff --git a/pipelined/regression/imperas.ic b/pipelined/regression/imperas.ic new file mode 100644 index 000000000..8a925389f --- /dev/null +++ b/pipelined/regression/imperas.ic @@ -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 + diff --git a/pipelined/regression/wally-pipelined-imperas-no-idv.do b/pipelined/regression/wally-pipelined-imperas-no-idv.do new file mode 100644 index 000000000..213355e54 --- /dev/null +++ b/pipelined/regression/wally-pipelined-imperas-no-idv.do @@ -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 diff --git a/pipelined/regression/wally-pipelined-imperas.do b/pipelined/regression/wally-pipelined-imperas.do index 285d013fc..21ed71420 100644 --- a/pipelined/regression/wally-pipelined-imperas.do +++ b/pipelined/regression/wally-pipelined-imperas.do @@ -32,14 +32,32 @@ vlib work # 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 ../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 -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 #-- display input and output signals as hexidecimal values add log -recursive /* do wave.do run -all + noview ../testbench/testbench_imperas.sv view wave diff --git a/pipelined/testbench/common/rvvitrace.sv b/pipelined/testbench/common/wallyTracer.sv similarity index 57% rename from pipelined/testbench/common/rvvitrace.sv rename to pipelined/testbench/common/wallyTracer.sv index ece265583..2cba8d2a4 100644 --- a/pipelined/testbench/common/rvvitrace.sv +++ b/pipelined/testbench/common/wallyTracer.sv @@ -3,18 +3,11 @@ `define NUM_REGS 32 `define NUM_CSRS 4096 -`define PRINT_PC_INSTR 1 -`define PRINT_MOST 1 +`define PRINT_PC_INSTR 0 +`define PRINT_MOST 0 `define PRINT_ALL 0 -module rvviTrace #( - 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 - (); +module wallyTracer(rvviTrace rvvi); localparam NUMREGS = `E_SUPPORTED ? 16 : 32; @@ -38,55 +31,36 @@ module rvviTrace #( 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] CSRArray [logic[11:0]]; logic [`XLEN-1:0] CSRArrayOld [logic[11:0]]; + logic [`XLEN-1:0] CSR_W [logic[11:0]]; logic CSRWriteM, CSRWriteW; 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 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 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 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 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; + assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL; + assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; always_comb begin // machine CSRs @@ -136,7 +110,7 @@ module rvviTrace #( 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_a3 = testbench.dut.core.ieu.dp.regf.a3; assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3; always_comb begin @@ -148,7 +122,7 @@ module rvviTrace #( 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_a4 = testbench.dut.core.fpu.fpu.fregfile.a4; assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4; always_comb begin @@ -157,7 +131,7 @@ module rvviTrace #( frf_wb[frf_a4] <= 1'b1; 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; // pipeline to writeback stage @@ -175,89 +149,77 @@ module rvviTrace #( 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); + 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 & ~FlushW; - assign order[0][0] = CSRArray[12'hB02]; - assign insn[0][0] = InstrRawW; - assign pc_rdata[0][0] = PCW; - assign trap[0][0] = TrapW; - assign halt[0][0] = HaltW; - assign intr[0][0] = IntrW; - assign mode[0][0] = PrivilegeModeW; - assign ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 : - PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL; - assign pc_wdata[0][0] = ~FlushW ? PCM : - ~FlushM ? PCE : - ~FlushE ? PCD : - ~FlushD ? PCF : PCNextF; + assign rvvi.clk = clk; + assign rvvi.valid[0][0] = InstrValidW & ~StallW & ~FlushW; + 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 x_wdata[0][0][index] = rf[index]; - assign x_wb[0][0][index] = rf_wb[index]; - assign f_wdata[0][0][index] = frf[index]; - assign f_wb[0][0][index] = frf_wb[index]; + 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 - if(CSRArray.exists(index4)) begin + CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0; CSRArrayOld[index4] = CSRArray[index4]; - end end end - + // check for csr value change. - integer index5; - always_comb begin - for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin - if(CSRArray.exists(index5)) begin - 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 + genvar index5; + for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin + assign rvvi.csr_wb[0][0][index5] = CSR_W[index5]; + assign rvvi.csr[0][0][index5] = CSRArray[index5]; end // *** implementation only cancel? so sc does not clear? - assign lrsc_cancel[0][0] = '0; + assign rvvi.lrsc_cancel[0][0] = '0; integer index2; always_ff @(posedge clk) begin - if(valid) begin + if(rvvi.valid[0][0]) begin 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) $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 $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 - $display("x%02d = %08x", index2, x_wdata[0][0][index2]); + $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, f_wdata[0][0][index2]); + $display("f%02d = %08x", index2, rvvi.f_wdata[0][0][index2]); end end end - if(HaltW) $stop(); + if(HaltW) $finish; +// if(HaltW) $stop; + end diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index 6e84e879b..4d100e8ad 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -31,10 +31,21 @@ `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; parameter DEBUG=0; - + +`ifdef USE_IMPERAS_DV + import rvviPkg::*; + import rvviApiPkg::*; +`endif + logic clk; logic reset_ext, reset; @@ -63,7 +74,7 @@ module testbench; integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 }; logic DCacheFlushDone, DCacheFlushStart; string testName; - string memfilename, pathname, adrstr; + string memfilename, testDir, adrstr, elffilename; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; @@ -91,29 +102,54 @@ module testbench; InReset = 1; testadr = 0; testadrNoBase = 0; + +`ifdef USE_IMPERAS_DV + // 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 - //testName = "rv64i_m/I/src/add-01.S"; - testName = "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S"; - + if ($value$plusargs("TRACE2COV_ENABLE=%d", TRACE2COV_ENABLE)) begin + msgnote($sformatf("%m @ t=%0t: TRACE2COV_ENABLE is %0d", $time, TRACE2COV_ENABLE)); + end +`endif + + if ($value$plusargs("testDir=%s", testDir)) begin + 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) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); else $error("Imperas test bench requires BUS."); - ProgramAddrMapFile = {pathname, testName, "/ref/ref.elf.objdump.addr"}; - ProgramLabelMapFile = {pathname, testName, "/ref/ref.elf.objdump.lab"}; - + ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; + 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 // 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); $display("Read memfile %s", memfilename); + 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 #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); @@ -254,7 +290,48 @@ module testbench; 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 module riscvassertions; @@ -413,6 +490,7 @@ module copyShadow end end + endmodule task automatic updateProgramAddrLabelArray; diff --git a/setup.imperas.sh b/setup.imperas.sh new file mode 100644 index 000000000..7f3d6c3d8 --- /dev/null +++ b/setup.imperas.sh @@ -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 +