From fabe13bdce045b3b29aa52b03d95eb35462a18b3 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 16 Jan 2023 13:35:06 -0600 Subject: [PATCH 01/32] Fixed issue with rvvi tracer so it reports call csr changes, not just instrutions which write the CSRs. --- pipelined/testbench/common/rvvitrace.sv | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/pipelined/testbench/common/rvvitrace.sv b/pipelined/testbench/common/rvvitrace.sv index cc564d382..ece265583 100644 --- a/pipelined/testbench/common/rvvitrace.sv +++ b/pipelined/testbench/common/rvvitrace.sv @@ -39,6 +39,7 @@ module rvviTrace #( 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 CSRWriteM, CSRWriteW; logic [11:0] CSRAdrM, CSRAdrW; @@ -202,10 +203,24 @@ module rvviTrace #( assign 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 + CSRArrayOld[index4] = CSRArray[index4]; + end + end + end + + // check for csr value change. + integer index5; always_comb begin - csr_wb[0][0] <= '0; - if(CSRWriteW) - csr_wb[0][0][CSRAdrW] <= 1'b1; + 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; From 7c4eaa1ca6b9347e01c6810b07f316e117fd8d0c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 16 Jan 2023 13:57:28 -0600 Subject: [PATCH 02/32] Found a potential issue with mstatush when XLEN = 64. --- pipelined/src/privileged/csrsr.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/pipelined/src/privileged/csrsr.sv b/pipelined/src/privileged/csrsr.sv index 82e8b5d5d..88669126b 100644 --- a/pipelined/src/privileged/csrsr.sv +++ b/pipelined/src/privileged/csrsr.sv @@ -66,6 +66,7 @@ module csrsr ( STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*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 assign MSTATUS_REGW = {STATUS_SD, 8'b0, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, From f4e7e54abe208c859c7d69591f17971504cdb66e Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Tue, 17 Jan 2023 12:47:38 +0000 Subject: [PATCH 03/32] 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 + From 8caa93ce4dae5aecaefe23bce556a126b8d9f75b Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Tue, 17 Jan 2023 13:01:01 +0000 Subject: [PATCH 04/32] refactor all rvvi into single initial block --- pipelined/testbench/testbench_imperas.sv | 103 +++++++++++------------ 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index 4d100e8ad..5c8ad2ff3 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -102,17 +102,6 @@ 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 - - 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"}; @@ -149,6 +138,56 @@ module testbench; .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'(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 + + + // 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); @@ -290,48 +329,6 @@ 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; From b30c13a188c3eeebd6a992bf6bd9c99dd8bcdbec Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 17 Jan 2023 18:24:46 -0600 Subject: [PATCH 05/32] Fixed the rvvi CSR write enable not synchronized with a valid instruction in the Writeback stage. --- pipelined/testbench/common/wallyTracer.sv | 147 +++++++++++++++------- pipelined/testbench/testbench_imperas.sv | 4 +- 2 files changed, 103 insertions(+), 48 deletions(-) diff --git a/pipelined/testbench/common/wallyTracer.sv b/pipelined/testbench/common/wallyTracer.sv index 2cba8d2a4..c7f68e65e 100644 --- a/pipelined/testbench/common/wallyTracer.sv +++ b/pipelined/testbench/common/wallyTracer.sv @@ -6,6 +6,7 @@ `define PRINT_PC_INSTR 0 `define PRINT_MOST 0 `define PRINT_ALL 0 +`define PRINT_CSRS 0 module wallyTracer(rvviTrace rvvi); @@ -33,7 +34,7 @@ module wallyTracer(rvviTrace rvvi); logic frf_we4; 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 [`NUM_CSRS-1:0] CSR_W; logic CSRWriteM, CSRWriteW; logic [11:0] CSRAdrM, CSRAdrW; @@ -49,6 +50,8 @@ module wallyTracer(rvviTrace rvvi); 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; @@ -63,46 +66,90 @@ module wallyTracer(rvviTrace rvvi); assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; always_comb 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.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.STVEC_REGW; - CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.SEPC_REGW; - CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.SCOUNTEREN_REGW; - CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.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.FRM_REGW; - CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; + // 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(~StallW) 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.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.STVEC_REGW; + CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.SEPC_REGW; + CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.SCOUNTEREN_REGW; + CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.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.FRM_REGW; + CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.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; @@ -155,8 +202,10 @@ module wallyTracer(rvviTrace rvvi); // Initially connecting the writeback stage signals, but may need to use M stage // and gate on ~FlushW. + logic valid; + assign valid = InstrValidW & ~StallW & ~FlushW; assign rvvi.clk = clk; - assign rvvi.valid[0][0] = InstrValidW & ~StallW & ~FlushW; + assign 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; @@ -182,14 +231,15 @@ module wallyTracer(rvviTrace rvvi); integer index4; always_ff @(posedge clk) begin for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin - CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0; - CSRArrayOld[index4] = CSRArray[index4]; + 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 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 @@ -216,10 +266,15 @@ module wallyTracer(rvviTrace rvvi); $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; -// if(HaltW) $stop; - end diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index 5c8ad2ff3..23aff3cba 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -124,8 +124,8 @@ module testbench; end - rvviTrace #(.XLEN(`XLEN), .FLEN(`FLEN)) rvvi(); - wallyTracer wallyTracer(rvvi); + rvviTrace #(.XLEN(`XLEN), .FLEN(`FLEN)) rvvi(); + wallyTracer wallyTracer(rvvi); `ifdef USE_IMPERAS_DV trace2log idv_trace2log(rvvi); From 538940e26956bf9a3e2484ef6d6c95df81317c46 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 13:19:14 +0000 Subject: [PATCH 06/32] update for private copy of Imperas --- .../ImpPublic/source/host/rvvi/rvvi-trace.sv | 102 ------------------ setup.imperas.sh | 15 ++- 2 files changed, 14 insertions(+), 103 deletions(-) delete mode 100644 external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv diff --git a/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv b/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv deleted file mode 100644 index 1dfe24cd5..000000000 --- a/external/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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/setup.imperas.sh b/setup.imperas.sh index 7f3d6c3d8..ac7740796 100644 --- a/setup.imperas.sh +++ b/setup.imperas.sh @@ -7,7 +7,20 @@ WALLY=$(dirname ${BASH_SOURCE[0]:-$0}) export WALLY=$(cd "$WALLY" && pwd) echo \$WALLY set to ${WALLY} -isetup -dv +# clone the Imperas repo +if [ ! -d external ]; then + mkdir -p external +fi +pushd external + if [ ! -f ImperasDV-HMC ]; then + git clone https://github.com/Imperas/ImperasDV-HMC + fi + pushd ImperasDV-HMC + git checkout 0c2f365 + popd +popd + +isetup -dv ${WALLY}/external/ImperasDV-HMC/Imperas svsetup -questa pushd pipelined/regression From eb67abdcdadf3caf9a266e9f149864ae7d073456 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 13:22:32 +0000 Subject: [PATCH 07/32] ignore external --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d4e9acd58..a7f1d43be 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,4 @@ tests/custom/*/*/*.map tests/custom/*/*/*.memfile tests/custom/crt0/*.a /pipelined/regression/sd_model.log +external From c18942bd0b5c7346a1c42f5ebc713861c5e5ab5a Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 13:26:07 +0000 Subject: [PATCH 08/32] refer to correct path --- pipelined/regression/wally-pipelined-imperas-no-idv.do | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/regression/wally-pipelined-imperas-no-idv.do b/pipelined/regression/wally-pipelined-imperas-no-idv.do index 213355e54..646c41c72 100644 --- a/pipelined/regression/wally-pipelined-imperas-no-idv.do +++ b/pipelined/regression/wally-pipelined-imperas-no-idv.do @@ -34,7 +34,7 @@ vlib work # *** 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 \ + ../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv \ ../testbench/testbench_imperas.sv \ ../testbench/common/*.sv \ ../src/*/*.sv \ From df4419dea2a8d31b0404b74f42ad009a24e5ddbf Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 13:33:57 +0000 Subject: [PATCH 09/32] remove volatile for FFLAGS and FCSR --- pipelined/testbench/testbench_imperas.sv | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index 23aff3cba..846662310 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -168,10 +168,8 @@ module testbench; 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 +// void'(rvviRefCsrSetVolatile(0, 32'h001)); // fflags +// void'(rvviRefCsrSetVolatile(0, 32'h003)); // fcsr // Enable the trace2log module From a5a5b7a408007646a4bb858ea94f7291327999d2 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 13:37:28 +0000 Subject: [PATCH 10/32] add im flags for compressed disass --- pipelined/regression/imperas.ic | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pipelined/regression/imperas.ic b/pipelined/regression/imperas.ic index 8a925389f..164cec228 100644 --- a/pipelined/regression/imperas.ic +++ b/pipelined/regression/imperas.ic @@ -1,20 +1,26 @@ #--showoverrides +--override cpu/show_c_prefix=T --override cpu/unaligned=F ---override refRoot/cpu/mstatus_FS=1 +--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 From 2e4e5f9c61b90916dd95fa1f7ade3abf690fe630 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 16:46:48 +0000 Subject: [PATCH 11/32] changes made with Ross --- pipelined/regression/wave.do | 78 +++++++++++++---------- pipelined/testbench/common/wallyTracer.sv | 18 ++++-- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/pipelined/regression/wave.do b/pipelined/regression/wave.do index be29ed870..edb10fc47 100644 --- a/pipelined/regression/wave.do +++ b/pipelined/regression/wave.do @@ -5,37 +5,37 @@ add wave -noupdate /testbench/reset add wave -noupdate /testbench/reset_ext add wave -noupdate /testbench/memfilename 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 -expand -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 -expand -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 -expand -group hazards /testbench/dut/core/hzu/LSUStallM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/MDUStallD -add wave -noupdate -group HDU -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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/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/FlushW -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallF -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallD -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallE -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallM -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallW +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/BPPredWrongE +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/RetM +add wave -noupdate -expand -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/MDUStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InterruptM +add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushD +add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushE +add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushM +add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushW +add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallF +add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallD +add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallE +add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallM +add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallW add wave -noupdate -group {instruction pipeline} /testbench/InstrFName add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/PostSpillInstrRawF add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD @@ -86,7 +86,6 @@ add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SSTATUS_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/STVEC_REGW add wave -noupdate -group Bpred -group {branch update selection inputs} -divider {class check} add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/BTBValidF -add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/BPInstrClassF add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/BTBPredPCF add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/TargetPredictor/LookUpPCIndex @@ -571,7 +570,6 @@ add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/FRD3E add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/ForwardedSrcAE add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/ForwardedSrcBE add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/Funct3E -add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/MDUE add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/W64E add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/unpack/X add wave -noupdate -group FPU /testbench/dut/core/fpu/fpu/unpack/Y @@ -603,8 +601,18 @@ add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/Br add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BranchInstrM add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewDirPredictionF add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewDirPredictionW +add wave -noupdate {/testbench/rvvi/csr[0][0][3]} +add wave -noupdate {/testbench/rvvi/csr[0][0][1]} +add wave -noupdate {/testbench/rvvi/csr_wb[0][0][3]} +add wave -noupdate {/testbench/rvvi/csr_wb[0][0][1]} +add wave -noupdate {/testbench/rvvi/valid[0][0]} +add wave -noupdate /testbench/rvvi/clk +add wave -noupdate {/testbench/rvvi/csr[0][0][768]} +add wave -noupdate /testbench/rvvi/csr +add wave -noupdate {/testbench/rvvi/csr_wb[0][0][768]} +add wave -noupdate /testbench/wallyTracer/InstrValidW TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {116741 ns} 0} +WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {104199 ns} 0} quietly wave cursor active 5 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 @@ -620,4 +628,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {118528 ns} {128752 ns} +WaveRestoreZoom {104186 ns} {104255 ns} diff --git a/pipelined/testbench/common/wallyTracer.sv b/pipelined/testbench/common/wallyTracer.sv index c7f68e65e..b1732488e 100644 --- a/pipelined/testbench/common/wallyTracer.sv +++ b/pipelined/testbench/common/wallyTracer.sv @@ -65,11 +65,13 @@ module wallyTracer(rvviTrace rvvi); 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(~StallW) begin + if(valid) begin // machine CSRs // *** missing PMP and performance counters. CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW; @@ -202,10 +204,9 @@ module wallyTracer(rvviTrace rvvi); // Initially connecting the writeback stage signals, but may need to use M stage // and gate on ~FlushW. - logic valid; assign valid = InstrValidW & ~StallW & ~FlushW; assign rvvi.clk = clk; - assign rvvi.valid[0][0] = valid; + 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; @@ -231,6 +232,8 @@ module wallyTracer(rvviTrace rvvi); 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 @@ -239,11 +242,16 @@ module wallyTracer(rvviTrace rvvi); 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 CSR_W[index5] = (CSRArrayOld[index5] != CSRArray[index5]) ? 1 : 0; + 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; From 7c0cad148d6dc605ee6280ddd299660ee05c8bae Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Wed, 18 Jan 2023 17:11:39 +0000 Subject: [PATCH 12/32] Partial fix for misaligned LD/ST --- pipelined/regression/wave.do | 81 ++++++++++++----------- pipelined/testbench/common/wallyTracer.sv | 2 +- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/pipelined/regression/wave.do b/pipelined/regression/wave.do index edb10fc47..62de1867b 100644 --- a/pipelined/regression/wave.do +++ b/pipelined/regression/wave.do @@ -5,48 +5,48 @@ add wave -noupdate /testbench/reset add wave -noupdate /testbench/reset_ext add wave -noupdate /testbench/memfilename add wave -noupdate /testbench/dut/core/SATP_REGW -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/BPPredWrongE -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/RetM -add wave -noupdate -expand -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/MDUStallD -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InterruptM -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushD -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushE -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushM -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/core/FlushW -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallF -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallD -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallE -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallM -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallW +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/BPPredWrongE +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/RetM +add wave -noupdate -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM +add wave -noupdate -group HDU -group hazards /testbench/dut/core/MDUStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM +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/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/FlushW +add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallF +add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallD +add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallE +add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallM +add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/core/StallW add wave -noupdate -group {instruction pipeline} /testbench/InstrFName add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/PostSpillInstrRawF add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrE add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrM -add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCNextF -add wave -noupdate -expand -group PCS /testbench/dut/core/PCF -add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCD -add wave -noupdate -expand -group PCS /testbench/dut/core/PCE -add wave -noupdate -expand -group PCS /testbench/dut/core/PCM -add wave -noupdate -expand -group PCS /testbench/PCW +add wave -noupdate -group PCS /testbench/dut/core/ifu/PCNextF +add wave -noupdate -group PCS /testbench/dut/core/PCF +add wave -noupdate -group PCS /testbench/dut/core/ifu/PCD +add wave -noupdate -group PCS /testbench/dut/core/PCE +add wave -noupdate -group PCS /testbench/dut/core/PCM +add wave -noupdate -group PCS /testbench/PCW add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/PCD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD add wave -noupdate -group {Decode Stage} /testbench/InstrDName @@ -611,8 +611,11 @@ add wave -noupdate {/testbench/rvvi/csr[0][0][768]} add wave -noupdate /testbench/rvvi/csr add wave -noupdate {/testbench/rvvi/csr_wb[0][0][768]} add wave -noupdate /testbench/wallyTracer/InstrValidW +add wave -noupdate -color Yellow /testbench/dut/core/FlushW +add wave -noupdate -color Orange /testbench/dut/core/StallW +add wave -noupdate {/testbench/rvvi/insn[0][0]} TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {104199 ns} 0} +WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {4687 ns} 0} quietly wave cursor active 5 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 @@ -628,4 +631,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {104186 ns} {104255 ns} +WaveRestoreZoom {4636 ns} {4705 ns} diff --git a/pipelined/testbench/common/wallyTracer.sv b/pipelined/testbench/common/wallyTracer.sv index b1732488e..23aaebd10 100644 --- a/pipelined/testbench/common/wallyTracer.sv +++ b/pipelined/testbench/common/wallyTracer.sv @@ -204,7 +204,7 @@ module wallyTracer(rvviTrace rvvi); // Initially connecting the writeback stage signals, but may need to use M stage // and gate on ~FlushW. - assign valid = InstrValidW & ~StallW & ~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 From e900914d3aeff23fd6b4630d79092b6965909c9e Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 18 Jan 2023 15:49:42 -0600 Subject: [PATCH 13/32] Modified to clone imperas via git rather than https. --- setup.imperas.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/setup.imperas.sh b/setup.imperas.sh index ac7740796..9a9f12f94 100644 --- a/setup.imperas.sh +++ b/setup.imperas.sh @@ -13,7 +13,7 @@ if [ ! -d external ]; then fi pushd external if [ ! -f ImperasDV-HMC ]; then - git clone https://github.com/Imperas/ImperasDV-HMC + git clone git@github.com:Imperas/ImperasDV-HMC.git fi pushd ImperasDV-HMC git checkout 0c2f365 @@ -37,3 +37,19 @@ pushd pipelined/regression vsim -c -do "do wally-pipelined-imperas-no-idv.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 From b53cb9eb2009c5f9584f3276289db436d298e685 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Thu, 19 Jan 2023 10:20:55 +0000 Subject: [PATCH 14/32] customer commands --- setup.imperas.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/setup.imperas.sh b/setup.imperas.sh index ac7740796..7ec1afd99 100644 --- a/setup.imperas.sh +++ b/setup.imperas.sh @@ -1,11 +1,12 @@ #!/bin/bash -echo "Imperas Environment to setup Wally" +REPO=davidharrishmc +REPO=eroom1966 +git clone https://github.com/${REPO}/riscv-wally -b imperas -# Path to Wally repository +cd riscv-wally WALLY=$(dirname ${BASH_SOURCE[0]:-$0}) export WALLY=$(cd "$WALLY" && pwd) -echo \$WALLY set to ${WALLY} # clone the Imperas repo if [ ! -d external ]; then @@ -16,24 +17,23 @@ pushd external git clone https://github.com/Imperas/ImperasDV-HMC fi pushd ImperasDV-HMC - git checkout 0c2f365 + git checkout fac563d popd popd -isetup -dv ${WALLY}/external/ImperasDV-HMC/Imperas +# 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=../../tests/riscof_lee/work/riscv-arch-test/rv64i_m/F/src/fadd_b1-01.S \ + 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" - - # 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 From a34a1e62388074af0cb55ce95d9545537c896346 Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Thu, 19 Jan 2023 10:41:11 +0000 Subject: [PATCH 15/32] correct the HASH --- setup.imperas.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.imperas.sh b/setup.imperas.sh index 7ec1afd99..d1de23ab4 100644 --- a/setup.imperas.sh +++ b/setup.imperas.sh @@ -1,5 +1,7 @@ #!/bin/bash +IMP_HASH=56b1479 + REPO=davidharrishmc REPO=eroom1966 git clone https://github.com/${REPO}/riscv-wally -b imperas @@ -17,7 +19,7 @@ pushd external git clone https://github.com/Imperas/ImperasDV-HMC fi pushd ImperasDV-HMC - git checkout fac563d + git checkout $IMP_HASH popd popd From d9d5b99218423873f4d48dbf52299092af5f618b Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Thu, 19 Jan 2023 13:29:46 +0000 Subject: [PATCH 16/32] update --- .gitignore | 1 + pipelined/regression/run-imperasdv-tests.bash | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100755 pipelined/regression/run-imperasdv-tests.bash diff --git a/.gitignore b/.gitignore index a7f1d43be..c9935826d 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,4 @@ tests/custom/*/*/*.memfile tests/custom/crt0/*.a /pipelined/regression/sd_model.log external +pipelined/regression/results diff --git a/pipelined/regression/run-imperasdv-tests.bash b/pipelined/regression/run-imperasdv-tests.bash new file mode 100755 index 000000000..c037c369d --- /dev/null +++ b/pipelined/regression/run-imperasdv-tests.bash @@ -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 From 2cca457f1485746686102615857f4dde7798dc13 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 20 Jan 2023 09:41:18 -0600 Subject: [PATCH 17/32] Imperas found a bug with the Fence.I instruction. If a fence.i directly followed a store miss, the d$ would release Stall during the cache line write. Then transition to ReadHold. This cause the d$ flush to go high while in ReadHold. The solution is to ensure the cache continues to assert Stall while in WriteLine state. There was a second issue also. The D$ flush asserted FlushD which flushed the I$ invalidate. Finally the third issue was CacheEn from the FSM needs to be asserted on an InvalidateCache. --- pipelined/src/cache/cachefsm.sv | 4 ++-- pipelined/src/cache/cacheway.sv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv index 4abbe59a2..a8be120b0 100644 --- a/pipelined/src/cache/cachefsm.sv +++ b/pipelined/src/cache/cachefsm.sv @@ -141,7 +141,7 @@ module cachefsm assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | - (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write. + (CurrState == STATE_WRITE_LINE) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write. (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_WRITEBACK); // write enables internal to cache @@ -181,6 +181,6 @@ module cachefsm resetDelay; assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD; - assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset; + assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; endmodule // cachefsm diff --git a/pipelined/src/cache/cacheway.sv b/pipelined/src/cache/cacheway.sv index 10bb4cfa0..8e9d12b18 100644 --- a/pipelined/src/cache/cacheway.sv +++ b/pipelined/src/cache/cacheway.sv @@ -152,7 +152,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, if (reset) ValidBits <= #1 '0; if(CacheEn) begin ValidWay <= #1 ValidBits[CAdr]; - if(InvalidateCache & ~FlushStage) ValidBits <= #1 '0; + if(InvalidateCache) ValidBits <= #1 '0; else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay; end end From 4cbefd98348f2a3ef6fbb358392f87a464f28403 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 30 Jan 2023 18:13:12 -0600 Subject: [PATCH 18/32] Minor gshare optimization. --- pipelined/src/ifu/bpred/speculativegshare.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 62608f0bb..f257d7537 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -109,7 +109,7 @@ module speculativegshare #(parameter int k = 10 ) ( always_comb begin if(FlushD | DirPredictionWrongE) begin - GHRNextF = GHRNextD[k-1:0]; + GHRNextF = GHRNextE[k-1:0]; end else if(BranchInstrF) GHRNextF = {DirPredictionF[1], GHRF[k-1:1]}; else GHRNextF = GHRF; end From 42828e6ec4900ed2ba9c461454085a3147375928 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 30 Jan 2023 19:27:18 -0600 Subject: [PATCH 19/32] Simplified gshare. --- pipelined/src/ifu/bpred/speculativegshare.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index f257d7537..fc497be7f 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -103,7 +103,7 @@ module speculativegshare #(parameter int k = 10 ) ( // GHR pipeline // this version fails the regression test do to pessimistic x propagation. - // assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextD[k-1:0] : + // assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextE[k-1:0] : // BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : // GHRF; From a15889e0aabfb4427b9d9bd207aa4c426b45462f Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 30 Jan 2023 23:37:34 -0600 Subject: [PATCH 20/32] Major cleanup of branch predictor. --- pipelined/src/ifu/bpred/speculativegshare.sv | 61 ++++++++------------ 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index fc497be7f..5fc5b7122 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -48,17 +48,13 @@ module speculativegshare #(parameter int k = 10 ) ( logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; logic [1:0] NewDirPredictionF, NewDirPredictionD, 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 FlushDOrDirWrong; assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]}; @@ -102,41 +98,32 @@ module speculativegshare #(parameter int k = 10 ) ( satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); // GHR pipeline - // this version fails the regression test do to pessimistic x propagation. - // assign GHRNextF = FlushD | DirPredictionWrongE ? GHRNextE[k-1:0] : - // BranchInstrF ? {DirPredictionF[1], GHRF[k-1:1]} : - // GHRF; - always_comb begin - if(FlushD | DirPredictionWrongE) begin - GHRNextF = GHRNextE[k-1:0]; - end else if(BranchInstrF) GHRNextF = {DirPredictionF[1], GHRF[k-1:1]}; - else GHRNextF = GHRF; - end + // If Fetch has a branch, speculatively insert prediction into the GHR + // If the front end is flushed or the direction prediction is wrong, reset to + // most recent valid GHR. For a BP wrong this is GHRD with the correct prediction shifted in. + // For FlushE this is GHRE. GHRNextE is both. + assign FlushDOrDirWrong = FlushD | DirPredictionWrongE; + mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0], + {FlushDOrDirWrong, BranchInstrF}, GHRNextF); + // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); - flopenr #(1) GHRFExtraReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRExtraF); + flopenr #(1) GHRFLastReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRLastF); - // use with out instruction class prediction - //assign GHRNextD = FlushD ? GHRNextE[k-1:0] : GHRF[k-1:0]; - // with instruction class prediction - assign GHRNextD = (FlushD | DirPredictionWrongE) ? GHRNextE[k-1:0] : - WrongPredInstrClassD[0] & BranchInstrD ? {DirPredictionD[1], GHRF[k-1:1]} : // shift right - WrongPredInstrClassD[0] & ~BranchInstrD ? {GHRF[k-2:0], GHRExtraF}: // shift left - GHRF[k-1:0]; + // With instruction class prediction, the class could be wrong and is checked in Decode. + // If it is wrong and branch does exist then shift right and insert the prediction. + // If the branch does not exist then shift left and use GHRLastF to restore the LSB. + logic [k-1:0] GHRClassWrong; + mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, BranchInstrD, GHRClassWrong); + // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. + mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD); flopenr #(k) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); - assign GHRNextE = BranchInstrE & ~FlushM ? {PCSrcE, GHRD[k-2:0]} : // if the branch is not flushed - FlushE ? GHRE : // branch is flushed - GHRD; + mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {BranchInstrE & ~FlushM, FlushE}, GHRNextE); + flopenr #(k) GHREReg(clk, reset, (BranchInstrE & ~StallE) | FlushE, GHRNextE, GHRE); - - //assign GHRNextM = FlushM ? GHRM : GHRE; - //flopenr #(k) GHRMReg(clk, reset, (BranchInstrM & ~StallM) | FlushM, GHRNextM, GHRM); - - //assign GHRNextW = FlushW ? GHRW : GHRM; - //flopenr #(k) GHRWReg(clk, reset, (BranchInstrW & ~StallW) | FlushW, GHRNextW, GHRW); assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; From 80f50f10d35728d7faf00805ceb95e90a4a40f3d Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 30 Jan 2023 23:51:04 -0600 Subject: [PATCH 21/32] Improved signal names. --- pipelined/src/ifu/bpred/bpred.sv | 3 +- pipelined/src/ifu/bpred/speculativegshare.sv | 40 ++++++++++---------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/pipelined/src/ifu/bpred/bpred.sv b/pipelined/src/ifu/bpred/bpred.sv index cccbe29f0..0f2b4bf6c 100644 --- a/pipelined/src/ifu/bpred/bpred.sv +++ b/pipelined/src/ifu/bpred/bpred.sv @@ -117,8 +117,7 @@ module bpred ( end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), - .BranchInstrW(InstrClassW[0]), .WrongPredInstrClassD, .PCSrcE); + .InstrClassF(PredInstrClassF), .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor // *** Fix me diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 5fc5b7122..2d0c9b90e 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -29,17 +29,17 @@ `include "wally-config.vh" module speculativegshare #(parameter int k = 10 ) ( - input logic clk, - input logic reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, - output logic [1:0] DirPredictionF, - output logic DirPredictionWrongE, + input logic clk, + input logic reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, + output logic [1:0] DirPredictionF, + output logic DirPredictionWrongE, // update input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic BranchInstrF, BranchInstrD, BranchInstrE, BranchInstrM, BranchInstrW, - input logic [3:0] WrongPredInstrClassD, - input logic PCSrcE + input logic [3:0] InstrClassF, InstrClassD, InstrClassE, + input logic [3:0] WrongPredInstrClassD, + input logic PCSrcE ); logic MatchF, MatchD, MatchE; @@ -67,14 +67,14 @@ module speculativegshare #(parameter int k = 10 ) ( .rd1(TableDirPredictionF), .wa2(IndexE), .wd2(NewDirPredictionE), - .we2(BranchInstrE & ~StallM & ~FlushM), + .we2(InstrClassE[0]), .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 // and then register for use in the Fetch stage. - assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); - assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); - assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); + assign MatchF = InstrClassF[0] & ~FlushD & (IndexNextF == IndexF); + assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD); + assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE); assign MatchNextX = MatchF | MatchD | MatchE; flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); @@ -105,26 +105,26 @@ module speculativegshare #(parameter int k = 10 ) ( // For FlushE this is GHRE. GHRNextE is both. assign FlushDOrDirWrong = FlushD | DirPredictionWrongE; mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0], - {FlushDOrDirWrong, BranchInstrF}, GHRNextF); + {FlushDOrDirWrong, InstrClassF[0]}, GHRNextF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. - flopenr #(k) GHRFReg(clk, reset, (~StallF) | FlushD, GHRNextF, GHRF); - flopenr #(1) GHRFLastReg(clk, reset, (~StallF) | FlushD, GHRF[0], GHRLastF); + flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushD, GHRNextF, GHRF); + flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushD, GHRF[0], GHRLastF); // With instruction class prediction, the class could be wrong and is checked in Decode. // If it is wrong and branch does exist then shift right and insert the prediction. // If the branch does not exist then shift left and use GHRLastF to restore the LSB. logic [k-1:0] GHRClassWrong; - mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, BranchInstrD, GHRClassWrong); + mux2 #(k) GHRClassWrongMux({DirPredictionD[1], GHRF[k-1:1]}, {GHRF[k-2:0], GHRLastF}, InstrClassD[0], GHRClassWrong); // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. mux3 #(k) GHRDMux(GHRF, GHRClassWrong, GHRNextE, {FlushDOrDirWrong, WrongPredInstrClassD[0]}, GHRNextD); flopenr #(k) GHRDReg(clk, reset, (~StallD) | FlushD, GHRNextD, GHRD); - mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {BranchInstrE & ~FlushM, FlushE}, GHRNextE); + mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE); - flopenr #(k) GHREReg(clk, reset, (BranchInstrE & ~StallE) | FlushE, GHRNextE, GHRE); + flopenr #(k) GHREReg(clk, reset, (InstrClassE[0] & ~StallE) | FlushE, GHRNextE, GHRE); - assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & BranchInstrE; + assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0]; endmodule From 238c4d14a9aea34ed37ef96b5a9ff4a9df6f3159 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 30 Jan 2023 23:55:52 -0600 Subject: [PATCH 22/32] More branch predictor cleanup. --- pipelined/src/ifu/bpred/bpred.sv | 18 ++++++++---------- pipelined/src/ifu/bpred/speculativegshare.sv | 6 +++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pipelined/src/ifu/bpred/bpred.sv b/pipelined/src/ifu/bpred/bpred.sv index 0f2b4bf6c..048aa1125 100644 --- a/pipelined/src/ifu/bpred/bpred.sv +++ b/pipelined/src/ifu/bpred/bpred.sv @@ -117,7 +117,7 @@ module bpred ( end else if (`BPRED_TYPE == "BPSPECULATIVEGSHARE") begin:Predictor speculativegshare #(`BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, - .InstrClassF(PredInstrClassF), .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE); + .PredInstrClassF, .InstrClassD, .InstrClassE, .WrongPredInstrClassD, .PCSrcE); end else if (`BPRED_TYPE == "BPLOCALPAg") begin:Predictor // *** Fix me @@ -151,15 +151,6 @@ module bpred ( .IEUAdrE, .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. if (`INSTR_CLASS_PRED == 0) begin : DirectClassDecode logic [4:0] CompressedOpcF; @@ -196,12 +187,19 @@ module bpred ( (PredInstrClassF[1] & PredValidF) ; 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[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 (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 + flopenrc #(4) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE); flopenrc #(4) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM); flopenrc #(4) InstrClassRegW(clk, reset, FlushW, ~StallW, InstrClassM, InstrClassW); diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 2d0c9b90e..09c1863b6 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -37,7 +37,7 @@ module speculativegshare #(parameter int k = 10 ) ( output logic DirPredictionWrongE, // update input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, - input logic [3:0] InstrClassF, InstrClassD, InstrClassE, + input logic [3:0] PredInstrClassF, InstrClassD, InstrClassE, input logic [3:0] WrongPredInstrClassD, input logic PCSrcE ); @@ -72,7 +72,7 @@ module speculativegshare #(parameter int k = 10 ) ( // 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. - assign MatchF = InstrClassF[0] & ~FlushD & (IndexNextF == IndexF); + assign MatchF = PredInstrClassF[0] & ~FlushD & (IndexNextF == IndexF); assign MatchD = InstrClassD[0] & ~FlushE & (IndexNextF == IndexD); assign MatchE = InstrClassE[0] & ~FlushM & (IndexNextF == IndexE); assign MatchNextX = MatchF | MatchD | MatchE; @@ -105,7 +105,7 @@ module speculativegshare #(parameter int k = 10 ) ( // For FlushE this is GHRE. GHRNextE is both. assign FlushDOrDirWrong = FlushD | DirPredictionWrongE; mux3 #(k) GHRFMux(GHRF, {DirPredictionF[1], GHRF[k-1:1]}, GHRNextE[k-1:0], - {FlushDOrDirWrong, InstrClassF[0]}, GHRNextF); + {FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushD, GHRNextF, GHRF); From 8feac6d242a11bbe21a07ebdad6f80c359c40515 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 00:08:11 -0600 Subject: [PATCH 23/32] Parameterized testbench branch predictor preload. --- pipelined/src/ifu/bpred/speculativegshare.sv | 9 +++------ pipelined/testbench/testbench.sv | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 09c1863b6..1c7ec6092 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -46,7 +46,7 @@ module speculativegshare #(parameter int k = 10 ) ( logic MatchNextX, MatchXF; logic [1:0] TableDirPredictionF, DirPredictionD, DirPredictionE; - logic [1:0] NewDirPredictionF, NewDirPredictionD, NewDirPredictionE; + logic [1:0] NewDirPredictionE; logic [k-1:0] GHRF, GHRD, GHRE; logic GHRLastF; @@ -79,8 +79,8 @@ module speculativegshare #(parameter int k = 10 ) ( flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); - assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : - MatchD ? NewDirPredictionD : + assign ForwardNewDirPrediction = MatchF ? {2{DirPredictionF[1]}} : + MatchD ? {2{DirPredictionD[1]}} : NewDirPredictionE ; flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); @@ -91,10 +91,7 @@ module speculativegshare #(parameter int k = 10 ) ( flopenr #(2) PredictionRegD(clk, reset, ~StallD, DirPredictionF, DirPredictionD); 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)); // GHR pipeline diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index 0696367da..0f25935f3 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -471,7 +471,7 @@ logic [3:0] dummy; genvar adrindex; // Initializing all zeroes into the branch predictor memory. - for(adrindex = 0; adrindex < 1024; adrindex++) begin + for(adrindex = 0; adrindex < 2**`BPRED_SIZE; adrindex++) 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; From 939095615fad7b67ed0e69a36fe5767111365982 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 00:11:01 -0600 Subject: [PATCH 24/32] Fixed parameterization in testbench. --- pipelined/testbench/testbench.sv | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index 0f25935f3..affb12128 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -471,13 +471,18 @@ logic [3:0] dummy; genvar adrindex; // Initializing all zeroes into the branch predictor memory. + for(adrindex = 0; adrindex < 2**10; adrindex++) begin + initial begin + force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; + #1; + release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex]; + 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; - force dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; #1; release dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex]; - release dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex]; end end From 0e3c77bed3af46d4da87705764c03cbdf50d6c4e Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 00:17:49 -0600 Subject: [PATCH 25/32] Found small bug in gshare. --- pipelined/src/ifu/bpred/speculativegshare.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 1c7ec6092..8ce431f6c 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -116,11 +116,11 @@ module speculativegshare #(parameter int k = 10 ) ( // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. 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 | FlushD, GHRNextD, GHRD); mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE); - flopenr #(k) GHREReg(clk, reset, (InstrClassE[0] & ~StallE) | FlushE, GHRNextE, GHRE); + flopenr #(k) GHREReg(clk, reset, ((InstrClassE[0] & ~FlushM) & ~StallE) | FlushE, GHRNextE, GHRE); assign DirPredictionWrongE = PCSrcE != DirPredictionE[1] & InstrClassE[0]; From ad0a0f0d515f583c2637ab9aab437dea41fd7275 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 10:44:11 -0600 Subject: [PATCH 26/32] Renamed signals in RAS. --- pipelined/src/ifu/bpred/RAsPredictor.sv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pipelined/src/ifu/bpred/RAsPredictor.sv b/pipelined/src/ifu/bpred/RAsPredictor.sv index d345a5b0c..0c47aed99 100644 --- a/pipelined/src/ifu/bpred/RAsPredictor.sv +++ b/pipelined/src/ifu/bpred/RAsPredictor.sv @@ -42,7 +42,7 @@ module RASPredictor #(parameter int StackSize = 16 )( logic CounterEn; 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; integer index; @@ -70,12 +70,12 @@ module RASPredictor #(parameter int StackSize = 16 )( assign CounterEn = PopF | PushE | RepairD; 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 PtrP1 = PtrQ + 1'b1; + assign PtrM1 = CurrPtr - 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. always_ff @ (posedge clk) begin @@ -87,7 +87,7 @@ module RASPredictor #(parameter int StackSize = 16 )( end end - assign RASPCF = memory[PtrQ]; + assign RASPCF = memory[CurrPtr]; endmodule From 5a770f148cfb018308c6bac7f62ba76212cdda8e Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 10:45:32 -0600 Subject: [PATCH 27/32] Minor bug fix in gshare. --- pipelined/src/ifu/bpred/speculativegshare.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pipelined/src/ifu/bpred/speculativegshare.sv b/pipelined/src/ifu/bpred/speculativegshare.sv index 8ce431f6c..23a49eac3 100644 --- a/pipelined/src/ifu/bpred/speculativegshare.sv +++ b/pipelined/src/ifu/bpred/speculativegshare.sv @@ -105,8 +105,8 @@ module speculativegshare #(parameter int k = 10 ) ( {FlushDOrDirWrong, PredInstrClassF[0]}, GHRNextF); // Need 1 extra bit to store the shifted out GHRF if repair needs to back shift. - flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushD, GHRNextF, GHRF); - flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushD, GHRF[0], GHRLastF); + flopenr #(k) GHRFReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRNextF, GHRF); + flopenr #(1) GHRFLastReg(clk, reset, ~StallF | FlushDOrDirWrong, GHRF[0], GHRLastF); // With instruction class prediction, the class could be wrong and is checked in Decode. // If it is wrong and branch does exist then shift right and insert the prediction. @@ -116,7 +116,7 @@ module speculativegshare #(parameter int k = 10 ) ( // As with GHRF FlushD and wrong direction prediction flushes the pipeline and restores to GHRNextE. 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); mux3 #(k) GHREMux(GHRD, GHRE, {PCSrcE, GHRD[k-2:0]}, {InstrClassE[0] & ~FlushM, FlushE}, GHRNextE); From c9c4f63c186932157cf15afbaa36e01e9d9567bb Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 13:04:26 -0600 Subject: [PATCH 28/32] Fixed remaining bugs in the imperas merge. --- pipelined/testbench/common/wallyTracer.sv | 14 +++++++------- pipelined/testbench/testbench_imperas.sv | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pipelined/testbench/common/wallyTracer.sv b/pipelined/testbench/common/wallyTracer.sv index 23aaebd10..14b229685 100644 --- a/pipelined/testbench/common/wallyTracer.sv +++ b/pipelined/testbench/common/wallyTracer.sv @@ -98,20 +98,20 @@ module wallyTracer(rvviTrace rvvi); 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.SSTATUS_REGW; + 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.STVEC_REGW; - CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.SEPC_REGW; - CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.SCOUNTEREN_REGW; - CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.SATP_REGW; + 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.FRM_REGW; - CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.FRM_REGW, 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]; diff --git a/pipelined/testbench/testbench_imperas.sv b/pipelined/testbench/testbench_imperas.sv index c8f036b1c..65c92eb33 100644 --- a/pipelined/testbench/testbench_imperas.sv +++ b/pipelined/testbench/testbench_imperas.sv @@ -111,7 +111,7 @@ module testbench; $error("Must specify test directory using plusarg testDir"); end - if (`BUS) $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."); ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; @@ -231,7 +231,7 @@ module testbench; // Track names of instructions 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.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); @@ -339,17 +339,17 @@ module riscvassertions; 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 (`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_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 (`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 < `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_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE)) 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_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE)) else $error("ICACHE_WAYSIZEINBYTES 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_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES 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_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(`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"); @@ -360,7 +360,7 @@ module riscvassertions; 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 ((`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_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"); @@ -383,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)]; - if(`DCACHE) begin + if(`DCACHE_SUPPORTED) begin localparam integer numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES; localparam integer numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS; localparam integer linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN; From 92fc532b82de3edbe73ec41a9a669f8bacb192c5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 13:51:05 -0600 Subject: [PATCH 29/32] Created scripts to install imperas and run a single test using imperas. --- bin/imperas-one-time.sh | 54 ++++++++++++++++++++++++++++++++ pipelined/regression/sim-imperas | 32 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100755 bin/imperas-one-time.sh create mode 100755 pipelined/regression/sim-imperas diff --git a/bin/imperas-one-time.sh b/bin/imperas-one-time.sh new file mode 100755 index 000000000..474bccea3 --- /dev/null +++ b/bin/imperas-one-time.sh @@ -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 + + diff --git a/pipelined/regression/sim-imperas b/pipelined/regression/sim-imperas new file mode 100755 index 000000000..d696f18e5 --- /dev/null +++ b/pipelined/regression/sim-imperas @@ -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" From a89f9dc92c5a258e2d18658d873f02b05951bac5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 14:35:05 -0600 Subject: [PATCH 30/32] RAS file name was spelled wrong. --- pipelined/src/ifu/bpred/{RAsPredictor.sv => RASPredictor.sv} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pipelined/src/ifu/bpred/{RAsPredictor.sv => RASPredictor.sv} (100%) diff --git a/pipelined/src/ifu/bpred/RAsPredictor.sv b/pipelined/src/ifu/bpred/RASPredictor.sv similarity index 100% rename from pipelined/src/ifu/bpred/RAsPredictor.sv rename to pipelined/src/ifu/bpred/RASPredictor.sv From fc2e3fed91fd34cf0479f04f01c0e9e561fe2f14 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 14:54:05 -0600 Subject: [PATCH 31/32] Simplified RAS. --- pipelined/src/ifu/bpred/RASPredictor.sv | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pipelined/src/ifu/bpred/RASPredictor.sv b/pipelined/src/ifu/bpred/RASPredictor.sv index 0c47aed99..6b2bdae4d 100644 --- a/pipelined/src/ifu/bpred/RASPredictor.sv +++ b/pipelined/src/ifu/bpred/RASPredictor.sv @@ -52,20 +52,21 @@ module RASPredictor #(parameter int StackSize = 16 )( logic IncrRepairD, DecRepairD; logic DecrementPtr; + logic FlushedRetDE; + logic WrongPredRetD; + 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 WrongPredRetD = (WrongPredInstrClassD[2]) & ~StallE & ~FlushE; + assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); + + 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; From 81b280576ffb67bb1ff83cf472bf47ab46b52cbf Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 31 Jan 2023 15:17:32 -0600 Subject: [PATCH 32/32] Updates to RAS. --- pipelined/src/ifu/bpred/RASPredictor.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/ifu/bpred/RASPredictor.sv b/pipelined/src/ifu/bpred/RASPredictor.sv index 6b2bdae4d..f71cb48f4 100644 --- a/pipelined/src/ifu/bpred/RASPredictor.sv +++ b/pipelined/src/ifu/bpred/RASPredictor.sv @@ -60,7 +60,7 @@ module RASPredictor #(parameter int StackSize = 16 )( assign PushE = InstrClassE[3] & ~StallM & ~FlushM; assign WrongPredRetD = (WrongPredInstrClassD[2]) & ~StallE & ~FlushE; - assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); + assign FlushedRetDE = (~StallE & FlushE & InstrClassD[2]) | (~StallM & FlushM & InstrClassE[2]); // flushed ret assign RepairD = WrongPredRetD | FlushedRetDE ;