mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 02:05:21 +00:00
Merge branch 'openhwgroup:main' into main
This commit is contained in:
commit
639870598a
@ -24,18 +24,18 @@ New users may wish to do the following setup to access the server via a GUI and
|
||||
Terminal on Mac, cmd on Windows, xterm on Linux
|
||||
See A.1 about ssh -Y login from a terminal
|
||||
|
||||
Then clone the repo, source setup, make the tests and run regression
|
||||
Then fork and clone the repo, source setup, make the tests and run regression
|
||||
|
||||
If you don't already have a Github account, create one
|
||||
In a web browser, visit https://github.com/openhwgroup/cvw
|
||||
In the upper right part of the screen, click on Fork
|
||||
Create a fork, choosing the owner as your github account and the repository as cvw.
|
||||
Create a fork, choosing the owner as your github account
|
||||
and the repository as cvw.
|
||||
|
||||
On the Linux computer where you will be working, log in
|
||||
|
||||
Clone your fork of the repo and run the setup script. Change <yourgithubid> to your github id.
|
||||
|
||||
$ cd
|
||||
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
|
||||
$ cd cvw
|
||||
$ git remote add upstream https://github.com/openhwgroup/cvw
|
||||
|
@ -33,13 +33,14 @@
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
import os;
|
||||
import os;
|
||||
use Data::Dumper;
|
||||
|
||||
my $curderiv = "";
|
||||
my @derivlist = ();
|
||||
my %derivs;
|
||||
my %basederiv;
|
||||
my @derivnames = ();
|
||||
|
||||
if ($#ARGV != -1) {
|
||||
die("Usage: $0")
|
||||
@ -69,13 +70,20 @@ foreach my $line (<$fh>) {
|
||||
}
|
||||
&terminateDeriv();
|
||||
close($fh);
|
||||
foreach my $key (keys %derivs) {
|
||||
#foreach my $key (keys %derivs) {
|
||||
foreach my $key (@derivnames) {
|
||||
my $dir = "$ENV{WALLY}/config/deriv/$key";
|
||||
system("rm -rf $dir");
|
||||
system("mkdir -p $dir");
|
||||
my $configunmod = "$dir/config_unmod.vh";
|
||||
my $config = "$dir/config.vh";
|
||||
my $base = "$ENV{WALLY}/config/$basederiv{$key}/config.vh";
|
||||
if (! -e $base) {
|
||||
$base = "$ENV{WALLY}/config/deriv/$basederiv{$key}/config.vh";
|
||||
#if (! -e $base) {
|
||||
# die("Unable to find base config $base for $key\n");
|
||||
#}
|
||||
}
|
||||
system("cp $base $configunmod");
|
||||
open(my $unmod, $configunmod) or die "Could not open file '$configunmod' $!";
|
||||
open(my $fh, '>>', $config) or die "Could not open file '$config' $!";
|
||||
@ -111,6 +119,7 @@ sub terminateDeriv {
|
||||
if ($curderiv ne "") { # close out the previous derivative
|
||||
my @dl = @derivlist;
|
||||
$derivs{$curderiv} = \@dl;
|
||||
push(@derivnames, $curderiv);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,184 +0,0 @@
|
||||
//////////////////////////////////////////
|
||||
// config.vh
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 4 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Specify which features are configured
|
||||
// Macros to determine which modes are supported based on MISA
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 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.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// include shared configuration
|
||||
`include "BranchPredictorType.vh"
|
||||
|
||||
// RV32 or RV64: XLEN = 32 or 64
|
||||
localparam XLEN = 32'd64;
|
||||
|
||||
// IEEE 754 compliance
|
||||
localparam IEEE754 = 0;
|
||||
|
||||
localparam MISA = (32'h0014112D);
|
||||
localparam ZICSR_SUPPORTED = 1;
|
||||
localparam ZIFENCEI_SUPPORTED = 1;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam COUNTERS = 12'd32;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 1;
|
||||
localparam ZICBOM_SUPPORTED = 1;
|
||||
localparam ZICBOZ_SUPPORTED = 1;
|
||||
localparam ZICBOP_SUPPORTED = 1;
|
||||
localparam ZICCLSM_SUPPORTED = 1;
|
||||
localparam ZICOND_SUPPORTED = 1;
|
||||
localparam SVPBMT_SUPPORTED = 1;
|
||||
localparam SVNAPOT_SUPPORTED = 1;
|
||||
localparam SVINVAL_SUPPORTED = 1;
|
||||
|
||||
// LSU microarchitectural Features
|
||||
localparam BUS_SUPPORTED = 1;
|
||||
localparam DCACHE_SUPPORTED = 1;
|
||||
localparam ICACHE_SUPPORTED = 1;
|
||||
localparam VIRTMEM_SUPPORTED = 1;
|
||||
localparam VECTORED_INTERRUPTS_SUPPORTED = 1;
|
||||
localparam BIGENDIAN_SUPPORTED = 1;
|
||||
|
||||
// TLB configuration. Entries should be a power of 2
|
||||
localparam ITLB_ENTRIES = 32'd32;
|
||||
localparam DTLB_ENTRIES = 32'd32;
|
||||
|
||||
// Cache configuration. Sizes should be a power of two
|
||||
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
|
||||
localparam DCACHE_NUMWAYS = 32'd4;
|
||||
localparam DCACHE_WAYSIZEINBYTES = 32'd4096;
|
||||
localparam DCACHE_LINELENINBITS = 32'd512;
|
||||
localparam ICACHE_NUMWAYS = 32'd4;
|
||||
localparam ICACHE_WAYSIZEINBYTES = 32'd4096;
|
||||
localparam ICACHE_LINELENINBITS = 32'd512;
|
||||
localparam CACHE_SRAMLEN = 32'd128;
|
||||
|
||||
// Integer Divider Configuration
|
||||
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||
localparam IDIV_BITSPERCYCLE = 32'd4;
|
||||
localparam IDIV_ON_FPU = 1;
|
||||
|
||||
// Legal number of PMP entries are 0, 16, or 64
|
||||
localparam PMP_ENTRIES = 32'd16;
|
||||
|
||||
// Address space
|
||||
localparam logic [63:0] RESET_VECTOR = 64'h0000000000001000;
|
||||
|
||||
// WFI Timeout Wait
|
||||
localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
|
||||
// Peripheral Addresses
|
||||
// Peripheral memory space extends from BASE to BASE+RANGE
|
||||
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
|
||||
localparam DTIM_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h00001FFF;
|
||||
localparam IROM_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] IROM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] IROM_RANGE = 64'h00001FFF;
|
||||
localparam BOOTROM_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] BOOTROM_BASE = 64'h00001000 ;
|
||||
localparam logic [63:0] BOOTROM_RANGE = 64'h00000FFF;
|
||||
localparam BOOTROM_PRELOAD = 1'b1;
|
||||
localparam UNCORE_RAM_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] UNCORE_RAM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] UNCORE_RAM_RANGE = 64'h0FFFFFFF;
|
||||
localparam UNCORE_RAM_PRELOAD = 1'b1;
|
||||
localparam EXT_MEM_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] EXT_MEM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] EXT_MEM_RANGE = 64'h07FFFFFF;
|
||||
localparam CLINT_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] CLINT_BASE = 64'h02000000;
|
||||
localparam logic [63:0] CLINT_RANGE = 64'h0000FFFF;
|
||||
localparam GPIO_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] GPIO_BASE = 64'h10060000;
|
||||
localparam logic [63:0] GPIO_RANGE = 64'h000000FF;
|
||||
localparam UART_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] UART_BASE = 64'h10000000;
|
||||
localparam logic [63:0] UART_RANGE = 64'h00000007;
|
||||
localparam PLIC_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] PLIC_BASE = 64'h0C000000;
|
||||
localparam logic [63:0] PLIC_RANGE = 64'h03FFFFFF;
|
||||
localparam SDC_SUPPORTED = 1'b0;
|
||||
localparam logic [63:0] SDC_BASE = 64'h00013000;
|
||||
localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
||||
localparam SPI_SUPPORTED = 1'b1;
|
||||
localparam logic [63:0] SPI_BASE = 64'h10040000;
|
||||
localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
|
||||
|
||||
// Bus Interface width
|
||||
localparam AHBW = 32'd64;
|
||||
|
||||
// AHB
|
||||
localparam RAM_LATENCY = 32'b0;
|
||||
localparam BURST_EN = 1;
|
||||
|
||||
// Test modes
|
||||
|
||||
// Tie GPIO outputs back to inputs
|
||||
localparam GPIO_LOOPBACK_TEST = 0;
|
||||
localparam SPI_LOOPBACK_TEST = 0;
|
||||
|
||||
// Hardware configuration
|
||||
localparam UART_PRESCALE = 32'd0;
|
||||
|
||||
// Interrupt configuration
|
||||
localparam PLIC_NUM_SRC = 32'd53;
|
||||
localparam PLIC_NUM_SRC_LT_32 = (PLIC_NUM_SRC < 32);
|
||||
localparam PLIC_UART_ID = 32'd10;
|
||||
localparam PLIC_GPIO_ID = 32'd3;
|
||||
localparam PLIC_SPI_ID = 32'd6;
|
||||
localparam PLIC_SDC_ID = 32'd20;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
localparam BPRED_SIZE = 32'd10;
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
localparam INSTR_CLASS_PRED = 1;
|
||||
|
||||
localparam SVADU_SUPPORTED = 1;
|
||||
localparam ZMMUL_SUPPORTED = 0;
|
||||
|
||||
// FPU division architecture
|
||||
localparam RADIX = 32'h4;
|
||||
localparam DIVCOPIES = 32'h4;
|
||||
|
||||
// bit manipulation
|
||||
localparam ZBA_SUPPORTED = 1;
|
||||
localparam ZBB_SUPPORTED = 1;
|
||||
localparam ZBC_SUPPORTED = 1;
|
||||
localparam ZBS_SUPPORTED = 1;
|
||||
|
||||
// New compressed instructions
|
||||
localparam ZCB_SUPPORTED = 1;
|
||||
localparam ZCA_SUPPORTED = 0;
|
||||
localparam ZCF_SUPPORTED = 0;
|
||||
localparam ZCD_SUPPORTED = 0;
|
||||
|
||||
// Memory synthesis configuration
|
||||
localparam USE_SRAM = 0;
|
||||
|
||||
`include "config-shared.vh"
|
@ -41,12 +41,12 @@ RESET_VECTOR 64'h1000
|
||||
UNCORE_RAM_RANGE 64'h0FFFFFFF
|
||||
UNCORE_RAM_PRELOAD 1
|
||||
GPIO_LOOPBACK_TEST 0
|
||||
SPI_LOOPBACK_TEST 0
|
||||
UART_PRESCALE 0
|
||||
SPI_LOOPBACK_TEST 0
|
||||
UART_PRESCALE 32'd0
|
||||
PLIC_NUM_SRC 32'd53
|
||||
|
||||
# fpga is used for FPGA hardware. It adds the SDC and DDR (EXT_MEM)
|
||||
deriv fpga rv64gc buildroot
|
||||
deriv fpga buildroot
|
||||
BOOTROM_PRELOAD 1
|
||||
UNCORE_RAM_BASE 64'h2000
|
||||
UNCORE_RAM_RANGE 64'hFFF
|
||||
@ -71,7 +71,7 @@ BTB_SIZE 32'd5
|
||||
# The other syn configurations have the same trimming
|
||||
deriv syn_rv32i rv32i syn_rv32e
|
||||
deriv syn_rv32imc rv32imc syn_rv32e
|
||||
deriv syn_rv32gc rv32gc syn_rv32e
|
||||
deriv syn_rv32gc syn_rv32e
|
||||
deriv syn_rv64i rv64i syn_rv32e
|
||||
deriv syn_rv64gc rv64gc syn_rv32e
|
||||
|
||||
@ -84,34 +84,34 @@ USE_SRAM 1
|
||||
# The other syn configurations have the same trimming
|
||||
deriv syn_sram_rv32i rv32i syn_sram_rv32e
|
||||
deriv syn_sram_rv32imc rv32imc syn_sram_rv32e
|
||||
deriv syn_sram_rv32gc rv32gc syn_sram_rv32e
|
||||
deriv syn_sram_rv32gc syn_sram_rv32e
|
||||
deriv syn_sram_rv64i rv64i syn_sram_rv32e
|
||||
deriv syn_sram_rv64gc rv64gc syn_sram_rv32e
|
||||
|
||||
# The following syn configurations gradually turn off features
|
||||
deriv syn_pmp0_rv64gc rv64gc syn_rv64gc
|
||||
deriv syn_pmp0_rv64gc syn_rv64gc
|
||||
PMP_ENTRIES 32'd0
|
||||
deriv syn_sram_pmp0_rv64gc rv64gc syn_sram_rv64gc
|
||||
deriv syn_sram_pmp0_rv64gc syn_sram_rv64gc
|
||||
PMP_ENTRIES 32'd0
|
||||
|
||||
deriv syn_noPriv_rv64gc rv64gc syn_pmp0_rv64gc
|
||||
deriv syn_noPriv_rv64gc syn_pmp0_rv64gc
|
||||
ZICSR_SUPPORTED 0
|
||||
deriv syn_sram_noPriv_rv64gc rv64gc syn_sram_pmp0_rv64gc
|
||||
deriv syn_sram_noPriv_rv64gc syn_sram_pmp0_rv64gc
|
||||
ZICSR_SUPPORTED 0
|
||||
|
||||
deriv syn_noFPU_rv64gc rv64gc syn_noPriv_rv64gc
|
||||
deriv syn_noFPU_rv64gc syn_noPriv_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
deriv syn_sram_noFPU_rv64gc rv64gc syn_sram_noPriv_rv64gc
|
||||
deriv syn_sram_noFPU_rv64gc syn_sram_noPriv_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
|
||||
deriv syn_noMulDiv_rv64gc rv64gc syn_noFPU_rv64gc
|
||||
deriv syn_noMulDiv_rv64gc syn_noFPU_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20 | 1 << 0)
|
||||
deriv syn_sram_noMulDiv_rv64gc rv64gc syn_sram_noFPU_rv64gc
|
||||
deriv syn_sram_noMulDiv_rv64gc syn_sram_noFPU_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20 | 1 << 0)
|
||||
|
||||
deriv syn_noAtomic_rv64gc rv64gc syn_noMulDiv_rv64gc
|
||||
deriv syn_noAtomic_rv64gc syn_noMulDiv_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20)
|
||||
deriv syn_sram_noAtomic_rv64gc rv64gc syn_sram_noMulDiv_rv64gc
|
||||
deriv syn_sram_noAtomic_rv64gc syn_sram_noMulDiv_rv64gc
|
||||
MISA (32'h00000104 | 1 << 18 | 1 << 20)
|
||||
|
||||
# Divider variants to check logical correctness
|
||||
@ -119,85 +119,98 @@ MISA (32'h00000104 | 1 << 18 | 1 << 20)
|
||||
deriv div_2_1_rv32gc rv32gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd1
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_2_rv32gc rv32gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd2
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_4_rv32gc rv32gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd4
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_1_rv32gc rv32gc
|
||||
RADIX 32'd4
|
||||
DIVCOPIES 32'd1
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_2_rv32gc rv32gc
|
||||
RADIX 32'd4
|
||||
IDIV_ON_FPU 0
|
||||
DIVCOPIES 32'd2
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_4_rv32gc rv32gc
|
||||
RADIX 32'd4
|
||||
DIVCOPIES 32'd4
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_1i_rv32gc rv32gc div_2_1_rv32gc
|
||||
deriv div_2_1i_rv32gc div_2_1_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_2_2i_rv32gc rv32gc div_2_2_rv32gc
|
||||
deriv div_2_2i_rv32gc div_2_2_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_2_4i_rv32gc rv32gc div_2_4_rv32gc
|
||||
deriv div_2_4i_rv32gc div_2_4_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_1i_rv32gc rv32gc div_4_1_rv32gc
|
||||
deriv div_4_1i_rv32gc div_4_1_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_2i_rv32gc rv32gc div_4_2_rv32gc
|
||||
deriv div_4_2i_rv32gc div_4_2_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_4i_rv32gc rv32gc div_4_4_rv32gc
|
||||
deriv div_4_4i_rv32gc div_4_4_rv32gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_2_1_rv64gc rv64gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd1
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_2_rv64gc rv64gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd2
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_4_rv64gc rv64gc
|
||||
RADIX 32'd2
|
||||
DIVCOPIES 32'd4
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_1_rv64gc rv64gc
|
||||
RADIX 32'd4
|
||||
DIVCOPIES 32'd1
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_2_rv64gc rv64gc
|
||||
RADIX 32'd4
|
||||
DIVCOPIES 32'd2
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_4_4_rv64gc rv64gc
|
||||
RADIX 32'd4
|
||||
DIVCOPIES 32'd4
|
||||
IDIV_ON_FPU 0
|
||||
|
||||
deriv div_2_1i_rv64gc rv64gc div_2_1_rv64gc
|
||||
deriv div_2_1i_rv64gc div_2_1_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_2_2i_rv64gc rv64gc div_2_2_rv64gc
|
||||
deriv div_2_2i_rv64gc div_2_2_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_2_4i_rv64gc rv64gc div_2_4_rv64gc
|
||||
deriv div_2_4i_rv64gc div_2_4_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_1i_rv64gc rv64gc div_4_1_rv64gc
|
||||
deriv div_4_1i_rv64gc div_4_1_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_2i_rv64gc rv64gc div_4_2_rv64gc
|
||||
deriv div_4_2i_rv64gc div_4_2_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
deriv div_4_4i_rv64gc rv64gc div_4_4_rv64gc
|
||||
deriv div_4_4i_rv64gc div_4_4_rv64gc
|
||||
IDIV_ON_FPU 1
|
||||
|
||||
# RAM latency and Burst mode for bus stress testing
|
||||
@ -242,22 +255,22 @@ BPRED_SIZE 32'd14
|
||||
deriv bpred_GSHARE_16_16_10_1_rv32gc rv32gc
|
||||
BPRED_SIZE 32'd16
|
||||
|
||||
deriv bpred_TWOBIT_6_16_10_1_rv32gc rv32gc bpred_GSHARE_6_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_6_16_10_1_rv32gc bpred_GSHARE_6_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_TWOBIT_8_16_10_1_rv32gc rv32gc bpred_GSHARE_8_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_8_16_10_1_rv32gc bpred_GSHARE_8_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_TWOBIT_10_16_10_1_rv32gc rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_10_16_10_1_rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_TWOBIT_12_16_10_1_rv32gc rv32gc bpred_GSHARE_12_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_12_16_10_1_rv32gc bpred_GSHARE_12_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_TWOBIT_14_16_10_1_rv32gc rv32gc bpred_GSHARE_14_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_14_16_10_1_rv32gc bpred_GSHARE_14_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_TWOBIT_16_16_10_1_rv32gc rv32gc bpred_GSHARE_16_16_10_1_rv32gc
|
||||
deriv bpred_TWOBIT_16_16_10_1_rv32gc bpred_GSHARE_16_16_10_1_rv32gc
|
||||
BPRED_TYPE `BP_TWOBIT
|
||||
|
||||
deriv bpred_GSHARE_10_2_10_1_rv32gc rv32gc
|
||||
@ -272,100 +285,104 @@ RAS_SIZE 32'd4
|
||||
deriv bpred_GSHARE_10_6_10_1_rv32gc rv32gc
|
||||
RAS_SIZE 32'd6
|
||||
|
||||
deriv bpred_GSHARE_10_2_10_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_10_10_1_rv32gc rv32gc
|
||||
RAS_SIZE 32'd10
|
||||
|
||||
deriv bpred_GSHARE_10_16_10_1_rv32gc rv32gc
|
||||
RAS_SIZE 32'd16
|
||||
|
||||
deriv bpred_GSHARE_10_2_6_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_16_6_1_rv32gc rv32gc
|
||||
BTB_SIZE 32'd6
|
||||
|
||||
deriv bpred_GSHARE_10_2_8_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_16_8_1_rv32gc rv32gc
|
||||
BTB_SIZE 32'd8
|
||||
|
||||
deriv bpred_GSHARE_10_2_12_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_16_12_1_rv32gc rv32gc
|
||||
BTB_SIZE 32'd12
|
||||
|
||||
deriv bpred_GSHARE_10_2_14_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_16_14_1_rv32gc rv32gc
|
||||
BTB_SIZE 32'd14
|
||||
|
||||
deriv bpred_GSHARE_10_2_16_1_rv32gc rv32gc
|
||||
deriv bpred_GSHARE_10_16_16_1_rv32gc rv32gc
|
||||
BTB_SIZE 32'd16
|
||||
|
||||
deriv bpred_GSHARE_6_16_10_0_rv32gc rv32gc bpred_GSHARE_6_16_10_1_rv32gc
|
||||
|
||||
|
||||
|
||||
deriv bpred_GSHARE_6_16_10_0_rv32gc bpred_GSHARE_6_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_8_16_10_0_rv32gc rv32gc bpred_GSHARE_8_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_8_16_10_0_rv32gc bpred_GSHARE_8_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_16_10_0_rv32gc rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_10_0_rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_12_16_10_0_rv32gc rv32gc bpred_GSHARE_12_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_12_16_10_0_rv32gc bpred_GSHARE_12_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_14_16_10_0_rv32gc rv32gc bpred_GSHARE_14_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_14_16_10_0_rv32gc bpred_GSHARE_14_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_16_16_10_0_rv32gc rv32gc bpred_GSHARE_16_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_16_16_10_0_rv32gc bpred_GSHARE_16_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_6_16_10_0_rv32gc rv32gc bpred_GSHARE_6_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_6_16_10_0_rv32gc bpred_TWOBIT_6_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_8_16_10_0_rv32gc rv32gc bpred_GSHARE_8_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_8_16_10_0_rv32gc bpred_TWOBIT_8_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_10_16_10_0_rv32gc rv32gc bpred_GSHARE_10_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_10_16_10_0_rv32gc bpred_TWOBIT_10_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_12_16_10_0_rv32gc rv32gc bpred_GSHARE_12_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_12_16_10_0_rv32gc bpred_TWOBIT_12_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_14_16_10_0_rv32gc rv32gc bpred_GSHARE_14_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_14_16_10_0_rv32gc bpred_TWOBIT_14_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_TWOBIT_16_16_10_0_rv32gc rv32gc bpred_GSHARE_16_16_10_0_rv32gc
|
||||
deriv bpred_TWOBIT_16_16_10_0_rv32gc bpred_TWOBIT_16_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_10_0_rv32gc rv32gc bpred_GSHARE_10_2_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_2_10_0_rv32gc bpred_GSHARE_10_2_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_3_10_0_rv32gc rv32gc bpred_GSHARE_10_3_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_3_10_0_rv32gc bpred_GSHARE_10_3_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_4_10_0_rv32gc rv32gc bpred_GSHARE_10_4_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_4_10_0_rv32gc bpred_GSHARE_10_4_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_6_10_0_rv32gc rv32gc bpred_GSHARE_10_6_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_6_10_0_rv32gc bpred_GSHARE_10_6_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_10_0_rv32gc rv32gc bpred_GSHARE_10_2_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_10_10_0_rv32gc bpred_GSHARE_10_10_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_16_10_0_rv32gc rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_10_0_rv32gc bpred_GSHARE_10_16_10_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_6_0_rv32gc rv32gc bpred_GSHARE_10_2_6_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_6_0_rv32gc bpred_GSHARE_10_16_6_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_8_0_rv32gc rv32gc bpred_GSHARE_10_2_8_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_8_0_rv32gc bpred_GSHARE_10_16_8_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_12_0_rv32gc rv32gc bpred_GSHARE_10_2_12_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_12_0_rv32gc bpred_GSHARE_10_16_12_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_14_0_rv32gc rv32gc bpred_GSHARE_10_2_14_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_14_0_rv32gc bpred_GSHARE_10_16_14_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
deriv bpred_GSHARE_10_2_16_0_rv32gc rv32gc bpred_GSHARE_10_2_16_1_rv32gc
|
||||
deriv bpred_GSHARE_10_16_16_0_rv32gc bpred_GSHARE_10_16_16_1_rv32gc
|
||||
INSTR_CLASS_PRED 0
|
||||
|
||||
# Cache configurations
|
||||
|
||||
deriv noicache_rv32gc rv32gc
|
||||
ICACHE_SUPPORTED 0
|
||||
VIRTMEM_SUPPORTED 0
|
||||
|
||||
deriv nodcache_rv32gc rv32gc
|
||||
DCACHE_SUPPORTED 0
|
||||
@ -374,6 +391,31 @@ deriv nocache_rv32gc rv32gc
|
||||
ICACHE_SUPPORTED 0
|
||||
DCACHE_SUPPORTED 0
|
||||
|
||||
deriv noicache_rv64gc rv64gc
|
||||
ICACHE_SUPPORTED 0
|
||||
VIRTMEM_SUPPORTED 0
|
||||
SVPBMT_SUPPORTED 0
|
||||
SVNAPOT_SUPPORTED 0
|
||||
|
||||
deriv nodcache_rv64gc rv64gc
|
||||
DCACHE_SUPPORTED 0
|
||||
VIRTMEM_SUPPORTED 0
|
||||
ZICBOM_SUPPORTED 0
|
||||
ZICBOZ_SUPPORTED 0
|
||||
SVPBMT_SUPPORTED 0
|
||||
SVNAPOT_SUPPORTED 0
|
||||
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12)
|
||||
|
||||
deriv nocache_rv64gc rv64gc
|
||||
ICACHE_SUPPORTED 0
|
||||
DCACHE_SUPPORTED 0
|
||||
VIRTMEM_SUPPORTED 0
|
||||
ZICBOM_SUPPORTED 0
|
||||
ZICBOZ_SUPPORTED 0
|
||||
SVPBMT_SUPPORTED 0
|
||||
SVNAPOT_SUPPORTED 0
|
||||
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12)
|
||||
|
||||
deriv way_1_4096_512_rv32gc rv32gc
|
||||
DCACHE_NUMWAYS 32'd1
|
||||
DCACHE_WAYSIZEINBYTES 32'd4096
|
||||
@ -382,40 +424,26 @@ ICACHE_NUMWAYS 32'd1
|
||||
ICACHE_WAYSIZEINBYTES 32'd4096
|
||||
ICACHE_LINELENINBITS 32'd512
|
||||
|
||||
deriv way_2_4096_512_rv32gc rv32gc way_1_4096_512_rv32gc
|
||||
deriv way_2_4096_512_rv32gc way_1_4096_512_rv32gc
|
||||
DCACHE_NUMWAYS 32'd1
|
||||
ICACHE_NUMWAYS 32'd1
|
||||
|
||||
deriv way_4_4096_512_rv32gc rv32gc way_1_4096_512_rv32gc
|
||||
deriv way_4_4096_512_rv32gc way_1_4096_512_rv32gc
|
||||
DCACHE_NUMWAYS 32'd4
|
||||
ICACHE_NUMWAYS 32'd4
|
||||
|
||||
deriv way_8_4096_512_rv32gc rv32gc way_1_4096_512_rv32gc
|
||||
deriv way_8_4096_512_rv32gc way_1_4096_512_rv32gc
|
||||
DCACHE_NUMWAYS 32'd8
|
||||
ICACHE_NUMWAYS 32'd8
|
||||
|
||||
deriv way_4_2048_512_rv32gc rv32gc way_4_4096_512_rv32gc
|
||||
deriv way_4_2048_512_rv32gc way_4_4096_512_rv32gc
|
||||
DCACHE_WAYSIZEINBYTES 32'd2048
|
||||
ICACHE_WAYSIZEINBYTES 32'd2048
|
||||
|
||||
deriv way_4_4096_256_rv32gc rv32gc way_4_4096_512_rv32gc
|
||||
deriv way_4_4096_256_rv32gc way_4_4096_512_rv32gc
|
||||
DCACHE_LINELENINBITS 32'd256
|
||||
ICACHE_LINELENINBITS 32'd256
|
||||
|
||||
deriv way_4_4096_1024_rv32gc rv32gc way_4_4096_512_rv32gc
|
||||
DCACHE_LINELENINBITS 32'd1024
|
||||
ICACHE_LINELENINBITS 32'd1024
|
||||
|
||||
deriv noicache_rv64gc rv64gc
|
||||
ICACHE_SUPPORTED 0
|
||||
|
||||
deriv nodcache_rv64gc rv64gc
|
||||
DCACHE_SUPPORTED 0
|
||||
|
||||
deriv nocache_rv64gc rv64gc
|
||||
ICACHE_SUPPORTED 0
|
||||
DCACHE_SUPPORTED 0
|
||||
|
||||
deriv way_1_4096_512_rv64gc rv64gc
|
||||
DCACHE_NUMWAYS 32'd1
|
||||
DCACHE_WAYSIZEINBYTES 32'd4096
|
||||
@ -424,27 +452,27 @@ ICACHE_NUMWAYS 32'd1
|
||||
ICACHE_WAYSIZEINBYTES 32'd4096
|
||||
ICACHE_LINELENINBITS 32'd512
|
||||
|
||||
deriv way_2_4096_512_rv64gc rv64gc way_1_4096_512_rv64gc
|
||||
deriv way_2_4096_512_rv64gc way_1_4096_512_rv64gc
|
||||
DCACHE_NUMWAYS 32'd1
|
||||
ICACHE_NUMWAYS 32'd1
|
||||
|
||||
deriv way_4_4096_512_rv64gc rv64gc way_1_4096_512_rv64gc
|
||||
deriv way_4_4096_512_rv64gc way_1_4096_512_rv64gc
|
||||
DCACHE_NUMWAYS 32'd4
|
||||
ICACHE_NUMWAYS 32'd4
|
||||
|
||||
deriv way_8_4096_512_rv64gc rv64gc way_1_4096_512_rv64gc
|
||||
deriv way_8_4096_512_rv64gc way_1_4096_512_rv64gc
|
||||
DCACHE_NUMWAYS 32'd8
|
||||
ICACHE_NUMWAYS 32'd8
|
||||
|
||||
deriv way_4_2048_512_rv64gc rv64gc way_4_4096_512_rv64gc
|
||||
deriv way_4_2048_512_rv64gc way_4_4096_512_rv64gc
|
||||
DCACHE_WAYSIZEINBYTES 32'd2048
|
||||
ICACHE_WAYSIZEINBYTES 32'd2048
|
||||
|
||||
deriv way_4_4096_256_rv64gc rv64gc way_4_4096_512_rv64gc
|
||||
deriv way_4_4096_256_rv64gc way_4_4096_512_rv64gc
|
||||
DCACHE_LINELENINBITS 32'd256
|
||||
ICACHE_LINELENINBITS 32'd256
|
||||
|
||||
deriv way_4_4096_1024_rv64gc rv64gc way_4_4096_512_rv64gc
|
||||
deriv way_4_4096_1024_rv64gc way_4_4096_512_rv64gc
|
||||
DCACHE_LINELENINBITS 32'd1024
|
||||
ICACHE_LINELENINBITS 32'd1024
|
||||
|
||||
@ -490,6 +518,10 @@ deriv fh_rv32gc rv32gc
|
||||
MISA (32'h00000104 | 1 << 5 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
ZFH_SUPPORTED 1
|
||||
|
||||
deriv fd_rv32gc rv32gc
|
||||
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
ZFH_SUPPORTED 0
|
||||
|
||||
deriv fdh_rv32gc rv32gc
|
||||
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||
ZFH_SUPPORTED 1
|
||||
@ -524,32 +556,35 @@ ZFH_SUPPORTED 1
|
||||
|
||||
# IEEE compatible variants for TestFloat
|
||||
|
||||
deriv f_ieee_rv32gc rv32gc f_rv32gc
|
||||
deriv f_ieee_rv32gc f_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fh_ieee_v32gc rv32gc fh_rv32gc
|
||||
deriv fh_ieee_rv32gc fh_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdh_ieee_rv32gc rv32gc fdh_rv32gc
|
||||
deriv fd_ieee_rv32gc fd_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdq_ieee_rv32gc rv32gc fdq_rv32gc
|
||||
deriv fdh_ieee_rv32gc fdh_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdqh_ieee_rv32gc rv32gc fdqh_rv32gc
|
||||
deriv fdq_ieee_rv32gc fdq_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv f_ieee_rv64gc rv64gc f_rv64gc
|
||||
deriv fdqh_ieee_rv32gc fdqh_rv32gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fh_ieee_rv64gc rv64gc fh_rv64gc
|
||||
deriv f_ieee_rv64gc f_rv64gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fd_ieee_rv64gc rv64gc fd_rv64gc
|
||||
deriv fh_ieee_rv64gc fh_rv64gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdq_ieee_rv64gc rv64gc fdq_rv64gc
|
||||
deriv fd_ieee_rv64gc fd_rv64gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdqh_ieee_rv64gc rv64gc fdqh_rv64gc
|
||||
deriv fdq_ieee_rv64gc fdq_rv64gc
|
||||
IEEE754 1
|
||||
|
||||
deriv fdqh_ieee_rv64gc fdqh_rv64gc
|
||||
IEEE754 1
|
||||
|
@ -154,22 +154,11 @@ localparam PLIC_SPI_ID = 32'd6;
|
||||
localparam PLIC_SDC_ID = 32'd9;
|
||||
|
||||
localparam BPRED_SUPPORTED = 1;
|
||||
// this is an annoying hack for the branch predictor parameterization override.
|
||||
`ifdef BPRED_OVERRIDE
|
||||
localparam BPRED_TYPE = `BPRED_TYPE;
|
||||
localparam BPRED_SIZE = `BPRED_SIZE;
|
||||
`else
|
||||
localparam BPRED_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||
localparam BPRED_SIZE = 32'd10;
|
||||
`endif
|
||||
localparam BPRED_NUM_LHR = 32'd6;
|
||||
`ifdef BTB_OVERRIDE
|
||||
localparam BTB_SIZE = `BTB_SIZE;
|
||||
localparam RAS_SIZE = `RAS_SIZE;
|
||||
`else
|
||||
localparam BTB_SIZE = 32'd10;
|
||||
localparam RAS_SIZE = 32'd16;
|
||||
`endif
|
||||
localparam INSTR_CLASS_PRED = 1;
|
||||
|
||||
localparam SVADU_SUPPORTED = 1;
|
||||
|
@ -103,15 +103,15 @@ localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r intege
|
||||
localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk)
|
||||
localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits
|
||||
localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration
|
||||
localparam DIVBLEN = $clog2(DIVb); // enough bits to count number of fractional bits
|
||||
localparam DIVBLEN = $clog2(DIVb+1); // enough bits to count number of fractional bits + 1 integer bit
|
||||
|
||||
// largest length in IEU/FPU
|
||||
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
|
||||
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
|
||||
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
|
||||
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6)));
|
||||
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); // max(CVTLEN+NF+1, DIVb + 1 + NF + 1, 3*NF+6)
|
||||
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
|
||||
localparam CORRSHIFTSZ = (((DIVMINb+1+NF) > (3*NF+4) ? (DIVMINb+1+NF) : (3*NF+4))); // max(DIVMINb+NF+1, 3*NF+4)
|
||||
localparam CORRSHIFTSZ = (NORMSHIFTSZ-2 > (DIVMINb + 1 + NF)) ? NORMSHIFTSZ-2 : (DIVMINb+1+NF); // max(NORMSHIFTSZ-2, DIVMINb + 1 + NF)
|
||||
|
||||
|
||||
// Disable spurious Verilator warnings
|
||||
|
@ -48,29 +48,14 @@ IP_Arty: $(dst)/xlnx_proc_sys_reset.log \
|
||||
|
||||
|
||||
PreProcessFiles:
|
||||
$(MAKE) -C ../../sim deriv
|
||||
rm -rf ../src/CopiedFiles_do_not_add_to_repo/
|
||||
cp -r ../../src/ ../src/CopiedFiles_do_not_add_to_repo/
|
||||
mkdir ../src/CopiedFiles_do_not_add_to_repo/config/
|
||||
cp ../../config/rv64gc/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/
|
||||
cp ../../config/deriv/fpga/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/
|
||||
./insert_debug_comment.sh
|
||||
# modify config *** RT: eventually setup for variably defined sized memory
|
||||
sed -i "s/ZICCLSM_SUPPORTED.*/ZICCLSM_SUPPORTED = 1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/RESET_VECTOR.*/RESET_VECTOR = 64'h0000000000001000;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/BOOTROM_PRELOAD.*/BOOTROM_PRELOAD = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/UNCORE_RAM_BASE.*/UNCORE_RAM_BASE = 64'h00002000;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/UNCORE_RAM_RANGE.*/UNCORE_RAM_RANGE = 64'h00000FFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/UNCORE_RAM_PRELOAD.*/UNCORE_RAM_PRELOAD = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/EXT_MEM_SUPPORTED.*/EXT_MEM_SUPPORTED = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/SDC_SUPPORTED.*/SDC_SUPPORTED = 1'b1;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/SPI_SUPPORTED.*/SPI_SUPPORTED = 1'b0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh # *** RT: Add SPI when ready
|
||||
sed -i "s/GPIO_LOOPBACK_TEST.*/GPIO_LOOPBACK_TEST = 0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/SPI_LOOPBACK_TEST.*/SPI_LOOPBACK_TEST = 0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/UART_PRESCALE.*/UART_PRESCALE = 32'd0;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/PLIC_NUM_SRC = .*/PLIC_NUM_SRC = 32'd53;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/PLIC_SDC_ID.*/PLIC_SDC_ID = 32'd20;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/BPRED_SIZE.*/BPRED_SIZE = 32'd12;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
sed -i "s/$\$readmemh.*/$\$readmemh(\"..\/..\/..\/fpga\/src\/boot.mem\", ROM, 0);/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv
|
||||
#sed -i "s/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/g" ../src/CopiedFiles_do_not_add_to_repo/config/config.vh
|
||||
# This line allows the Bootloader to be loaded in a Block RAM on the FPGA
|
||||
sed -i "s/logic \[DATA_WIDTH-1:0\].*ROM.*/(\* rom_style=\"block\" \*) &/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv
|
||||
|
||||
|
@ -72,6 +72,13 @@ if [ ! -e "$SDCARD" ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prefix partition with "p" for non-SCSI disks (mmcblk, nvme)
|
||||
if [[ $SDCARD == "/dev/sd"* ]]; then
|
||||
$PART_PREFIX=""
|
||||
else
|
||||
$PART_PREFIX="p"
|
||||
fi
|
||||
|
||||
# If no images directory, images have not been built
|
||||
if [ ! -d $IMAGES ] ; then
|
||||
echo -e "$ERRORTEXT Buildroot images directory does not exist"
|
||||
@ -155,18 +162,18 @@ if [[ $REPLY =~ ^[Yy]$ ]] ; then
|
||||
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
|
||||
|
||||
echo -e "$NAME Copying device tree"
|
||||
sudo dd if=$DEVICE_TREE of="$SDCARD"1 $DD_FLAGS
|
||||
sudo dd if=$DEVICE_TREE of="$SDCARD""$PART_PREFIX"1 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME Copying OpenSBI"
|
||||
sudo dd if=$FW_JUMP of="$SDCARD"2 $DD_FLAGS
|
||||
sudo dd if=$FW_JUMP of="$SDCARD""$PART_PREFIX"2 $DD_FLAGS
|
||||
|
||||
echo -e "$NAME Copying Kernel"
|
||||
sudo dd if=$LINUX_KERNEL of="$SDCARD"3 $DD_FLAGS
|
||||
sudo dd if=$LINUX_KERNEL of="$SDCARD""$PART_PREFIX"3 $DD_FLAGS
|
||||
|
||||
sudo mkfs.ext4 "$SDCARD"4
|
||||
sudo mkfs.ext4 "$SDCARD""$PART_PREFIX"4
|
||||
sudo mkdir /mnt/$MNT_DIR
|
||||
|
||||
sudo mount -v "$SDCARD"4 /mnt/$MNT_DIR
|
||||
sudo mount -v "$SDCARD""$PART_PREFIX"4 /mnt/$MNT_DIR
|
||||
|
||||
sudo umount -v /mnt/$MNT_DIR
|
||||
|
||||
|
12
sim/Makefile
12
sim/Makefile
@ -1,5 +1,5 @@
|
||||
|
||||
all: riscoftests memfiles coveragetests deriv
|
||||
all: riscoftests memfiles coveragetests deriv benchmarks
|
||||
# *** Build old tests/imperas-riscv-tests for now;
|
||||
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
|
||||
# DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired
|
||||
@ -54,7 +54,7 @@ riscoftests:
|
||||
wallyriscoftests:
|
||||
# Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions
|
||||
make -C ../tests/riscof/ wally-riscv-arch-test
|
||||
|
||||
|
||||
memfiles:
|
||||
make -f makefile-memfile wally-sim-files --jobs
|
||||
|
||||
@ -63,4 +63,10 @@ coveragetests:
|
||||
|
||||
deriv:
|
||||
derivgen.pl
|
||||
|
||||
|
||||
benchmarks:
|
||||
$(MAKE) -C ../benchmarks/embench build
|
||||
$(MAKE) -C ../benchmarks/embench size
|
||||
$(MAKE) -C ../benchmarks/embench modelsim_build_memfile
|
||||
$(MAKE) -C ../benchmarks/coremark
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
../logs/rv32gc_gshare6.log gshare 6
|
||||
../logs/rv32gc_gshare8.log gshare 8
|
||||
../logs/rv32gc_gshare10.log gshare 10
|
||||
../logs/rv32gc_gshare12.log gshare 12
|
||||
../logs/rv32gc_gshare14.log gshare 14
|
||||
../logs/rv32gc_gshare16.log gshare 16
|
||||
../logs/rv32gc_twobit6.log twobit 6
|
||||
../logs/rv32gc_twobit8.log twobit 8
|
||||
../logs/rv32gc_twobit10.log twobit 10
|
||||
../logs/rv32gc_twobit12.log twobit 12
|
||||
../logs/rv32gc_twobit14.log twobit 14
|
||||
../logs/rv32gc_twobit16.log twobit 16
|
||||
../logs/bpred_GSHARE_6_16_10_0_rv32gc_embench.log gshare 6
|
||||
../logs/bpred_GSHARE_8_16_10_0_rv32gc_embench.log gshare 8
|
||||
../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log gshare 10
|
||||
../logs/bpred_GSHARE_12_16_10_0_rv32gc_embench.log gshare 12
|
||||
../logs/bpred_GSHARE_14_16_10_0_rv32gc_embench.log gshare 14
|
||||
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log gshare 16
|
||||
../logs/bpred_TWOBIT_6_16_10_0_rv32gc_embench.log twobit 6
|
||||
../logs/bpred_TWOBIT_8_16_10_0_rv32gc_embench.log twobit 8
|
||||
../logs/bpred_TWOBIT_10_16_10_0_rv32gc_embench.log twobit 10
|
||||
../logs/bpred_TWOBIT_12_16_10_0_rv32gc_embench.log twobit 12
|
||||
../logs/bpred_TWOBIT_14_16_10_0_rv32gc_embench.log twobit 14
|
||||
../logs/bpred_TWOBIT_16_16_10_0_rv32gc_embench.log twobit 16
|
||||
|
@ -1,6 +1,6 @@
|
||||
../logs/rv32gc_BTB6.log btb 6
|
||||
../logs/rv32gc_BTB8.log btb 8
|
||||
../logs/rv32gc_BTB10.log btb 10
|
||||
../logs/rv32gc_BTB12.log btb 12
|
||||
../logs/rv32gc_BTB14.log btb 14
|
||||
../logs/rv32gc_BTB16.log btb 16
|
||||
../logs/bpred_GSHARE_16_16_6_0_rv32gc_embench.log btb 6
|
||||
../logs/bpred_GSHARE_16_16_8_0_rv32gc_embench.log btb 8
|
||||
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log btb 10
|
||||
../logs/bpred_GSHARE_16_16_12_0_rv32gc_embench.log btb 12
|
||||
../logs/bpred_GSHARE_16_16_14_0_rv32gc_embench.log btb 14
|
||||
../logs/bpred_GSHARE_16_16_16_0_rv32gc_embench.log btb 16
|
||||
|
@ -1,6 +1,6 @@
|
||||
../logs/rv32gc_class6.log class 6
|
||||
../logs/rv32gc_class8.log class 8
|
||||
../logs/rv32gc_class10.log class 10
|
||||
../logs/rv32gc_class12.log class 12
|
||||
../logs/rv32gc_class14.log class 14
|
||||
../logs/rv32gc_class16.log class 16
|
||||
../logs/bpred_GSHARE_16_16_6_1_rv32gc_embench.log btb 6
|
||||
../logs/bpred_GSHARE_16_16_8_1_rv32gc_embench.log btb 8
|
||||
../logs/bpred_GSHARE_16_16_10_1_rv32gc_embench.log btb 10
|
||||
../logs/bpred_GSHARE_16_16_12_1_rv32gc_embench.log btb 12
|
||||
../logs/bpred_GSHARE_16_16_14_1_rv32gc_embench.log btb 14
|
||||
../logs/bpred_GSHARE_16_16_16_1_rv32gc_embench.log btb 16
|
||||
|
@ -1,5 +1,5 @@
|
||||
../logs/rv32gc_RAS3.log ras 3
|
||||
../logs/rv32gc_RAS4.log ras 4
|
||||
../logs/rv32gc_RAS6.log ras 6
|
||||
../logs/rv32gc_RAS10.log ras 10
|
||||
../logs/rv32gc_RAS16.log ras 16
|
||||
../logs/bpred_GSHARE_10_3_10_0_rv32gc_embench.log ras 3
|
||||
../logs/bpred_GSHARE_10_4_10_0_rv32gc_embench.log ras 4
|
||||
../logs/bpred_GSHARE_10_6_10_0_rv32gc_embench.log ras 6
|
||||
../logs/bpred_GSHARE_10_10_10_0_rv32gc_embench.log ras 10
|
||||
../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log ras 16
|
||||
|
@ -58,11 +58,12 @@ coverage exclude -scope /dut/core/fpu/fpu/postprocess/flags -linerange [GetLineN
|
||||
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
|
||||
# Also exclude the write line to ready transition for the I$ since we can't get a flush during this operation.
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -fstate CurrState STATE_FLUSH STATE_FLUSH_WRITEBACK STATE_FLUSH_WRITEBACK STATE_WRITEBACK
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -ftrans CurrState STATE_WRITE_LINE->STATE_READY STATE_FETCH->STATE_READY
|
||||
# exclude unused transitions from case statement. Unfortunately the whole branch needs to be excluded I think. Expression coverage should still work.
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache state-case"] -item b 1
|
||||
# exclude branch/condition coverage: LineDirty if statement
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FETCHStatement"] -item bc 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache FLUSHStatement"] -item bs 1
|
||||
# exclude the unreachable logic
|
||||
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
|
||||
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"]
|
||||
@ -81,7 +82,9 @@ set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache flushdir
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"]
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrTag"] -item e 1 -fecexprrow 8
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12
|
||||
|
||||
# cache.sv AdrSelMuxData and AdrSelMuxTag and CacheBusAdrMux, excluding unhit Flush branch
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxData -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxTag -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
|
||||
@ -100,6 +103,26 @@ for {set i 0} {$i < $numcacheways} {incr i} {
|
||||
# No dirty ways in read-only I$
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache DirtyWay"] -item e 1
|
||||
}
|
||||
# I$ buscachefsm does not perform atomics or write/writeback; HREADY is always 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicReadData"]
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"] -item s 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicPhase"]
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"] -item bs 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item b 2
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item s 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback"]
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback2"] -item bs 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item bs 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item bs 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADYread"] -item c 1 -feccondrow 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"] -item c 1 -feccondrow 1,2,3,4,6
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"] -item c 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"] -item c 1
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign HTRANS"] -item c 1 -feccondrow 5
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BeatCntEn"] -item e 1 -fecexprrow 4
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheAccess"] -item e 1 -fecexprrow 4
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign BusStall"] -item e 1 -fecexprrow 10,12,18
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheBusAck"] -item e 1 -fecexprrow 3
|
||||
|
||||
## D$ Exclusions.
|
||||
# InvalidateCache is I$ only:
|
||||
@ -117,10 +140,10 @@ for {set i 0} {$i < $numcacheways} {incr i} {
|
||||
# going into the WRITE_LINE state (and asserting SetValidWay). No TrapM can fire and since StallW is high, a stallM caused by WFIStallM would not cause a flushW.
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4
|
||||
# Not right; other ways can get flushed and dirtied simultaneously coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache UpdateDirty"] -item c 1 -fecexprrow 6
|
||||
# Not right; other ways can get flushed and dirtied simultaneously coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache UpdateDirty"] -item c 1 -feccondrow 6
|
||||
}
|
||||
# D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
|
||||
|
||||
####################
|
||||
# Unused / illegal peripheral accesses
|
||||
@ -136,7 +159,13 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec
|
||||
|
||||
# PMA Regions 8, 9, and 10 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage
|
||||
# PMA Regions 1, 2, and 3 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage
|
||||
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-atomic"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-tim"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
|
||||
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-cachable"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2
|
||||
@ -145,11 +174,17 @@ coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$lin
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6,8
|
||||
|
||||
# Excluding so far un-used instruction sources for the ifu
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/spidec
|
||||
|
||||
#Excluding the bootrom, uncoreran, and clint as sources for the lsu
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec
|
||||
# The following peripherals are always supported
|
||||
set line [GetLineNum ../src/mmu/adrdec.sv "exclusion-tag: adrdecSel"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec -linerange $line-$line -item e 1 -fecexprrow 3,7
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/spidec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
|
||||
#Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0
|
||||
set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
|
||||
@ -158,22 +193,15 @@ set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uncoreramdec -linerange $line-$line -item e 1 -fecexprrow 5
|
||||
|
||||
# set line [GetLineNum ../src/mmu/adrdec.sv "& Supported"]
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec
|
||||
|
||||
# No DTIM or IROM
|
||||
coverage exclude -scope /dut/core/ifu/bus/icache/UnCachedDataMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/UnCachedDataMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
|
||||
|
||||
####################
|
||||
# Unused access types due to sharing IFU and LSU logic
|
||||
####################
|
||||
@ -216,6 +244,10 @@ set line [GetLineNum ../src/mmu/mmu.sv "ExecuteAccessF \\| ReadAccessM"]
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4
|
||||
set line [GetLineNum ../src/mmu/mmu.sv "ReadAccessM & ~WriteAccessM"]
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 2-4
|
||||
set line [GetLineNum ../src/mmu/mmu.sv "assign AmoAccessM"]
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1
|
||||
set line [GetLineNum ../src/mmu/mmu.sv "assign AmoMisalignedCausesAccessFaultM"]
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1
|
||||
set line [GetLineNum ../src/mmu/mmu.sv "DataMisalignedM & WriteAccessM"]
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,2,4
|
||||
set line [GetLineNum ../src/mmu/mmu.sv "TLBPageFault & ExecuteAccessF"]
|
||||
@ -308,6 +340,56 @@ coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item
|
||||
set line [GetLineNum ../src/ebu/ebufsmarb.sv "FinalBeatReg\\("]
|
||||
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
|
||||
|
||||
# The WritebackWriteback and FetchWriteback support back to back pipelined cache writebacks and fetch then
|
||||
# writebacks. The cache never issues these type of requests.
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm WritebackWriteback"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 2
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWriteback"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 2
|
||||
|
||||
# FetchWait never occurs because HREADY is never 0.
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm FetchWait"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item bc 1
|
||||
|
||||
# all of these HREADY exclusions occur because HREADY is always 1. The ram_ahb module never stalls.
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY0"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
|
||||
#set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY1"]
|
||||
#coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
|
||||
#set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY2"]
|
||||
#coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY3"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 4
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY4"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 3
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY5"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
|
||||
set line [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm HREADY6"]
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 1
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange $line-$line -item c 1 -feccondrow 5
|
||||
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "assign CacheBusAck"] -item e 1 -fecexprrow 5
|
||||
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicElse"] -item s 1
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -linerange [GetLineNum ../src/ebu/buscachefsm.sv "exclusion-tag: buscachefsm AtomicWait"] -item s 1
|
||||
|
||||
# these transitions will not happen
|
||||
coverage exclude -scope /dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm -ftrans CurrState DATA_PHASE->ADR_PHASE ATOMIC_READ_DATA_PHASE->ADR_PHASE ATOMIC_PHASE->ADR_PHASE
|
||||
|
||||
# TLB not recently used never has all RU bits = 1 because it will then clear all to 0
|
||||
# This is a blunt instrument; perhaps there is a more graceful exclusion
|
||||
coverage exclude -srcfile priorityonehot.sv
|
||||
@ -316,6 +398,13 @@ coverage exclude -srcfile priorityonehot.sv
|
||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
|
||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
|
||||
|
||||
####################
|
||||
# Privileged
|
||||
####################
|
||||
|
||||
# Instruction Misaligned never asserted because compresssed instructions are accepted
|
||||
coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ../src/privileged/trap.sv "assign ExceptionM"] -item e 1 -fecexprrow 2
|
||||
|
||||
####################
|
||||
# EBU
|
||||
####################
|
||||
|
@ -6,26 +6,43 @@ export PATH=$PATH:/usr/local/bin/
|
||||
verilator=`which verilator`
|
||||
|
||||
basepath=$(dirname $0)/..
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
fails=0
|
||||
|
||||
if [ "$1" == "-nightly" ]; then
|
||||
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
|
||||
derivconfigs=`ls $WALLY/config/deriv`
|
||||
for entry in $derivconfigs
|
||||
do
|
||||
configs[${#configs[@]}]=$entry
|
||||
if [[ $entry != *"syn_sram"* ]]; then # ignore syn_sram* configs that contain undefined module
|
||||
configs[${#configs[@]}]=$entry
|
||||
fi
|
||||
done
|
||||
else
|
||||
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i fdqh_rv64gc)
|
||||
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i div_2_1i_rv64gc ) # add fdqh_rv64gc when working
|
||||
fi
|
||||
|
||||
for config in ${configs[@]}; do
|
||||
echo "$config linting..."
|
||||
# echo "$config linting..."
|
||||
if !($verilator --no-timing --lint-only --top-module wallywrapper "-I$basepath/config/shared" "-I$basepath/config/$config" "-I$basepath/config/deriv/$config" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then
|
||||
echo "Exiting after $config lint due to errors or warnings"
|
||||
exit 1
|
||||
if [ "$1" == "-nightly" ]; then
|
||||
echo -e "${RED}$config failed lint${NC}"
|
||||
fails=$((fails+1))
|
||||
else
|
||||
echo -e "${RED}$config fails with lint errors or warnings"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}$config passed lint${NC}"
|
||||
fi
|
||||
done
|
||||
echo "All lints run with no errors or warnings"
|
||||
if [ $fails -gt 0 ]; then
|
||||
echo -e "${RED}Linting failed for $fails of ${#configs[@]} configurations"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}All ${#configs[@]} lints run with no errors or warnings"
|
||||
|
||||
# --lint-only just runs lint rather than trying to compile and simulate
|
||||
# -I points to the include directory where files such as `include config.vh are found
|
||||
|
@ -11,6 +11,9 @@
|
||||
#
|
||||
##################################
|
||||
import sys,os,shutil
|
||||
import multiprocessing
|
||||
|
||||
|
||||
|
||||
class bcolors:
|
||||
HEADER = '\033[95m'
|
||||
@ -51,7 +54,7 @@ else:
|
||||
name="lints",
|
||||
variant="all",
|
||||
cmd="./lint-wally " + nightMode + " | tee {}",
|
||||
grepstr="All lints run with no errors or warnings"
|
||||
grepstr="lints run with no errors or warnings"
|
||||
)
|
||||
]
|
||||
|
||||
@ -69,7 +72,7 @@ def getBuildrootTC(boot):
|
||||
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0 -coverage\n!"
|
||||
else:
|
||||
print( "buildroot no coverage")
|
||||
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0\n!"
|
||||
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot configOptions -GINSTR_LIMIT=" +str(INSTR_LIMIT) + " \n!"
|
||||
BRgrepstr=str(INSTR_LIMIT)+" instructions"
|
||||
return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
|
||||
|
||||
@ -85,7 +88,7 @@ for test in tests64i:
|
||||
configs.append(tc)
|
||||
|
||||
tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused
|
||||
tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zfh", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zfad",
|
||||
tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32f_divsqrt", "arch32d_divsqrt", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbs", "arch32zfh", "arch32zfh_fma", "arch32zfh_divsqrt", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zbc", "arch32zfad",
|
||||
#tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"]
|
||||
for test in tests32gc:
|
||||
tc = TestCase(
|
||||
@ -124,16 +127,7 @@ for test in tests32e:
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
ahbTests = [("0", "0"), ("0", "1"), ("1", "0"), ("1", "1"), ("2", "0"), ("2", "1")]
|
||||
for test in ahbTests:
|
||||
tc = TestCase(
|
||||
name="ram_latency_" + test[0] + "_burst_en_" + test[1],
|
||||
variant="ahb",
|
||||
cmd="vsim > {} -c <<!\ndo wally-batch.do rv64gc ahb "+test[0]+" "+test[1]+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfaf", "arch64zfad",
|
||||
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad",
|
||||
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working
|
||||
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
||||
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
|
||||
@ -141,13 +135,14 @@ if (coverage): # delete all but 64gc tests when running coverage
|
||||
configs = []
|
||||
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
|
||||
"arch64zifencei", "arch64zicond", "arch64a", "wally64a", "wally64periph", "wally64priv",
|
||||
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zcb", "arch64zicboz"
|
||||
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zcb", "arch64zicboz"
|
||||
if (fp):
|
||||
tests64gc.append("arch64f")
|
||||
tests64gc.append("arch64d")
|
||||
tests64gc.append("arch64zfh")
|
||||
tests64gc.append("arch64f_fma")
|
||||
tests64gc.append("arch64d_fma") # *** add arch64zfh_fma when available(see riscv-arch-test pr 367)
|
||||
tests64gc.append("arch64d_fma")
|
||||
tests64gc.append("arch64zfh_fma")
|
||||
tests64gc.append("arch64f_divsqrt")
|
||||
tests64gc.append("arch64d_divsqrt")
|
||||
tests64gc.append("arch64zfh_divsqrt")
|
||||
@ -176,7 +171,6 @@ if (nightly):
|
||||
["way_8_4096_512_rv32gc", ["arch32i"]],
|
||||
["way_4_2048_512_rv32gc", ["arch32i"]],
|
||||
["way_4_4096_256_rv32gc", ["arch32i"]],
|
||||
["way_4_4096_1024_rv32gc", ["arch32i"]],
|
||||
["way_1_4096_512_rv64gc", ["arch64i"]],
|
||||
["way_2_4096_512_rv64gc", ["arch64i"]],
|
||||
["way_8_4096_512_rv64gc", ["arch64i"]],
|
||||
@ -184,12 +178,22 @@ if (nightly):
|
||||
["way_4_4096_256_rv64gc", ["arch64i"]],
|
||||
["way_4_4096_1024_rv64gc", ["arch64i"]],
|
||||
|
||||
["ram_0_0_rv64gc", ["ahb"]],
|
||||
["ram_1_0_rv64gc", ["ahb"]],
|
||||
["ram_1_1_rv64gc", ["ahb"]],
|
||||
["ram_2_0_rv64gc", ["ahb"]],
|
||||
["ram_2_1_rv64gc", ["ahb"]],
|
||||
["ram_0_0_rv64gc", ["ahb64"]],
|
||||
["ram_1_0_rv64gc", ["ahb64"]],
|
||||
["ram_1_1_rv64gc", ["ahb64"]],
|
||||
["ram_2_0_rv64gc", ["ahb64"]],
|
||||
["ram_2_1_rv64gc", ["ahb64"]],
|
||||
|
||||
["noicache_rv32gc", ["ahb32"]],
|
||||
# cacheless designs will not work until DTIM supports FLEN > XLEN
|
||||
# ["nodcache_rv32gc", ["ahb32"]],
|
||||
# ["nocache_rv32gc", ["ahb32"]],
|
||||
["noicache_rv64gc", ["ahb64"]],
|
||||
["nodcache_rv64gc", ["ahb64"]],
|
||||
["nocache_rv64gc", ["ahb64"]],
|
||||
|
||||
### add misaligned tests
|
||||
|
||||
["div_2_1_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
||||
["div_2_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
||||
["div_2_2_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
||||
@ -215,15 +219,83 @@ if (nightly):
|
||||
["div_4_4_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
|
||||
["div_4_4i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
|
||||
|
||||
### branch predictor simulation
|
||||
|
||||
["bpred_TWOBIT_6_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_8_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_10_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_12_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_14_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_16_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_6_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_8_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_10_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_12_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_14_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_TWOBIT_16_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
|
||||
["bpred_GSHARE_6_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_6_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_8_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_8_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_12_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_12_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_14_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_14_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_16_16_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_16_16_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
|
||||
# btb
|
||||
["bpred_GSHARE_10_16_6_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_6_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_8_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_8_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_12_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_16_12_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
|
||||
# ras
|
||||
["bpred_GSHARE_10_2_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_2_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_3_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_3_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_4_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_4_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_6_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_6_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_10_10_0_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
["bpred_GSHARE_10_10_10_1_rv32gc", ["embench"], "configOptions", "-GPrintHPMCounters=1"],
|
||||
|
||||
|
||||
# enable floating-point tests when lint is fixed
|
||||
# ["f_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma"]],
|
||||
# ["fh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32zfh", "arch32zfh_divsqrt"]],
|
||||
# ["fdh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]],
|
||||
# ["fdq_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]],
|
||||
# ["fdqh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]],
|
||||
# ["f_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma"]],
|
||||
# ["fh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64zfh", "arch64zfh_divsqrt"]], # hanging 1/31/24 dh; try again when lint is fixed
|
||||
# ["fdh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]],
|
||||
# ["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]],
|
||||
# ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]],
|
||||
|
||||
|
||||
]
|
||||
for test in derivconfigtests:
|
||||
config = test[0];
|
||||
tests = test[1];
|
||||
if(len(test) >= 4 and test[2] == "configOptions"):
|
||||
configOptions = test[3]
|
||||
cmdPrefix = "vsim > {} -c <<!\ndo wally-batch.do "+config
|
||||
else:
|
||||
configOptions = ""
|
||||
cmdPrefix = "vsim > {} -c <<!\ndo wally-batch.do "+config
|
||||
for t in tests:
|
||||
tc = TestCase(
|
||||
name=t,
|
||||
variant=config,
|
||||
cmd="vsim > {} -c <<!\ndo wally-batch.do "+config+" "+t+"\n!",
|
||||
cmd=cmdPrefix+" "+t+" configOptions "+configOptions+"\n!",
|
||||
grepstr="All tests ran without failures")
|
||||
configs.append(tc)
|
||||
|
||||
@ -293,13 +365,16 @@ def main():
|
||||
# Also it is slow to run.
|
||||
# configs.append(getBuildrootTC(boot=False))
|
||||
os.system('rm -f cov/*.ucdb')
|
||||
elif '-nightly' in sys.argv:
|
||||
TIMEOUT_DUR = 60*1440 # 1 day
|
||||
configs.append(getBuildrootTC(boot=False))
|
||||
else:
|
||||
TIMEOUT_DUR = 10*60 # seconds
|
||||
configs.append(getBuildrootTC(boot=False))
|
||||
|
||||
# Scale the number of concurrent processes to the number of test cases, but
|
||||
# max out at a limited number of concurrent processes to not overwhelm the system
|
||||
with Pool(processes=min(len(configs),40)) as pool:
|
||||
with Pool(processes=min(len(configs),multiprocessing.cpu_count())) as pool:
|
||||
num_fail = 0
|
||||
results = {}
|
||||
for config in configs:
|
||||
|
@ -3,8 +3,8 @@
|
||||
#export RISCV=/scratch/moore/RISCV
|
||||
|
||||
export IMPERAS_TOOLS=$(pwd)/imperas.ic
|
||||
export OTHERFLAGS="+TRACE2LOG_ENABLE=1"
|
||||
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=100"
|
||||
#export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
|
||||
export OTHERFLAGS=""
|
||||
#export OTHERFLAGS=""
|
||||
|
||||
vsim -c -do "do wally-linux-imperas.do buildroot buildroot-no-trace $::env(RISCV) 0 0 0"
|
||||
vsim -do "do wally-linux-imperas.do buildroot buildroot $::env(RISCV) 0 0 0"
|
||||
|
@ -21,33 +21,40 @@
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if {$2 eq "ahb"} {
|
||||
if [file exists wkdir/work_${1}_${2}_${3}_${4}] {
|
||||
vdel -lib wkdir/work_${1}_${2}_${3}_${4} -all
|
||||
}
|
||||
vlib wkdir/work_${1}_${2}_${3}_${4}
|
||||
|
||||
|
||||
} elseif {$2 eq "configOptions"} {
|
||||
if [file exists wkdir/work_${1}_${3}_${4}] {
|
||||
vdel -lib wkdir/work_${1}_${3}_${4} -all
|
||||
}
|
||||
vlib wkdir/work_${1}_${3}_${4}
|
||||
|
||||
} else {
|
||||
if [file exists wkdir/work_${1}_${2}] {
|
||||
vdel -lib wkdir/work_${1}_${2} -all
|
||||
}
|
||||
vlib wkdir/work_${1}_${2}
|
||||
if [file exists wkdir/work_${1}_${2}] {
|
||||
vdel -lib wkdir/work_${1}_${2} -all
|
||||
}
|
||||
vlib wkdir/work_${1}_${2}
|
||||
# Create directory for coverage data
|
||||
mkdir -p cov
|
||||
|
||||
# Check if measuring coverage
|
||||
set coverage 0
|
||||
set coverage 0
|
||||
set CoverageVoptArg ""
|
||||
set CoverageVsimArg ""
|
||||
|
||||
# Need to be able to pass arguments to vopt. Unforunately argv does not work because
|
||||
# it takes on different values if vsim and the do file are called from the command line or
|
||||
# if the do file isd called from questa sim directly. This chunk of code uses the $4 through $n
|
||||
# variables and compacts into a single list for passing to vopt.
|
||||
set configOptions ""
|
||||
set from 4
|
||||
set step 1
|
||||
set lst {}
|
||||
for {set i 0} true {incr i} {
|
||||
set x [expr {$i*$step + $from}]
|
||||
if {$x > $argc} break
|
||||
set arg [expr "$$x"]
|
||||
lappend lst $arg
|
||||
}
|
||||
|
||||
if {$argc >= 3} {
|
||||
if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
|
||||
set coverage 1
|
||||
set CoverageVoptArg "+cover=sbecf"
|
||||
set CoverageVsimArg "-coverage"
|
||||
} elseif {$3 eq "configOptions"} {
|
||||
set configOptions $lst
|
||||
puts $configOptions
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,91 +65,20 @@ if {$argc >= 3} {
|
||||
|
||||
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
|
||||
# do wally-pipelined-batch.do ../config/rv32imc rv32imc
|
||||
if {$2 eq "buildroot"} {
|
||||
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
|
||||
# start and run simulation
|
||||
if { $coverage } {
|
||||
echo "wally-batch buildroot coverage"
|
||||
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt +cover=sbecf
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover
|
||||
} else {
|
||||
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -o testbenchopt
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7
|
||||
}
|
||||
|
||||
run -all
|
||||
run -all
|
||||
exec ./slack-notifier/slack-notifier.py
|
||||
} elseif {$2 eq "buildroot-no-trace"} {
|
||||
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
|
||||
# start and run simulation
|
||||
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G NO_SPOOFING=1 -o testbenchopt
|
||||
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
|
||||
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
|
||||
|
||||
#-- Run the Simulation
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo "Don't forget to change DEBUG_LEVEL = 0."
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
run -all
|
||||
run -all
|
||||
exec ./slack-notifier/slack-notifier.py
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg}
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg}
|
||||
|
||||
} elseif {$2 eq "ahb"} {
|
||||
vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt wkdir/work_${1}_${2}_${3}_${4}.testbench -work wkdir/work_${1}_${2}_${3}_${4} -G TEST=$2 -o testbenchopt
|
||||
vsim -lib wkdir/work_${1}_${2}_${3}_${4} testbenchopt -fatal 7
|
||||
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time
|
||||
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
|
||||
#vsim -coverage -lib work_$2 workopt_$2
|
||||
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
|
||||
} elseif {$2 eq "configOptions"} {
|
||||
# set arguments " "
|
||||
# for {set i 5} {$i <= $argc} {incr i} {
|
||||
# append arguments "\$$i "
|
||||
# }
|
||||
# puts $arguments
|
||||
# set options eval $arguments
|
||||
# **** fix this so we can pass any number of +defines.
|
||||
# only allows 3 right now
|
||||
|
||||
vlog -lint -work wkdir/work_${1}_${3}_${4} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 $5 $6 $7
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt wkdir/work_${1}_${3}_${4}.testbench -work wkdir/work_${1}_${3}_${4} -G TEST=$4 -o testbenchopt
|
||||
vsim -lib wkdir/work_${1}_${3}_${4} testbenchopt -fatal 7 -suppress 3829
|
||||
# Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time
|
||||
#vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf
|
||||
#vsim -coverage -lib work_$2 workopt_$2
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
|
||||
} else {
|
||||
vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/deriv/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
if {$coverage} {
|
||||
# vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf
|
||||
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbecf
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage
|
||||
} else {
|
||||
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt
|
||||
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
|
||||
}
|
||||
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
}
|
||||
# power add generates the logging necessary for said generation.
|
||||
# power add -r /dut/core/*
|
||||
run -all
|
||||
# power off -r /dut/core/*
|
||||
|
||||
|
||||
if {$coverage} {
|
||||
echo "Saving coverage to ${1}_${2}.ucdb"
|
||||
|
@ -32,25 +32,10 @@ vlib work
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
|
||||
# start and run simulation
|
||||
vopt work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt
|
||||
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
|
||||
|
||||
#-- Run the Simulation
|
||||
#run -all
|
||||
run 7000 ms
|
||||
add log -recursive /*
|
||||
do linux-wave.do
|
||||
run -all
|
||||
|
||||
exec ./slack-notifier/slack-notifier.py
|
||||
|
||||
} elseif {$2 eq "buildroot-no-trace"} {
|
||||
if {$2 eq "buildroot"} {
|
||||
vlog -lint -work work_${1}_${2} \
|
||||
+define+USE_IMPERAS_DV \
|
||||
+incdir+../config/$1 \
|
||||
+incdir+../config/deriv/$1 \
|
||||
+incdir+../config/shared \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
|
||||
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
|
||||
@ -64,7 +49,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \
|
||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
|
||||
../src/cvw.sv \
|
||||
../testbench/testbench-linux-imperas.sv \
|
||||
../testbench/testbench.sv \
|
||||
../testbench/common/*.sv ../src/*/*.sv \
|
||||
../src/*/*/*.sv -suppress 2583
|
||||
|
||||
@ -76,7 +61,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
# visualizer -fprofile+perf+dir=fprofile
|
||||
#
|
||||
eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
|
||||
-G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt
|
||||
-G TEST=$2 -o testbenchopt
|
||||
eval vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 \
|
||||
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
|
||||
$env(OTHERFLAGS)
|
||||
@ -96,60 +81,4 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
|
||||
exec ./slack-notifier/slack-notifier.py
|
||||
|
||||
} elseif {$2 eq "fpga"} {
|
||||
echo "hello"
|
||||
vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286
|
||||
vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt
|
||||
vsim workopt +nowarn3829 -fatal 7
|
||||
|
||||
do fpga-wave.do
|
||||
add log -r /*
|
||||
run 20 ms
|
||||
|
||||
} else {
|
||||
if {$2 eq "ahb"} {
|
||||
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
|
||||
} else {
|
||||
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
|
||||
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
|
||||
}
|
||||
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
|
||||
|
||||
vsim workopt +nowarn3829 -fatal 7
|
||||
|
||||
view wave
|
||||
#-- display input and output signals as hexidecimal values
|
||||
#do ./wave-dos/peripheral-waves.do
|
||||
add log -recursive /*
|
||||
do wave.do
|
||||
#do wave-bus.do
|
||||
|
||||
# power add generates the logging necessary for saif generation.
|
||||
#power add -r /dut/core/*
|
||||
#-- Run the Simulation
|
||||
|
||||
run -all
|
||||
#power off -r /dut/core/*
|
||||
#power report -all -bsaif power.saif
|
||||
noview ../testbench/testbench.sv
|
||||
view wave
|
||||
}
|
||||
|
||||
|
||||
|
||||
#elseif {$2 eq "buildroot-no-trace""} {
|
||||
# vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
|
||||
# start and run simulation
|
||||
# vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt
|
||||
# vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
|
||||
|
||||
#-- Run the Simulation
|
||||
# run 100 ns
|
||||
# force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
|
||||
# force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
|
||||
# add log -recursive /*
|
||||
# do linux-wave.do
|
||||
# run -all
|
||||
|
||||
# exec ./slack-notifier/slack-notifier.py
|
||||
#}
|
||||
|
@ -77,12 +77,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
||||
run 20 ms
|
||||
|
||||
} else {
|
||||
if {$2 eq "ahb"} {
|
||||
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
|
||||
} else {
|
||||
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
|
||||
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
|
||||
}
|
||||
vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
|
||||
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
|
||||
|
||||
vsim workopt +nowarn3829 -fatal 7
|
||||
|
2
src/cache/cacheLRU.sv
vendored
2
src/cache/cacheLRU.sv
vendored
@ -143,7 +143,7 @@ module cacheLRU
|
||||
// This is a two port memory.
|
||||
// Every cycle must read from CacheSetData and each load/store must write the new LRU.
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset | (InvalidateCache & ~FlushStage)) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] = '0;
|
||||
if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] = '0; // exclusion-tag: initialize
|
||||
if(CacheEn) begin
|
||||
if(ClearValid & ~FlushStage)
|
||||
LRUMemory[PAdr] <= '0;
|
||||
|
10
src/cache/cachefsm.sv
vendored
10
src/cache/cachefsm.sv
vendored
@ -117,12 +117,11 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
NextState = STATE_READY;
|
||||
case (CurrState) // exclusion-tag: icache state-case
|
||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
||||
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
|
||||
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; // exclusion-tag: icache FLUSHStatement
|
||||
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
|
||||
else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else if((AnyMiss | CMOWriteback) & ~READ_ONLY_CACHE) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||
else NextState = STATE_READY;
|
||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||
else if(CacheBusAck) NextState = STATE_READY;
|
||||
else NextState = STATE_FETCH;
|
||||
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
|
||||
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
|
||||
@ -158,7 +157,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
|
||||
assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
|
||||
(CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
|
||||
// coverage off -item e 1 -fecexprrow 8
|
||||
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
||||
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
||||
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
|
||||
@ -190,8 +188,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
|
||||
|
||||
logic LoadMiss;
|
||||
|
||||
//assign StoreMiss = (CacheRW[0]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
||||
assign LoadMiss = (CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
||||
|
||||
assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
|
||||
@ -204,7 +200,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
||||
(CurrState == STATE_WRITEBACK) |
|
||||
(CurrState == STATE_WRITE_LINE) |
|
||||
resetDelay;
|
||||
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
|
||||
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrTag // changes if store delay hazard removed
|
||||
(CurrState == STATE_FETCH) |
|
||||
(CurrState == STATE_WRITEBACK) |
|
||||
(CurrState == STATE_WRITE_LINE) |
|
||||
|
2
src/cache/cacheway.sv
vendored
2
src/cache/cacheway.sv
vendored
@ -53,7 +53,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
output logic [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid
|
||||
output logic HitWay, // This way hits
|
||||
output logic ValidWay, // This way is valid
|
||||
output logic HitDirtyWay, // The hit way is dirty
|
||||
output logic HitDirtyWay, // The hit way is dirty
|
||||
output logic DirtyWay , // The selected way is dirty
|
||||
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
|
||||
|
||||
|
@ -79,7 +79,7 @@ module buscachefsm #(
|
||||
logic CacheAccess;
|
||||
logic BusWrite;
|
||||
|
||||
assign BusWrite = CacheBusRW[0] | BusCMOZero;
|
||||
assign BusWrite = (CacheBusRW[0] | BusCMOZero) & ~READ_ONLY_CACHE;
|
||||
|
||||
always_ff @(posedge HCLK)
|
||||
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
||||
@ -87,28 +87,28 @@ module buscachefsm #(
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0
|
||||
else if (HREADY & BusWrite & ~READ_ONLY_CACHE) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADYread
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE;
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
||||
DATA_PHASE: if(HREADY & BusAtomic & ~READ_ONLY_CACHE) NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm HREADY2
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3; // exclusion-tag: buscachefsm HREADY3
|
||||
else NextState = DATA_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE;
|
||||
else NextState = ATOMIC_READ_DATA_PHASE;
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3;
|
||||
else NextState = ATOMIC_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicReadData
|
||||
else NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm AtomicElse
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3; // exclusion-tag: buscachefsm AtomicPhase
|
||||
else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait
|
||||
MEM3: if(Stall) NextState = MEM3;
|
||||
else NextState = ADR_PHASE;
|
||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm FetchWriteback
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm FetchWait
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||
else NextState = CACHE_FETCH;
|
||||
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3;
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||
else NextState = CACHE_WRITEBACK;
|
||||
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback
|
||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADY4
|
||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; // exclusion-tag: buscachefsm HREADY5
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; // exclusion-tag: buscachefsm HREADY6
|
||||
else NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback2
|
||||
default: NextState = ADR_PHASE;
|
||||
endcase
|
||||
end
|
||||
@ -139,12 +139,12 @@ module buscachefsm #(
|
||||
|
||||
// AHB bus interface
|
||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE) |
|
||||
(CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request
|
||||
(CacheAccess & |BeatCount) ? (BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
|
||||
|
||||
assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CurrState == CACHE_WRITEBACK & |BeatCount);
|
||||
assign HWRITE = (((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CurrState == CACHE_WRITEBACK & |BeatCount)) & ~READ_ONLY_CACHE;
|
||||
assign HBURST = BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
||||
|
||||
always_comb begin
|
||||
|
@ -237,11 +237,10 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.q q->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu
|
||||
endcase
|
||||
// coverage on
|
||||
// coverage off
|
||||
// Not covered in testing because rv64gc is not RV64Q or RV32D
|
||||
7'b1011001: if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct3D == 3'b000)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.d.x (Zfa) *** untested, controls could be wrong
|
||||
// Not covered in testing because rv64gc does not support quad precision
|
||||
// coverage off
|
||||
7'b1011011: if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct3D == 3'b000)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa)
|
||||
// coverage on
|
||||
|
@ -278,9 +278,14 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||
end else assign FliResE = '0;
|
||||
|
||||
// fmv.*.x: NaN Box SrcA to extend integer to requested FP size
|
||||
if(P.FPSIZES == 1) assign PreIntSrcE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
|
||||
if(P.FPSIZES == 1)
|
||||
if (P.FLEN >= P.XLEN) assign PreIntSrcE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
|
||||
else assign PreIntSrcE = ForwardedSrcAE[P.FLEN-1:0];
|
||||
else if(P.FPSIZES == 2)
|
||||
mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, PreIntSrcE);
|
||||
if (P.FLEN >= P.XLEN)
|
||||
mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, PreIntSrcE);
|
||||
else
|
||||
mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, ForwardedSrcAE[P.FLEN-1:0], FmtE, PreIntSrcE);
|
||||
else if(P.FPSIZES == 3 | P.FPSIZES == 4) begin
|
||||
localparam XD_LEN = P.D_LEN < P.XLEN ? P.D_LEN : P.XLEN; // shorter of D_LEN and XLEN
|
||||
mux3 #(P.FLEN) SrcAMux ({{P.FLEN-P.S_LEN{1'b1}}, ForwardedSrcAE[P.S_LEN-1:0]},
|
||||
|
@ -45,7 +45,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
output logic [P.NE+1:0] Ue // corrected exponent for divider
|
||||
);
|
||||
|
||||
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||
logic ResSubnorm; // is the result Subnormal
|
||||
@ -69,7 +69,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
|
||||
always_comb
|
||||
if(FmaOp) Mf = {CorrSumShifted, {P.CORRSHIFTSZ-(3*P.NF+4){1'b0}}};
|
||||
if(FmaOp) Mf = {CorrSumShifted};
|
||||
else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
|
||||
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
||||
|
||||
|
@ -140,15 +140,12 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
if (BadNaNBox) begin
|
||||
case (Fmt)
|
||||
P.FMT: PostBox = In;
|
||||
P.FMT1: PostBox = {{(P.FLEN-P.LEN1){1'b1}}, 1'b1, {(P.NE1+1){1'b1}}, {(P.LEN1-P.NE1-2){1'b0}}};
|
||||
P.FMT2: PostBox = {{(P.FLEN-P.LEN2){1'b1}}, 1'b1, {(P.NE2+1){1'b1}}, {(P.LEN2-P.NE2-2){1'b0}}};
|
||||
default: PostBox = 'x;
|
||||
endcase
|
||||
end else
|
||||
PostBox = In;
|
||||
if (BadNaNBox & Fmt == P.FMT1)
|
||||
PostBox = {{(P.FLEN-P.LEN1){1'b1}}, 1'b1, {(P.NE1+1){1'b1}}, {(P.LEN1-P.NE1-2){1'b0}}};
|
||||
else if (BadNaNBox) // Fmt == P.FMT2
|
||||
PostBox = {{(P.FLEN-P.LEN2){1'b1}}, 1'b1, {(P.NE2+1){1'b1}}, {(P.LEN2-P.NE2-2){1'b0}}};
|
||||
else
|
||||
PostBox = In;
|
||||
|
||||
// extract the sign bit
|
||||
always_comb
|
||||
|
@ -42,6 +42,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||
output logic BranchD, // Branch instruction
|
||||
output logic StructuralStallD, // Structural stalls detected by controller
|
||||
output logic LoadStallD, // Structural stalls for load, sent to performance counters
|
||||
output logic StoreStallD, // load after store hazard
|
||||
output logic [4:0] Rs1D, Rs2D, // Register sources to read in Decode or Execute stage
|
||||
// Execute stage control signals
|
||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
||||
@ -159,7 +160,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||
logic CMOStallD; // Structural hazards from cache management ops
|
||||
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
|
||||
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
|
||||
logic StoreStallD; // load after store hazard
|
||||
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
|
||||
|
||||
// Extract fields
|
||||
|
@ -76,6 +76,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
|
||||
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
|
||||
output logic StructuralStallD, // IEU detects structural hazard in Decode stage
|
||||
output logic LoadStallD, // Structural stalls for load, sent to performance counters
|
||||
output logic StoreStallD, // load after store hazard
|
||||
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
||||
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
|
||||
);
|
||||
@ -107,7 +108,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
|
||||
controller #(P) c(
|
||||
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
|
||||
.IllegalIEUFPUInstrD, .IllegalBaseInstrD,
|
||||
.StructuralStallD, .LoadStallD, .Rs1D, .Rs2D,
|
||||
.StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D,
|
||||
.StallE, .FlushE, .FlagsE, .FWriteIntE,
|
||||
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
|
||||
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
|
||||
|
@ -88,15 +88,17 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
logic [P.XLEN-1:0] BPBTAD;
|
||||
|
||||
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
logic ReturnD, CallD;
|
||||
logic ReturnE, CallE;
|
||||
logic BranchM, JumpM, ReturnM, CallM;
|
||||
logic BranchW, JumpW, ReturnW, CallW;
|
||||
logic BPReturnWrongD;
|
||||
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||
logic ReturnD, CallD;
|
||||
logic ReturnE, CallE;
|
||||
logic BranchM, JumpM, ReturnM, CallM;
|
||||
logic BranchW, JumpW, ReturnW, CallW;
|
||||
logic BPReturnWrongD;
|
||||
logic [P.XLEN-1:0] BPBTAE;
|
||||
logic BPBTAWrongM;
|
||||
logic PCSrcM;
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
if (P.BPRED_TYPE == `BP_TWOBIT) begin:Predictor
|
||||
@ -144,6 +146,8 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
.BranchD, .BranchE, .BranchM, .PCSrcE);
|
||||
end
|
||||
|
||||
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM);
|
||||
|
||||
// Part 2 Branch target address prediction
|
||||
// BTB contains target address for all CFI
|
||||
|
||||
@ -152,6 +156,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||
.BPBTAF, .BPBTAD, .BPBTAE,
|
||||
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
||||
.BPBTAWrongM,
|
||||
.IClassWrongM, .IClassWrongE,
|
||||
.IEUAdrE, .IEUAdrM,
|
||||
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
||||
@ -196,7 +201,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
if(P.ZIHPM_SUPPORTED) begin
|
||||
logic [P.XLEN-1:0] RASPCD, RASPCE;
|
||||
logic BTAWrongE, RASPredPCWrongE;
|
||||
logic RASPredPCWrongE;
|
||||
// performance counters
|
||||
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
|
||||
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
|
||||
@ -208,14 +213,15 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
||||
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
||||
// both without the above inaccuracies.
|
||||
// **** use BPBTAWrongM from BTB.
|
||||
assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
|
||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
|
||||
|
||||
flopenrc #(P.XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
||||
flopenrc #(P.XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
||||
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
||||
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
|
||||
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
|
||||
flopenrc #(2) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
||||
{BPDirPredWrongE, RASPredPCWrongE},
|
||||
{BPDirPredWrongM, RASPredPCWrongM});
|
||||
|
||||
assign BTAWrongM = BPBTAWrongM & PCSrcM;
|
||||
|
||||
end else begin
|
||||
assign {BTAWrongM, RASPredPCWrongM} = '0;
|
||||
|
@ -39,6 +39,7 @@ module btb import cvw::*; #(parameter cvw_t P,
|
||||
output logic [P.XLEN-1:0] BPBTAD,
|
||||
output logic [P.XLEN-1:0] BPBTAE,
|
||||
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
||||
output logic BPBTAWrongM,
|
||||
// update
|
||||
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
||||
input logic IClassWrongE,
|
||||
@ -57,7 +58,7 @@ module btb import cvw::*; #(parameter cvw_t P,
|
||||
logic [P.XLEN-1:0] IEUAdrW;
|
||||
logic [P.XLEN-1:0] PCW;
|
||||
logic BTBWrongE, BPBTAWrongE;
|
||||
logic BTBWrongM, BPBTAWrongM;
|
||||
logic BTBWrongM;
|
||||
|
||||
|
||||
// hashing function for indexing the PC
|
||||
|
@ -374,12 +374,12 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
ahbinterface #(P.XLEN, 1'b1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .BusAtomic(AtomicM[1]), .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM[P.XLEN-1:0]),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .BusAtomic(AtomicM[1]), .ByteMask(ByteMaskM[P.XLEN/8-1:0]), .WriteData(LSUWriteDataM[P.XLEN-1:0]),
|
||||
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||
|
||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
||||
if(P.DTIM_SUPPORTED) mux2 #(P.XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM[P.XLEN-1:0], SelDTIM, ReadDataWordMuxM[P.XLEN-1:0]);
|
||||
else assign ReadDataWordMuxM = FetchBuffer[P.XLEN-1:0];
|
||||
else assign ReadDataWordMuxM[P.XLEN-1:0] = FetchBuffer[P.XLEN-1:0]; // *** bus only does not support double wide floats.
|
||||
assign LSUHBURST = 3'b0;
|
||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||
end
|
||||
@ -406,7 +406,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
end
|
||||
|
||||
if (P.F_SUPPORTED)
|
||||
mux2 #(P.LLEN) datamux({{{P.LLEN-P.XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM);
|
||||
if (P.FLEN >= P.XLEN)
|
||||
mux2 #(P.LLEN) datamux({{{P.LLEN-P.XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM);
|
||||
else
|
||||
mux2 #(P.LLEN) datamux(IMAWriteDataM, {{{P.XLEN-P.FLEN}{1'b0}}, FWriteDataM}, FpLoadStoreM, IMAFWriteDataM);
|
||||
|
||||
else assign IMAFWriteDataM = IMAWriteDataM;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -49,5 +49,5 @@ module adrdec #(parameter PA_BITS) (
|
||||
assign SizeValid = SizeMask[Size];
|
||||
|
||||
// Select this peripheral if the address matches, the peripheral is supported, and the type and size of access is ok
|
||||
assign Sel = Match & Supported & AccessValid & SizeValid;
|
||||
assign Sel = Match & Supported & AccessValid & SizeValid; // exclusion-tag: adrdecSel
|
||||
endmodule
|
||||
|
@ -54,7 +54,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [3:0] CauseM, // Trap cause
|
||||
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
||||
// inputs for performance counters
|
||||
input logic LoadStallD,
|
||||
input logic LoadStallD, StoreStallD,
|
||||
input logic ICacheStallF,
|
||||
input logic DCacheStallM,
|
||||
input logic BPDirPredWrongM,
|
||||
@ -275,7 +275,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
if (P.ZICNTR_SUPPORTED) begin:counters
|
||||
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
|
||||
.InstrValidNotFlushedM, .LoadStallD, .CSRWriteM, .CSRMWriteM,
|
||||
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM,
|
||||
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
|
||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
|
||||
.InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
||||
|
@ -33,7 +33,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic clk, reset,
|
||||
input logic StallE, StallM,
|
||||
input logic FlushM,
|
||||
input logic InstrValidNotFlushedM, LoadStallD,
|
||||
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
|
||||
input logic CSRMWriteM, CSRWriteM,
|
||||
input logic BPDirPredWrongM,
|
||||
input logic BTAWrongM,
|
||||
@ -76,6 +76,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
logic [P.XLEN-1:0] HPMCOUNTER_REGW[P.COUNTERS-1:0];
|
||||
logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0];
|
||||
logic LoadStallE, LoadStallM;
|
||||
logic StoreStallE, StoreStallM;
|
||||
logic [P.COUNTERS-1:0] WriteHPMCOUNTERM;
|
||||
logic [P.COUNTERS-1:0] CounterEvent;
|
||||
logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0];
|
||||
@ -85,6 +86,9 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
// Interface signals
|
||||
flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); // don't flush the load stall during a load stall.
|
||||
flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));
|
||||
|
||||
flopenrc #(1) StoreStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d(StoreStallD), .q(StoreStallE)); // don't flush the load stall during a load stall.
|
||||
flopenrc #(1) StoreStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(StoreStallE), .q(StoreStallM));
|
||||
|
||||
// Determine when to increment each counter
|
||||
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
||||
@ -100,7 +104,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
|
||||
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
||||
assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
|
||||
assign CounterEvent[12] = 0; // depricated Store Stall
|
||||
assign CounterEvent[12] = StoreStallM; // depricated Store Stall
|
||||
assign CounterEvent[13] = DCacheAccess; // data cache access
|
||||
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
|
||||
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles
|
||||
|
@ -46,6 +46,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||
// processor events for performance counter logging
|
||||
input logic FRegWriteM, // instruction will write floating-point registers
|
||||
input logic LoadStallD, // load instruction is stalling
|
||||
input logic StoreStallD, // store instruction is stalling
|
||||
input logic ICacheStallF, // I cache stalled
|
||||
input logic DCacheStallM, // D cache stalled
|
||||
input logic BPDirPredWrongM, // branch predictor guessed wrong direction
|
||||
@ -135,7 +136,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
||||
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM,
|
||||
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
|
||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
|
||||
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
|
||||
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
|
||||
.sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
||||
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
|
||||
|
@ -78,6 +78,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
logic DivBusyE;
|
||||
logic StructuralStallD;
|
||||
logic LoadStallD;
|
||||
logic StoreStallD;
|
||||
logic SquashSCW;
|
||||
logic MDUActiveE; // Mul/Div instruction being executed
|
||||
logic ENVCFG_ADUE; // HPTW A/D Update enable
|
||||
@ -212,7 +213,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
|
||||
// hazards
|
||||
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.StructuralStallD, .LoadStallD, .PCSrcE,
|
||||
.StructuralStallD, .LoadStallD, .StoreStallD, .PCSrcE,
|
||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM);
|
||||
|
||||
lsu #(P) lsu(
|
||||
@ -286,7 +287,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM,
|
||||
.RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
|
||||
.InstrValidM, .CommittedM, .CommittedF,
|
||||
.FRegWriteM, .LoadStallD,
|
||||
.FRegWriteM, .LoadStallD, .StoreStallD,
|
||||
.BPDirPredWrongM, .BTAWrongM, .BPWrongM,
|
||||
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
|
||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
||||
|
@ -21,53 +21,51 @@
|
||||
|
||||
module riscvassertions import cvw::*; #(parameter cvw_t P);
|
||||
initial begin
|
||||
assert (P.PMP_ENTRIES == 0 || P.PMP_ENTRIES==16 || P.PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||
assert (P.S_SUPPORTED || P.VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support");
|
||||
assert (P.IDIV_BITSPERCYCLE == 1 || P.IDIV_BITSPERCYCLE==2 || P.IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||
assert (P.F_SUPPORTED || ~P.D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)");
|
||||
assert (P.D_SUPPORTED || ~P.Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)");
|
||||
assert (P.F_SUPPORTED || ~P.ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (P.DCACHE_SUPPORTED || ~P.F_SUPPORTED || P.FLEN <= P.XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
|
||||
assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $error("Exactly one of I and E must be supported");
|
||||
assert (P.FLEN<=P.XLEN || P.DCACHE_SUPPORTED || P.DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported");
|
||||
assert (P.DCACHE_WAYSIZEINBYTES <= 4096 || (!P.DCACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.DCACHE_LINELENINBITS >= 128 || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (P.ICACHE_WAYSIZEINBYTES <= 4096 || (!P.ICACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.ICACHE_LINELENINBITS >= 32 || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (P.ICACHE_LINELENINBITS < P.ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(P.DCACHE_LINELENINBITS) == P.DCACHE_LINELENINBITS || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(P.DCACHE_WAYSIZEINBYTES) == P.DCACHE_WAYSIZEINBYTES || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(P.ICACHE_LINELENINBITS) == P.ICACHE_LINELENINBITS || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(P.ICACHE_WAYSIZEINBYTES) == P.ICACHE_WAYSIZEINBYTES || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(P.ITLB_ENTRIES) == P.ITLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2");
|
||||
assert (2**$clog2(P.DTLB_ENTRIES) == P.DTLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2");
|
||||
assert (P.PMP_ENTRIES == 0 || P.PMP_ENTRIES==16 || P.PMP_ENTRIES==64) else $fatal(1, "Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64");
|
||||
assert (P.S_SUPPORTED || P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "Virtual memory requires S mode support");
|
||||
assert (P.IDIV_BITSPERCYCLE == 1 || P.IDIV_BITSPERCYCLE==2 || P.IDIV_BITSPERCYCLE==4) else $fatal(1, "Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
||||
assert (P.F_SUPPORTED || ~P.D_SUPPORTED) else $fatal(1, "Can't support double fp (D) without supporting float (F)");
|
||||
assert (P.D_SUPPORTED || ~P.Q_SUPPORTED) else $fatal(1, "Can't support quad fp (Q) without supporting double (D)");
|
||||
assert (P.F_SUPPORTED || ~P.ZFH_SUPPORTED) else $fatal(1, "Can't support half-precision fp (ZFH) without supporting float (F)");
|
||||
assert (P.DCACHE_SUPPORTED || ~P.F_SUPPORTED || P.FLEN <= P.XLEN) else $fatal(1, "Data cache required to support FLEN > XLEN because AHB/DTIM bus width is XLEN");
|
||||
assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $fatal(1, "Exactly one of I and E must be supported");
|
||||
assert (P.DCACHE_WAYSIZEINBYTES <= 4096 || (!P.DCACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.DCACHE_LINELENINBITS >= 128 || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||
assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $fatal(1, "DCACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (P.ICACHE_WAYSIZEINBYTES <= 4096 || (!P.ICACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||
assert (P.ICACHE_LINELENINBITS >= 32 || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||
assert (P.ICACHE_LINELENINBITS < P.ICACHE_WAYSIZEINBYTES*8) else $fatal(1, "ICACHE_LINELENINBITS must be smaller than way size");
|
||||
assert (2**$clog2(P.DCACHE_LINELENINBITS) == P.DCACHE_LINELENINBITS || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(P.DCACHE_WAYSIZEINBYTES) == P.DCACHE_WAYSIZEINBYTES || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(P.ICACHE_LINELENINBITS) == P.ICACHE_LINELENINBITS || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_LINELENINBITS must be a power of 2");
|
||||
assert (2**$clog2(P.ICACHE_WAYSIZEINBYTES) == P.ICACHE_WAYSIZEINBYTES || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_WAYSIZEINBYTES must be a power of 2");
|
||||
assert (2**$clog2(P.ITLB_ENTRIES) == P.ITLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $fatal(1, "ITLB_ENTRIES must be a power of 2");
|
||||
assert (2**$clog2(P.DTLB_ENTRIES) == P.DTLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $fatal(1, "DTLB_ENTRIES must be a power of 2");
|
||||
assert (P.UNCORE_RAM_RANGE >= 64'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 64'h07FFFFFF");
|
||||
assert (P.ZICSR_SUPPORTED == 1 || (P.PMP_ENTRIES == 0 && P.VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported.");
|
||||
assert (P.ZICSR_SUPPORTED == 1 || (P.S_SUPPORTED == 0 && P.U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported");
|
||||
assert (P.ZICSR_SUPPORTED == 1 || (P.PMP_ENTRIES == 0 && P.VIRTMEM_SUPPORTED == 0)) else $fatal(1, "PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported.");
|
||||
assert (P.ZICSR_SUPPORTED == 1 || (P.S_SUPPORTED == 0 && P.U_SUPPORTED == 0)) else $fatal(1, "S and U modes not supported if ZICSR not supported");
|
||||
assert (P.U_SUPPORTED || (P.S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported");
|
||||
assert (P.VIRTMEM_SUPPORTED == 0 || (P.DTIM_SUPPORTED == 0 && P.IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses");
|
||||
assert (P.DCACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache");
|
||||
assert (P.ICACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
|
||||
assert ((P.DCACHE_SUPPORTED == 0 && P.ICACHE_SUPPORTED == 0) || P.BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED.");
|
||||
assert (P.DCACHE_LINELENINBITS <= P.XLEN*16 || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
||||
assert (P.DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||
assert (P.DCACHE_SUPPORTED || (P.A_SUPPORTED == 0)) else $error("Atomic extension (A) requires cache on Wally.");
|
||||
assert (P.IDIV_ON_FPU == 0 || P.F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED");
|
||||
assert (P.SSTC_SUPPORTED == 0 || (P.S_SUPPORTED)) else $error("SSTC requires S_SUPPORTED");
|
||||
assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled");
|
||||
assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED");
|
||||
assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $error("ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED");
|
||||
assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOM requires DCACHE_SUPPORTED");
|
||||
assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOZ requires DCACHE_SUPPORTED");
|
||||
assert ((P.ZICBOP_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOP requires DCACHE_SUPPORTED");
|
||||
assert ((P.SVPBMT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVPBMT requires VIRTMEM_SUPPORTED and RV64");
|
||||
assert ((P.SVNAPOT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVNAPOT requires VIRTMEM_SUPPORTED and RV64");
|
||||
assert ((P.ZCB_SUPPORTED == 0) || (P.M_SUPPORTED == 1 && (P.ZBA_SUPPORTED == 1 || P.XLEN == 32) && P.ZBB_SUPPORTED == 1)) else $error("ZCB requires M and ZBB (and also ZBA for RV64)");
|
||||
assert ((P.C_SUPPORTED == 0) || (P.ZCA_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0 && P.ZCD_SUPPORTED == 0)) else $error("C and ZCA/ZCD/ZCF cannot simultaneously be supported");
|
||||
assert ((P.ZCA_SUPPORTED == 1) || (P.ZCD_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0)) else $error("ZCF or ZCD requires ZCA");
|
||||
assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $error("ZCF requires F");
|
||||
assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $error("ZCD requires D");
|
||||
assert (P.VIRTMEM_SUPPORTED == 0 || (P.DTIM_SUPPORTED == 0 && P.IROM_SUPPORTED == 0)) else $fatal(1, "Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses");
|
||||
assert (P.DCACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $fatal(1, "Virtual memory needs dcache");
|
||||
assert (P.ICACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $fatal(1, "Virtual memory needs icache");
|
||||
assert ((P.DCACHE_SUPPORTED == 0 && P.ICACHE_SUPPORTED == 0) || P.BUS_SUPPORTED) else $fatal(1, "Dcache and Icache requires DBUS_SUPPORTED.");
|
||||
assert (P.DCACHE_LINELENINBITS <= P.XLEN*16 || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 16");
|
||||
assert (P.DCACHE_LINELENINBITS % 4 == 0) else $fatal(1, "DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
||||
assert (P.DCACHE_SUPPORTED || (P.A_SUPPORTED == 0)) else $fatal(1, "Atomic extension (A) requires cache on Wally.");
|
||||
assert (P.IDIV_ON_FPU == 0 || P.F_SUPPORTED) else $fatal(1, "IDIV on FPU needs F_SUPPORTED");
|
||||
assert (P.SSTC_SUPPORTED == 0 || (P.S_SUPPORTED)) else $fatal(1, "SSTC requires S_SUPPORTED");
|
||||
assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $fatal(1, "At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled");
|
||||
assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $fatal(1, "ZICNTR_SUPPORTED requires ZICSR_SUPPORTED");
|
||||
assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $fatal(1, "ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED");
|
||||
assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICBOM requires DCACHE_SUPPORTED");
|
||||
assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICBOZ requires DCACHE_SUPPORTED");
|
||||
assert ((P.SVPBMT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $fatal(1, "SVPBMT requires VIRTMEM_SUPPORTED and RV64");
|
||||
assert ((P.SVNAPOT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $fatal(1, "SVNAPOT requires VIRTMEM_SUPPORTED and RV64");
|
||||
assert ((P.ZCB_SUPPORTED == 0) || (P.M_SUPPORTED == 1 && (P.ZBA_SUPPORTED == 1 || P.XLEN == 32) && P.ZBB_SUPPORTED == 1)) else $fatal(1, "ZCB requires M and ZBB (and also ZBA for RV64)");
|
||||
assert ((P.C_SUPPORTED == 0) || (P.ZCA_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0 && P.ZCD_SUPPORTED == 0)) else $fatal(1, "C and ZCA/ZCD/ZCF cannot simultaneously be supported");
|
||||
assert ((P.ZCA_SUPPORTED == 1) || (P.ZCD_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0)) else $fatal(1, "ZCF or ZCD requires ZCA");
|
||||
assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $fatal(1, "ZCF requires F");
|
||||
assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,870 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// testbench-linux.sv
|
||||
//
|
||||
// Written: nboorstin@g.hmc.edu 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Testbench for Buildroot Linux
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 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.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "config.vh"
|
||||
import cvw::*;
|
||||
|
||||
`define DEBUG_TRACE 0
|
||||
// Debug Levels
|
||||
// 0: don't check against QEMU
|
||||
// 1: print disagreements with QEMU, but only halt on PCW disagreements
|
||||
// 2: halt on any disagreement with QEMU except CSRs
|
||||
// 3: halt on all disagreements with QEMU
|
||||
// 4: print memory accesses whenever they happen
|
||||
// 5: print everything
|
||||
|
||||
module testbench;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////// CONFIG ////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Recommend setting all of these in 'do' script using -G option
|
||||
parameter INSTR_LIMIT = 0; // # of instructions at which to stop
|
||||
parameter INSTR_WAVEON = 0; // # of instructions at which to turn on waves in graphical sim
|
||||
parameter CHECKPOINT = 0;
|
||||
parameter RISCV_DIR = "/opt/riscv";
|
||||
parameter NO_SPOOFING = 0;
|
||||
|
||||
|
||||
`include "parameter-defs.vh"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////// SIGNAL / VAR / MACRO DECLARATIONS /////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// ========== Testbench Core ==========
|
||||
integer warningCount = 0;
|
||||
integer errorCount = 0;
|
||||
integer fault;
|
||||
string ProgramAddrMapFile, ProgramLabelMapFile;
|
||||
// ========== Initialization ==========
|
||||
string testvectorDir;
|
||||
string linuxImageDir;
|
||||
integer memFile;
|
||||
integer readResult;
|
||||
// ========== Checkpointing ==========
|
||||
string checkpointDir;
|
||||
logic [1:0] initPriv;
|
||||
// ========== Trace parsing & checking ==========
|
||||
integer garbageInt;
|
||||
string garbageString;
|
||||
`define DECLARE_TRACE_SCANNER_SIGNALS(STAGE) \
|
||||
integer traceFile``STAGE; \
|
||||
integer matchCount``STAGE; \
|
||||
string line``STAGE; \
|
||||
string token``STAGE; \
|
||||
string ExpectedTokens``STAGE [31:0]; \
|
||||
integer index``STAGE; \
|
||||
integer StartIndex``STAGE, EndIndex``STAGE; \
|
||||
integer TokenIndex``STAGE; \
|
||||
integer MarkerIndex``STAGE; \
|
||||
integer NumCSR``STAGE; \
|
||||
logic [P.XLEN-1:0] ExpectedPC``STAGE; \
|
||||
logic [31:0] ExpectedInstr``STAGE; \
|
||||
string text``STAGE; \
|
||||
string MemOp``STAGE; \
|
||||
string RegWrite``STAGE; \
|
||||
integer ExpectedRegAdr``STAGE; \
|
||||
logic [P.XLEN-1:0] ExpectedRegValue``STAGE; \
|
||||
logic [P.XLEN-1:0] ExpectedIEUAdr``STAGE, ExpectedMemReadData``STAGE, ExpectedMemWriteData``STAGE; \
|
||||
string ExpectedCSRArray``STAGE[10:0]; \
|
||||
logic [P.XLEN-1:0] ExpectedCSRArrayValue``STAGE[10:0]; // *** might be redundant?
|
||||
`DECLARE_TRACE_SCANNER_SIGNALS(E)
|
||||
`DECLARE_TRACE_SCANNER_SIGNALS(M)
|
||||
// M-stage expected values
|
||||
logic checkInstrM;
|
||||
integer MIPexpected, SIPexpected;
|
||||
string name;
|
||||
logic [P.AHBW-1:0] readDataExpected;
|
||||
// W-stage expected values
|
||||
logic checkInstrW;
|
||||
logic [P.XLEN-1:0] ExpectedPCW;
|
||||
logic [31:0] ExpectedInstrW;
|
||||
string textW;
|
||||
string RegWriteW;
|
||||
integer ExpectedRegAdrW;
|
||||
logic [P.XLEN-1:0] ExpectedRegValueW;
|
||||
string MemOpW;
|
||||
logic [P.XLEN-1:0] ExpectedIEUAdrW, ExpectedMemReadDataW, ExpectedMemWriteDataW;
|
||||
integer NumCSRW;
|
||||
string ExpectedCSRArrayW[10:0];
|
||||
logic [P.XLEN-1:0] ExpectedCSRArrayValueW[10:0];
|
||||
logic [P.XLEN-1:0] ExpectedIntType;
|
||||
integer NumCSRWIndex;
|
||||
integer NumCSRPostWIndex;
|
||||
logic [P.XLEN-1:0] InstrCountW;
|
||||
// ========== Interrupt parsing & spoofing ==========
|
||||
string interrupt;
|
||||
string interruptLine;
|
||||
integer interruptFile;
|
||||
integer interruptInstrCount;
|
||||
integer interruptHartVal;
|
||||
integer interruptAsyncVal;
|
||||
longint interruptCauseVal;
|
||||
longint interruptEpcVal;
|
||||
longint interruptTVal;
|
||||
string interruptDesc;
|
||||
integer NextMIPexpected, NextSIPexpected;
|
||||
integer NextMepcExpected;
|
||||
logic [P.XLEN-1:0] AttemptedInstructionCount;
|
||||
// ========== Misc Aliases ==========
|
||||
`define RF dut.core.ieu.dp.regf.rf
|
||||
`define PC dut.core.ifu.pcreg.q
|
||||
`define PRIV_BASE dut.core.priv.priv
|
||||
`define PRIV `PRIV_BASE.privmode.privmode.privmodereg.q
|
||||
`define CSR_BASE `PRIV_BASE.csr
|
||||
`define MEIP `PRIV_BASE.MExtInt
|
||||
`define SEIP `PRIV_BASE.SExtInt
|
||||
`define MTIP `PRIV_BASE.MTimerInt
|
||||
`define HPMCOUNTER `CSR_BASE.counters.counters.HPMCOUNTER_REGW
|
||||
`define MEDELEG `CSR_BASE.csrm.deleg.MEDELEGreg.q
|
||||
`define MIDELEG `CSR_BASE.csrm.deleg.MIDELEGreg.q
|
||||
`define MIE `CSR_BASE.csri.MIE_REGW
|
||||
`define MIP `CSR_BASE.csri.MIP_REGW_writeable
|
||||
`define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q
|
||||
`define SCAUSE `CSR_BASE.csrs.csrs.SCAUSEreg.q
|
||||
`define MEPC `CSR_BASE.csrm.MEPCreg.q
|
||||
`define SEPC `CSR_BASE.csrs.csrs.SEPCreg.q
|
||||
`define MCOUNTEREN `CSR_BASE.csrm.mcounteren.MCOUNTERENreg.q
|
||||
`define SCOUNTEREN `CSR_BASE.csrs.csrs.SCOUNTERENreg.q
|
||||
`define MSCRATCH `CSR_BASE.csrm.MSCRATCHreg.q
|
||||
`define SSCRATCH `CSR_BASE.csrs.csrs.SSCRATCHreg.q
|
||||
`define MTVEC `CSR_BASE.csrm.MTVECreg.q
|
||||
`define STVEC `CSR_BASE.csrs.csrs.STVECreg.q
|
||||
`define SATP `CSR_BASE.csrs.csrs.genblk2.SATPreg.q
|
||||
`define INSTRET `CSR_BASE.counters.counters.HPMCOUNTER_REGW[2]
|
||||
`define MSTATUS `CSR_BASE.csrsr.MSTATUS_REGW
|
||||
`define SSTATUS `CSR_BASE.csrsr.SSTATUS_REGW
|
||||
`define STATUS_TSR `CSR_BASE.csrsr.STATUS_TSR_INT
|
||||
`define STATUS_TW `CSR_BASE.csrsr.STATUS_TW_INT
|
||||
`define STATUS_TVM `CSR_BASE.csrsr.STATUS_TVM_INT
|
||||
`define STATUS_MXR `CSR_BASE.csrsr.STATUS_MXR_INT
|
||||
`define STATUS_SUM `CSR_BASE.csrsr.STATUS_SUM_INT
|
||||
`define STATUS_MPRV `CSR_BASE.csrsr.STATUS_MPRV_INT
|
||||
`define STATUS_FS `CSR_BASE.csrsr.STATUS_FS_INT
|
||||
`define STATUS_MPP `CSR_BASE.csrsr.STATUS_MPP
|
||||
`define STATUS_SPP `CSR_BASE.csrsr.STATUS_SPP
|
||||
`define STATUS_MPIE `CSR_BASE.csrsr.STATUS_MPIE
|
||||
`define STATUS_SPIE `CSR_BASE.csrsr.STATUS_SPIE
|
||||
`define STATUS_MIE `CSR_BASE.csrsr.STATUS_MIE
|
||||
`define STATUS_SIE `CSR_BASE.csrsr.STATUS_SIE
|
||||
`define UART dut.uncore.uncore.uart.uart.u
|
||||
`define UART_IER `UART.IER
|
||||
`define UART_LCR `UART.LCR
|
||||
`define UART_MCR `UART.MCR
|
||||
`define UART_SCR `UART.SCR
|
||||
`define UART_IP `UART.INTR
|
||||
`define PLIC dut.uncore.uncore.plic.plic
|
||||
`define PLIC_INT_PRIORITY `PLIC.intPriority
|
||||
`define PLIC_INT_ENABLE `PLIC.intEn
|
||||
`define PLIC_THRESHOLD `PLIC.intThreshold
|
||||
`define PCM dut.core.ifu.PCM
|
||||
// ========== COMMON MACROS ==========
|
||||
// Needed for initialization and core
|
||||
`define SCAN_NEW_INTERRUPT \
|
||||
begin \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
//$display("Time %t, interruptLine %x", $time, interruptLine); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%d", interruptInstrCount); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%d", interruptHartVal); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%d", interruptAsyncVal); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%x", interruptCauseVal); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%x", interruptEpcVal); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%x", interruptTVal); \
|
||||
$fgets(interruptLine, interruptFile); \
|
||||
$sscanf(interruptLine, "%s", interruptDesc); \
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// Cache Issue ///////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Duplicate copy of pipeline registers that are optimized out of some configurations
|
||||
logic [31:0] NextInstrE, InstrM;
|
||||
mux2 #(32) FlushInstrMMux(dut.core.ifu.InstrE, dut.core.ifu.nop, dut.core.ifu.FlushM, NextInstrE);
|
||||
flopenr #(32) InstrMReg(dut.core.clk, dut.core.reset, ~dut.core.ifu.StallM, NextInstrE, InstrM);
|
||||
|
||||
logic probe;
|
||||
if (NO_SPOOFING)
|
||||
assign probe = testbench.dut.core.PCM == 64'hffffffff80200c8c
|
||||
& InstrM != 32'h14021273
|
||||
& testbench.dut.core.InstrValidM;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////// HARDWARE ///////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Clock and Reset
|
||||
logic clk, reset_ext;
|
||||
logic reset;
|
||||
initial begin reset_ext <= 1; # 22; reset_ext <= 0; end
|
||||
always begin clk <= 1; # 5; clk <= 0; # 5; end
|
||||
// Wally Interface
|
||||
logic [P.AHBW-1:0] HRDATAEXT;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic HCLK, HRESETn;
|
||||
logic HREADY;
|
||||
logic HSELEXT;
|
||||
logic HSELEXTSDC;
|
||||
logic [P.PA_BITS-1:0] HADDR;
|
||||
logic [P.AHBW-1:0] HWDATA;
|
||||
logic [P.XLEN/8-1:0] HWSTRB;
|
||||
logic HWRITE;
|
||||
logic [2:0] HSIZE;
|
||||
logic [2:0] HBURST;
|
||||
logic [3:0] HPROT;
|
||||
logic [1:0] HTRANS;
|
||||
logic HMASTLOCK;
|
||||
logic [31:0] GPIOIN;
|
||||
logic [31:0] GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
logic SPIIn, SPIOut;
|
||||
logic [3:0] SPICS;
|
||||
|
||||
// FPGA-specific Stuff
|
||||
logic SDCIntr;
|
||||
|
||||
// Hardwire UART, GPIO pins
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
assign SDCIntr = 0;
|
||||
|
||||
// Wally
|
||||
wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC,
|
||||
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout, .SDCIntr, .SPICS, .SPIOut, .SPIIn);
|
||||
|
||||
// W-stage hardware not needed by Wally itself
|
||||
parameter nop = 'h13;
|
||||
logic [P.XLEN-1:0] PCW;
|
||||
logic [31:0] InstrW;
|
||||
logic InstrValidW;
|
||||
logic [P.XLEN-1:0] IEUAdrW, WriteDataW;
|
||||
logic TrapW;
|
||||
`define FLUSHW dut.core.FlushW
|
||||
`define STALLW dut.core.StallW
|
||||
flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : InstrM, InstrW);
|
||||
flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW);
|
||||
flopenrc #(P.XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW);
|
||||
flopenrc #(P.XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW);
|
||||
flopenr #(1) TrapWReg(clk, reset, ~`STALLW, dut.core.hzu.TrapM, TrapW);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// INITIALIZATION ////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ========== CHECKPOINTING ==========
|
||||
`define MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
logic DIM init``SIGNAL[ARRAY_MAX:ARRAY_MIN]; \
|
||||
initial begin \
|
||||
#1; \
|
||||
if (CHECKPOINT!=0) $readmemh({checkpointDir,"checkpoint-",`"SIGNAL`"}, init``SIGNAL); \
|
||||
end
|
||||
|
||||
`define INIT_CHECKPOINT_SIMPLE_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
initial begin \
|
||||
if (CHECKPOINT!=0) begin \
|
||||
force `SIGNAL = init``SIGNAL[ARRAY_MAX:ARRAY_MIN]; \
|
||||
while (reset!==1) #1; \
|
||||
while (reset!==0) #1; \
|
||||
#1; \
|
||||
release `SIGNAL; \
|
||||
end \
|
||||
end
|
||||
|
||||
`define INIT_CHECKPOINT_PACKED_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \
|
||||
for (i=ARRAY_MIN; i<ARRAY_MAX+1; i=i+1) begin \
|
||||
initial begin \
|
||||
if (CHECKPOINT!=0) begin \
|
||||
force `SIGNAL[i] = init``SIGNAL[i]; \
|
||||
while (reset!==1) #1; \
|
||||
while (reset!==0) #1; \
|
||||
#1; \
|
||||
release `SIGNAL[i]; \
|
||||
end \
|
||||
end \
|
||||
end
|
||||
|
||||
// Note that dimension usage is very intentional here.
|
||||
// We are dancing around (un)packed type requirements.
|
||||
`define INIT_CHECKPOINT_VAL(SIGNAL,DIM) \
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,0,0) \
|
||||
initial begin \
|
||||
if (CHECKPOINT!=0) begin \
|
||||
force `SIGNAL = init``SIGNAL[0]; \
|
||||
while (reset!==1) #1; \
|
||||
while (reset!==0) #1; \
|
||||
#1; \
|
||||
release `SIGNAL; \
|
||||
end \
|
||||
end
|
||||
|
||||
// Initializing all zeroes into the branch predictor memory.
|
||||
genvar adrindex;
|
||||
for(adrindex = 0; adrindex < 1024; 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
|
||||
|
||||
genvar i;
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [P.XLEN-1:0],31,1);
|
||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [P.XLEN-1:0],P.COUNTERS-1,0);
|
||||
`INIT_CHECKPOINT_VAL(PC, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MEDELEG, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MIDELEG, [P.XLEN-1:0]);
|
||||
if(!NO_SPOOFING) begin
|
||||
`INIT_CHECKPOINT_VAL(MIE, [11:0]);
|
||||
`INIT_CHECKPOINT_VAL(MIP, [11:0]);
|
||||
end
|
||||
`INIT_CHECKPOINT_VAL(MCAUSE, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(SCAUSE, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MEPC, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(SEPC, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MCOUNTEREN, [31:0]);
|
||||
`INIT_CHECKPOINT_VAL(SCOUNTEREN, [31:0]);
|
||||
`INIT_CHECKPOINT_VAL(MSCRATCH, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(SSCRATCH, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(MTVEC, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(STVEC, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(SATP, [P.XLEN-1:0]);
|
||||
`INIT_CHECKPOINT_VAL(PRIV, [1:0]);
|
||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],P.PLIC_NUM_SRC,1);
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(PLIC_INT_ENABLE, [P.PLIC_NUM_SRC:0],1,0);
|
||||
`INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
||||
// UART checkpointing does not cover entire UART state
|
||||
// Many UART registers are difficult to initialize because under the hood
|
||||
// they are not simple registers. Instead some are generated by interesting
|
||||
// combinational blocks such that they depend upon a variety of different
|
||||
// underlying flops. See for example how RBR might be the actual RXBR
|
||||
// register, but it could also just as well be 0 or the tail of the fifo
|
||||
// array.
|
||||
`INIT_CHECKPOINT_VAL(UART_IER, [7:0]);
|
||||
`INIT_CHECKPOINT_VAL(UART_LCR, [7:0]);
|
||||
`INIT_CHECKPOINT_VAL(UART_MCR, [4:0]);
|
||||
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
||||
// xSTATUS need to be handled manually because the most upstream signals
|
||||
// are made of individual bits, not registers
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(MSTATUS, [P.XLEN-1:0],0,0);
|
||||
`MAKE_CHECKPOINT_INIT_SIGNAL(SSTATUS, [P.XLEN-1:0],0,0);
|
||||
|
||||
// ========== INITIALIZATION ==========
|
||||
initial begin
|
||||
if(!NO_SPOOFING) begin
|
||||
force `MEIP = 0;
|
||||
force `SEIP = 0;
|
||||
force `UART_IP = 0;
|
||||
force `MTIP = 0;
|
||||
end
|
||||
$sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR);
|
||||
$sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR);
|
||||
if (CHECKPOINT!=0)
|
||||
$sformat(checkpointDir,"%s/linux-testvectors/checkpoint%0d/",RISCV_DIR,CHECKPOINT);
|
||||
ProgramAddrMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.addr"};
|
||||
ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"};
|
||||
// initialize bootrom
|
||||
memFile = $fopen({testvectorDir,"bootmem.bin"}, "rb");
|
||||
readResult = $fread(dut.uncore.uncore.bootrom.bootrom.memory.ROM,memFile);
|
||||
$fclose(memFile);
|
||||
// initialize RAM and ROM
|
||||
if (CHECKPOINT==0)
|
||||
memFile = $fopen({testvectorDir,"ram.bin"}, "rb");
|
||||
else
|
||||
memFile = $fopen({checkpointDir,"ram.bin"}, "rb");
|
||||
readResult = $fread(dut.uncore.uncore.ram.ram.memory.RAM,memFile);
|
||||
$fclose(memFile);
|
||||
// ---------- Ground-Zero -----------
|
||||
if (CHECKPOINT==0) begin
|
||||
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
|
||||
traceFileE = $fopen({testvectorDir,"all.txt"}, "r");
|
||||
interruptFile = $fopen({testvectorDir,"interrupts.txt"}, "r");
|
||||
`SCAN_NEW_INTERRUPT
|
||||
InstrCountW = '0;
|
||||
AttemptedInstructionCount = 1; // offset needed here when running from ground zero
|
||||
// ---------- Checkpoint ----------
|
||||
end else begin
|
||||
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.uncore.ram.ram.memory.RAM);
|
||||
traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
|
||||
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
|
||||
interruptFile = $fopen({testvectorDir,"interrupts.txt"}, "r");
|
||||
`SCAN_NEW_INTERRUPT
|
||||
while(interruptInstrCount < CHECKPOINT) begin
|
||||
`SCAN_NEW_INTERRUPT
|
||||
end
|
||||
InstrCountW = CHECKPOINT;
|
||||
AttemptedInstructionCount = CHECKPOINT;
|
||||
// manual checkpoint initializations
|
||||
force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17];
|
||||
force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11];
|
||||
force {`STATUS_SPP,`STATUS_MPIE} = initMSTATUS[0][8:7];
|
||||
// force {`STATUS_SPIE,`STATUS_UPIE,`STATUS_MIE} = initMSTATUS[0][5:3]; // dh removed UPIE and UIE 4/25/22 from depricated n-mode
|
||||
force {`STATUS_SPIE} = initMSTATUS[0][5];
|
||||
force {`STATUS_MIE} = initMSTATUS[0][3];
|
||||
force {`STATUS_SIE} = initMSTATUS[0][1];
|
||||
force `PLIC_INT_ENABLE = {initPLIC_INT_ENABLE[1][P.PLIC_NUM_SRC:1],initPLIC_INT_ENABLE[0][P.PLIC_NUM_SRC:1]}; // would need to expand into a generate loop to cover an arbitrary number of contexts
|
||||
force `INSTRET = CHECKPOINT;
|
||||
while (reset!==1) #1;
|
||||
while (reset!==0) #1;
|
||||
#1;
|
||||
release {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV};
|
||||
release {`STATUS_FS,`STATUS_MPP};
|
||||
release {`STATUS_SPP,`STATUS_MPIE};
|
||||
release {`STATUS_SPIE,`STATUS_MIE};
|
||||
release {`STATUS_SIE};
|
||||
release `PLIC_INT_ENABLE;
|
||||
release `INSTRET;
|
||||
end
|
||||
// Get the E-stage trace reader ahead of the M-stage trace reader
|
||||
matchCountE = $fgets(lineE,traceFileE); // *** look at removing?
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////// CORE /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// =========== TRACE PARSING MACRO ==========
|
||||
// Because qemu does not match exactly to wally it is necessary to read the the
|
||||
// trace in the memory stage and detect if anything in wally must be overwritten.
|
||||
// This includes mtimer, interrupts, and various bits in mstatus and xtval.
|
||||
|
||||
// then on the next posedge the expected state is registered.
|
||||
// on the next falling edge the expected state is compared to the wally state.
|
||||
|
||||
// step 0: read the expected state
|
||||
`define SCAN_NEW_INSTR_FROM_TRACE(STAGE) \
|
||||
// always check PC, instruction bits \
|
||||
if (checkInstrM) begin \
|
||||
// read 1 line of the trace file \
|
||||
matchCount``STAGE = $fgets(line``STAGE, traceFile``STAGE); \
|
||||
if(`DEBUG_TRACE >= 5) $display("Time %t, line %x", $time, line``STAGE); \
|
||||
// extract PC, Instr \
|
||||
matchCount``STAGE = $sscanf(line``STAGE, "%x %x %s", ExpectedPC``STAGE, ExpectedInstr``STAGE, text``STAGE); \
|
||||
if (`"STAGE`"=="M") begin \
|
||||
AttemptedInstructionCount += 1; \
|
||||
end \
|
||||
\
|
||||
// for the life of me I cannot get any build in C or C++ string parsing functions/methods to work. \
|
||||
// strtok was the best idea but it cannot be used correctly as system verilog does not have null \
|
||||
// terminated strings. \
|
||||
\
|
||||
// Just going to do this char by char. \
|
||||
StartIndex``STAGE = 0; \
|
||||
TokenIndex``STAGE = 0; \
|
||||
//$display("len = %d", line``STAGE.len()); \
|
||||
for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \
|
||||
//$display("char = %s", line``STAGE[index]); \
|
||||
if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \
|
||||
EndIndex``STAGE = index``STAGE; \
|
||||
ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \
|
||||
//$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \
|
||||
StartIndex``STAGE = EndIndex``STAGE + 1; \
|
||||
TokenIndex``STAGE++; \
|
||||
end \
|
||||
end \
|
||||
\
|
||||
MarkerIndex``STAGE = 3; \
|
||||
NumCSR``STAGE = 0; \
|
||||
MemOp``STAGE = ""; \
|
||||
RegWrite``STAGE = ""; \
|
||||
\
|
||||
#2; \
|
||||
\
|
||||
while(TokenIndex``STAGE > MarkerIndex``STAGE) begin \
|
||||
// parse the GPR \
|
||||
if (ExpectedTokens``STAGE[MarkerIndex``STAGE] == "GPR") begin \
|
||||
RegWrite``STAGE = ExpectedTokens``STAGE[MarkerIndex``STAGE]; \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%d", ExpectedRegAdr``STAGE); \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+2], "%x", ExpectedRegValue``STAGE); \
|
||||
MarkerIndex``STAGE += 3; \
|
||||
// parse memory address, read data, and/or write data \
|
||||
end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE].substr(0, 2) == "Mem") begin \
|
||||
MemOp``STAGE = ExpectedTokens``STAGE[MarkerIndex``STAGE]; \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%x", ExpectedIEUAdr``STAGE); \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+2], "%x", ExpectedMemWriteData``STAGE); \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+3], "%x", ExpectedMemReadData``STAGE); \
|
||||
MarkerIndex``STAGE += 4; \
|
||||
// parse CSRs, because there are 1 or more CSRs after the CSR token \
|
||||
// we check if the CSR token or the number of CSRs is greater than 0. \
|
||||
// if so then we want to parse for a CSR. \
|
||||
end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR" | NumCSR``STAGE > 0) begin \
|
||||
if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR") begin \
|
||||
// all additional CSR's won't have this token. \
|
||||
MarkerIndex``STAGE++; \
|
||||
end \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE], "%s", ExpectedCSRArray``STAGE[NumCSR``STAGE]); \
|
||||
matchCount``STAGE = $sscanf(ExpectedTokens``STAGE[MarkerIndex``STAGE+1], "%x", ExpectedCSRArrayValue``STAGE[NumCSR``STAGE]); \
|
||||
MarkerIndex``STAGE += 2; \
|
||||
\
|
||||
NumCSR``STAGE++; \
|
||||
end \
|
||||
end \
|
||||
if(`"STAGE`"=="M") begin \
|
||||
// override on special conditions \
|
||||
if ((dut.core.lsu.PAdrM == 'h10000002) | (dut.core.lsu.PAdrM == 'h10000005) | (dut.core.lsu.PAdrM == 'h10000006)) begin \
|
||||
if(!NO_SPOOFING) begin \
|
||||
$display("%tns, %d instrs: Overwrite UART's Register in memory stage.", $time, AttemptedInstructionCount); \
|
||||
force dut.core.lsu.ReadDataM = ExpectedMemReadDataM; \
|
||||
end \
|
||||
end else \
|
||||
if(!NO_SPOOFING) \
|
||||
release dut.core.lsu.ReadDataM; \
|
||||
if(textM.substr(0,5) == "rdtime") begin \
|
||||
//$display("%tns, %d instrs: Overwrite MTIME_CLINT on read of MTIME in memory stage.", $time, InstrCountW-1); \
|
||||
if(!NO_SPOOFING) \
|
||||
force dut.uncore.uncore.clint.clint.MTIME = ExpectedRegValueM; \
|
||||
end \
|
||||
end \
|
||||
end \
|
||||
|
||||
// ========== VALUE-CHECKING MACROS ==========
|
||||
`define checkEQ(NAME, VAL, EXPECTED) \
|
||||
if(VAL != EXPECTED) begin \
|
||||
$display("%tns, %d instrs: %s %x differs from expected %x", $time, AttemptedInstructionCount, NAME, VAL, EXPECTED); \
|
||||
if ((NAME == "PCW") | (`DEBUG_TRACE >= 2)) fault = 1; \
|
||||
end
|
||||
|
||||
`define checkCSR(CSR) \
|
||||
begin \
|
||||
if (CSR != ExpectedCSRArrayValueW[NumCSRPostWIndex]) begin \
|
||||
$display("%tns, %d instrs: CSR %s = %016x, does not equal expected value %016x", $time, AttemptedInstructionCount, ExpectedCSRArrayW[NumCSRPostWIndex], CSR, ExpectedCSRArrayValueW[NumCSRPostWIndex]); \
|
||||
if(`DEBUG_TRACE >= 3) fault = 1; \
|
||||
end \
|
||||
end
|
||||
|
||||
// =========== CORE ===========
|
||||
assign checkInstrM = dut.core.ieu.InstrValidM & ~dut.core.priv.priv.trap.InstrPageFaultM & ~dut.core.priv.priv.trap.InterruptM & ~dut.core.StallM;
|
||||
always @(negedge clk) begin
|
||||
`SCAN_NEW_INSTR_FROM_TRACE(E)
|
||||
`SCAN_NEW_INSTR_FROM_TRACE(M)
|
||||
end
|
||||
|
||||
// step 1: register expected state into the write back stage.
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
ExpectedPCW <= '0;
|
||||
ExpectedInstrW <= '0;
|
||||
textW <= "";
|
||||
RegWriteW <= "";
|
||||
ExpectedRegAdrW <= '0;
|
||||
ExpectedRegValueW <= '0;
|
||||
ExpectedIEUAdrW <= '0;
|
||||
MemOpW <= "";
|
||||
ExpectedMemWriteDataW <= '0;
|
||||
ExpectedMemReadDataW <= '0;
|
||||
NumCSRW <= '0;
|
||||
end else if(~dut.core.StallW) begin
|
||||
if(dut.core.FlushW) begin
|
||||
ExpectedPCW <= '0;
|
||||
ExpectedInstrW <= '0;
|
||||
textW <= "";
|
||||
RegWriteW <= "";
|
||||
ExpectedRegAdrW <= '0;
|
||||
ExpectedRegValueW <= '0;
|
||||
ExpectedIEUAdrW <= '0;
|
||||
MemOpW <= "";
|
||||
ExpectedMemWriteDataW <= '0;
|
||||
ExpectedMemReadDataW <= '0;
|
||||
NumCSRW <= '0;
|
||||
end else if (dut.core.ieu.c.InstrValidM) begin
|
||||
ExpectedPCW <= ExpectedPCM;
|
||||
ExpectedInstrW <= ExpectedInstrM;
|
||||
textW <= textM;
|
||||
RegWriteW <= RegWriteM;
|
||||
ExpectedRegAdrW <= ExpectedRegAdrM;
|
||||
ExpectedRegValueW <= ExpectedRegValueM;
|
||||
ExpectedIEUAdrW <= ExpectedIEUAdrM;
|
||||
MemOpW <= MemOpM;
|
||||
ExpectedMemWriteDataW <= ExpectedMemWriteDataM;
|
||||
ExpectedMemReadDataW <= ExpectedMemReadDataM;
|
||||
NumCSRW <= NumCSRM;
|
||||
for(NumCSRWIndex = 0; NumCSRWIndex < NumCSRM; NumCSRWIndex++) begin
|
||||
ExpectedCSRArrayW[NumCSRWIndex] = ExpectedCSRArrayM[NumCSRWIndex];
|
||||
ExpectedCSRArrayValueW[NumCSRWIndex] = ExpectedCSRArrayValueM[NumCSRWIndex];
|
||||
end
|
||||
end
|
||||
#1;
|
||||
// override on special conditions
|
||||
if(~dut.core.StallW) begin
|
||||
if(textW.substr(0,5) == "rdtime") begin
|
||||
//$display("%tns, %d instrs: Releasing force of MTIME_CLINT.", $time, AttemptedInstructionCount);
|
||||
if(!NO_SPOOFING)
|
||||
release dut.uncore.uncore.clint.clint.MTIME;
|
||||
end
|
||||
//if (ExpectedIEUAdrM == 'h10000005) begin
|
||||
//$display("%tns, %d instrs: releasing force of ReadDataM.", $time, AttemptedInstructionCount);
|
||||
//release dut.core.ieu.dp.ReadDataM;
|
||||
//end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// step2: make all checks in the write back stage.
|
||||
assign checkInstrW = InstrValidW & ~dut.core.StallW; // trapW will already be invalid in there was an InstrPageFault in the previous instruction.
|
||||
always @(negedge clk) begin
|
||||
#1; // small delay allows interrupt spoofing to happen first
|
||||
// always check PC, instruction bits
|
||||
if (checkInstrW) begin
|
||||
InstrCountW += 1;
|
||||
// print progress message
|
||||
if (AttemptedInstructionCount % 'd100000 == 0) $display("Reached %d instructions", AttemptedInstructionCount);
|
||||
// turn on waves
|
||||
if (AttemptedInstructionCount == INSTR_WAVEON) $stop;
|
||||
// end sim
|
||||
if ((AttemptedInstructionCount == INSTR_LIMIT) & (INSTR_LIMIT!=0)) begin $stop; $stop; end
|
||||
fault = 0;
|
||||
if (`DEBUG_TRACE >= 1) begin
|
||||
`checkEQ("PCW",PCW,ExpectedPCW)
|
||||
//`checkEQ("InstrW",InstrW,ExpectedInstrW) <-- not viable because of
|
||||
// compressed to uncompressed conversion
|
||||
`checkEQ("Instr Count",dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2],InstrCountW)
|
||||
#2; // delay 2 ns.
|
||||
if(`DEBUG_TRACE >= 5) begin
|
||||
$display("%tns, %d instrs: Reg Write Address %02d ? expected value: %02d", $time, AttemptedInstructionCount, dut.core.ieu.dp.regf.a3, ExpectedRegAdrW);
|
||||
$display("%tns, %d instrs: RF[%02d] %016x ? expected value: %016x", $time, AttemptedInstructionCount, ExpectedRegAdrW, dut.core.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW);
|
||||
end
|
||||
if (RegWriteW == "GPR") begin
|
||||
`checkEQ("Reg Write Address",dut.core.ieu.dp.regf.a3,ExpectedRegAdrW)
|
||||
$sformat(name,"RF[%02d]",ExpectedRegAdrW);
|
||||
`checkEQ(name, dut.core.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW)
|
||||
end
|
||||
if (MemOpW.substr(0,2) == "Mem") begin
|
||||
if(`DEBUG_TRACE >= 4) $display("\tIEUAdrW: %016x ? expected: %016x", IEUAdrW, ExpectedIEUAdrW);
|
||||
`checkEQ("IEUAdrW",IEUAdrW,ExpectedIEUAdrW)
|
||||
if(MemOpW == "MemR" | MemOpW == "MemRW") begin
|
||||
if(`DEBUG_TRACE >= 4) $display("\tReadDataW: %016x ? expected: %016x", dut.core.ieu.dp.ReadDataW, ExpectedMemReadDataW);
|
||||
`checkEQ("ReadDataW",dut.core.ieu.dp.ReadDataW,ExpectedMemReadDataW)
|
||||
end else if(MemOpW == "MemW" | MemOpW == "MemRW") begin
|
||||
if(`DEBUG_TRACE >= 4) $display("\tWriteDataW: %016x ? expected: %016x", WriteDataW, ExpectedMemWriteDataW);
|
||||
`checkEQ("WriteDataW",ExpectedMemWriteDataW,ExpectedMemWriteDataW)
|
||||
end
|
||||
end
|
||||
// check csr
|
||||
for(NumCSRPostWIndex = 0; NumCSRPostWIndex < NumCSRW; NumCSRPostWIndex++) begin
|
||||
case(ExpectedCSRArrayW[NumCSRPostWIndex])
|
||||
"mhartid": `checkCSR(`CSR_BASE.csrm.MHARTID_REGW)
|
||||
"mstatus": `checkCSR(`CSR_BASE.csrm.MSTATUS_REGW)
|
||||
"sstatus": `checkCSR(`CSR_BASE.csrs.csrs.SSTATUS_REGW)
|
||||
"mtvec": `checkCSR(`CSR_BASE.csrm.MTVEC_REGW)
|
||||
"mie": `checkCSR(`CSR_BASE.csrm.MIE_REGW)
|
||||
"mideleg": `checkCSR(`CSR_BASE.csrm.MIDELEG_REGW)
|
||||
"medeleg": `checkCSR(`CSR_BASE.csrm.MEDELEG_REGW)
|
||||
"mepc": `checkCSR(`CSR_BASE.csrm.MEPC_REGW)
|
||||
"mtval": `checkCSR(`CSR_BASE.csrm.MTVAL_REGW)
|
||||
"sepc": `checkCSR(`CSR_BASE.csrs.csrs.SEPC_REGW)
|
||||
"scause": `checkCSR(`CSR_BASE.csrs.csrs.SCAUSE_REGW)
|
||||
"stvec": `checkCSR(`CSR_BASE.csrs.csrs.STVEC_REGW)
|
||||
"stval": `checkCSR(`CSR_BASE.csrs.csrs.STVAL_REGW)
|
||||
"mip": begin
|
||||
`checkCSR(`CSR_BASE.csrm.MIP_REGW)
|
||||
if(!NO_SPOOFING) begin
|
||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<11) == 0)
|
||||
force `MEIP = 0;
|
||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<09) == 0)
|
||||
force `SEIP = 0;
|
||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & ((1<<11) | (1<<09))) == 0)
|
||||
force `UART_IP = 0;
|
||||
if ((ExpectedCSRArrayValueW[NumCSRPostWIndex] & 1<<07) == 0)
|
||||
force `MTIP = 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
if (fault == 1) begin
|
||||
errorCount +=1;
|
||||
$display("processed %0d instructions with %0d warnings", AttemptedInstructionCount, warningCount);
|
||||
$stop; $stop;
|
||||
end
|
||||
end // if (`DEBUG_TRACE >= 1)
|
||||
end // if (checkInstrW)
|
||||
end // always @ (negedge clk)
|
||||
|
||||
|
||||
// New IP spoofing
|
||||
logic globalIntsBecomeEnabled;
|
||||
assign globalIntsBecomeEnabled = (`CSR_BASE.csrm.WriteMSTATUSM || `CSR_BASE.csrs.csrs.WriteSSTATUSM) && (|(`CSR_BASE.CSRWriteValM & (~`CSR_BASE.csrm.MSTATUS_REGW) & 32'h22));
|
||||
logic checkInterruptM;
|
||||
assign checkInterruptM = dut.core.ieu.InstrValidM & ~dut.core.priv.priv.trap.InstrPageFaultM & ~dut.core.priv.priv.trap.InterruptM;
|
||||
|
||||
always @(negedge clk) begin
|
||||
if(checkInterruptM) begin
|
||||
if((interruptInstrCount+1) == AttemptedInstructionCount) begin
|
||||
if(!NO_SPOOFING) begin
|
||||
case (interruptCauseVal)
|
||||
11: begin
|
||||
force `MEIP = 1;
|
||||
force `UART_IP = 1;
|
||||
end
|
||||
09: begin
|
||||
force `SEIP = 1;
|
||||
force `UART_IP = 1;
|
||||
end
|
||||
07: force `MTIP = 1;
|
||||
default: $display("Unsupported interrupt in interrupts.txt. cause = %0d",interruptCauseVal);
|
||||
endcase
|
||||
$display("Forcing interrupt.");
|
||||
end
|
||||
`SCAN_NEW_INTERRUPT
|
||||
if (globalIntsBecomeEnabled) begin
|
||||
$display("Enabled global interrupts");
|
||||
// The idea here is if a CSR instruction causes an interrupt by
|
||||
// enabling interrupts, that CSR instruction will commit.
|
||||
end else begin
|
||||
// Other instructions, however, will get interrupted and not
|
||||
// commit, so we don't want our W-stage checker to look for them
|
||||
// and get confused when it doesn't find them.
|
||||
garbageInt = $fgets(garbageString,traceFileE);
|
||||
garbageInt = $fgets(garbageString,traceFileM);
|
||||
AttemptedInstructionCount += 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// Extra Features ///////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Function Tracking
|
||||
FunctionName #(P) FunctionName(.reset(reset),
|
||||
.clk(clk),
|
||||
.ProgramAddrMapFile(ProgramAddrMapFile),
|
||||
.ProgramLabelMapFile(ProgramLabelMapFile));
|
||||
|
||||
// Instr Opcode Tracking
|
||||
// For waveview convenience
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// ------------------
|
||||
// Address Translator
|
||||
// ------------------
|
||||
/**
|
||||
* Walk the page table stored in ram according to sv39 logic and translate a
|
||||
* virtual address to a physical address.
|
||||
*
|
||||
* See section 4.3.2 of the RISC-V Privileged specification for a full
|
||||
* explanation of the below algorithm.
|
||||
*/
|
||||
logic SvMode, PTE_R, PTE_X;
|
||||
logic [P.XLEN-1:0] SATP, PTE;
|
||||
logic [55:0] BaseAdr, PAdr;
|
||||
logic [8:0] VPN [2:0];
|
||||
logic [11:0] Offset;
|
||||
function logic [P.XLEN-1:0] adrTranslator(
|
||||
input logic [P.XLEN-1:0] adrIn);
|
||||
begin
|
||||
int i;
|
||||
// Grab the SATP register from privileged unit
|
||||
SATP = dut.core.priv.priv.csr.SATP_REGW;
|
||||
// Split the virtual address into page number segments and offset
|
||||
VPN[2] = adrIn[38:30];
|
||||
VPN[1] = adrIn[29:21];
|
||||
VPN[0] = adrIn[20:12];
|
||||
Offset = adrIn[11:0];
|
||||
// We do not support sv48; only sv39
|
||||
SvMode = SATP[63];
|
||||
// Only perform translation if translation is on and the processor is not
|
||||
// in machine mode
|
||||
if (SvMode & (dut.core.priv.priv.PrivilegeModeW != P.M_MODE)) begin
|
||||
BaseAdr = SATP[43:0] << 12;
|
||||
for (i = 2; i >= 0; i--) begin
|
||||
PAdr = BaseAdr + (VPN[i] << 3);
|
||||
// ram.memory.RAM is 64-bit addressed. PAdr specifies a byte. We right shift
|
||||
// by 3 (the PTE size) to get the requested 64-bit PTE.
|
||||
PTE = dut.uncore.uncore.ram.ram.memory.RAM[PAdr >> 3];
|
||||
PTE_R = PTE[1];
|
||||
PTE_X = PTE[3];
|
||||
if (PTE_R | PTE_X) begin
|
||||
// Leaf page found
|
||||
break;
|
||||
end else begin
|
||||
// Go to next level of table
|
||||
BaseAdr = PTE[53:10] << 12;
|
||||
end
|
||||
end
|
||||
// Determine which parts of the PTE page number to use based on the
|
||||
// level of the page table we reached.
|
||||
if (i == 2) begin
|
||||
// Gigapage
|
||||
assign adrTranslator = {8'b0, PTE[53:28], VPN[1], VPN[0], Offset};
|
||||
end else if (i == 1) begin
|
||||
// Megapage
|
||||
assign adrTranslator = {8'b0, PTE[53:19], VPN[0], Offset};
|
||||
end else begin
|
||||
// Kilopage
|
||||
assign adrTranslator = {8'b0, PTE[53:10], Offset};
|
||||
end
|
||||
end else begin
|
||||
// Direct translation if address translation is not on
|
||||
assign adrTranslator = adrIn;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
endmodule
|
@ -29,6 +29,10 @@
|
||||
`include "tests.vh"
|
||||
`include "BranchPredictorType.vh"
|
||||
|
||||
`ifdef USE_IMPERAS_DV
|
||||
`include "idv/idv.svh"
|
||||
`endif
|
||||
|
||||
import cvw::*;
|
||||
|
||||
module testbench;
|
||||
@ -40,7 +44,15 @@ module testbench;
|
||||
parameter BPRED_LOGGER=0;
|
||||
parameter I_CACHE_ADDR_LOGGER=0;
|
||||
parameter D_CACHE_ADDR_LOGGER=0;
|
||||
|
||||
parameter RISCV_DIR = "/opt/riscv";
|
||||
parameter INSTR_LIMIT = 0;
|
||||
|
||||
`ifdef USE_IMPERAS_DV
|
||||
import idvPkg::*;
|
||||
import rvviApiPkg::*;
|
||||
import idvApiPkg::*;
|
||||
`endif
|
||||
|
||||
`include "parameter-defs.vh"
|
||||
|
||||
logic clk;
|
||||
@ -121,7 +133,7 @@ module testbench;
|
||||
"wally64periph": tests = wally64periph;
|
||||
"coremark": tests = coremark;
|
||||
"fpga": tests = fpga;
|
||||
"ahb" : tests = ahb;
|
||||
"ahb64" : tests = ahb64;
|
||||
"coverage64gc" : tests = coverage64gc;
|
||||
"arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba;
|
||||
"arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb;
|
||||
@ -130,10 +142,11 @@ module testbench;
|
||||
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
|
||||
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
|
||||
"arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh;
|
||||
// "arch64zfh_fma": if (P.ZFH_SUPPORTED) tests = arch64zfh_fma; *** not yet in riscv-arch-tst PR367
|
||||
"arch64zfh_fma": if (P.ZFH_SUPPORTED) tests = arch64zfh_fma;
|
||||
"arch64zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch64zfh_divsqrt;
|
||||
"arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf;
|
||||
"arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad;
|
||||
"buildroot": tests = buildroot;
|
||||
endcase
|
||||
end else begin // RV32
|
||||
case (TEST)
|
||||
@ -162,6 +175,7 @@ module testbench;
|
||||
"wally32i": tests = wally32i;
|
||||
"wally32priv": tests = wally32priv;
|
||||
"wally32periph": tests = wally32periph;
|
||||
"ahb32" : tests = ahb32;
|
||||
"embench": tests = embench;
|
||||
"coremark": tests = coremark;
|
||||
"arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba;
|
||||
@ -171,7 +185,7 @@ module testbench;
|
||||
"arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz;
|
||||
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
|
||||
"arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh;
|
||||
// "arch32zfh_fma": if (P.ZFH_SUPPORTED) tests = arch32zfh_fma; *** not yet in riscv-arch-tst PR367
|
||||
"arch32zfh_fma": if (P.ZFH_SUPPORTED) tests = arch32zfh_fma;
|
||||
"arch32zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch32zfh_divsqrt;
|
||||
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
|
||||
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
|
||||
@ -179,7 +193,7 @@ module testbench;
|
||||
end
|
||||
if (tests.size() == 0) begin
|
||||
$display("TEST %s not supported in this configuration", TEST);
|
||||
$stop;
|
||||
$finish;
|
||||
end
|
||||
end // initial begin
|
||||
|
||||
@ -209,7 +223,7 @@ module testbench;
|
||||
logic ResetCntRst;
|
||||
logic CopyRAM;
|
||||
|
||||
string signame, memfilename, pathname;
|
||||
string signame, memfilename, bootmemfilename, pathname;
|
||||
integer begin_signature_addr, end_signature_addr, signature_size;
|
||||
|
||||
assign ResetThreshold = 3'd5;
|
||||
@ -278,10 +292,17 @@ module testbench;
|
||||
always @(posedge clk) begin
|
||||
if(SelectTest) begin
|
||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
||||
else if(TEST == "buildroot") begin
|
||||
memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"};
|
||||
bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"};
|
||||
end
|
||||
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
||||
if (riscofTest) begin
|
||||
ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"};
|
||||
ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"};
|
||||
end else if (TEST == "buildroot") begin
|
||||
ProgramAddrMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.addr"};
|
||||
ProgramLabelMapFile = {RISCV_DIR, "/buildroot/output/images/disassembly/vmlinux.objdump.lab"};
|
||||
end else begin
|
||||
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
|
||||
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
||||
@ -325,19 +346,18 @@ module testbench;
|
||||
end else begin
|
||||
// for tests with no self checking mechanism, read .signature.output file and compare to check for errors
|
||||
// clear signature to prevent contamination from previous tests
|
||||
if (!begin_signature_addr)
|
||||
$display("begin_signature addr not found in %s", ProgramLabelMapFile);
|
||||
else if (TEST != "embench") begin // *** quick hack for embench. need a better long term solution
|
||||
CheckSignature(pathname, tests[test], riscofTest, begin_signature_addr, errors);
|
||||
if(errors > 0) totalerrors = totalerrors + 1;
|
||||
end
|
||||
end
|
||||
|
||||
if (!begin_signature_addr)
|
||||
$display("begin_signature addr not found in %s", ProgramLabelMapFile);
|
||||
else if (TEST != "embench") begin // *** quick hack for embench. need a better long term solution
|
||||
CheckSignature(pathname, tests[test], riscofTest, begin_signature_addr, errors);
|
||||
end
|
||||
if(errors > 0) totalerrors = totalerrors + 1;
|
||||
test = test + 1; // *** this probably needs to be moved.
|
||||
if (test == tests.size()) begin
|
||||
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
|
||||
else $display("FAIL: %d test programs had errors", totalerrors);
|
||||
$stop;
|
||||
$stop; // if this is changed to $finish, wally-batch.do does not go to the next step to run coverage
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -352,6 +372,8 @@ module testbench;
|
||||
integer StartIndex;
|
||||
integer EndIndex;
|
||||
integer BaseIndex;
|
||||
integer memFile;
|
||||
integer readResult;
|
||||
if (P.SDC_SUPPORTED) begin
|
||||
always @(posedge clk) begin
|
||||
if (LoadMem) begin
|
||||
@ -373,7 +395,16 @@ module testbench;
|
||||
end else if (P.BUS_SUPPORTED) begin : bus_supported
|
||||
always @(posedge clk) begin
|
||||
if (LoadMem) begin
|
||||
$readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
||||
if (TEST == "buildroot") begin
|
||||
memFile = $fopen(bootmemfilename, "rb");
|
||||
readResult = $fread(dut.uncore.uncore.bootrom.bootrom.memory.ROM, memFile);
|
||||
$fclose(memFile);
|
||||
memFile = $fopen(memfilename, "rb");
|
||||
readResult = $fread(dut.uncore.uncore.ram.ram.memory.RAM, memFile);
|
||||
$fclose(memFile);
|
||||
end else
|
||||
$readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM);
|
||||
if (TEST == "embench") $display("Read memfile %s", memfilename);
|
||||
end
|
||||
if (CopyRAM) begin
|
||||
LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64
|
||||
@ -519,6 +550,175 @@ module testbench;
|
||||
|
||||
DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone));
|
||||
|
||||
if(P.ZICSR_SUPPORTED & INSTR_LIMIT != 0) begin
|
||||
logic [P.XLEN-1:0] Minstret;
|
||||
assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2];
|
||||
always @(negedge clk) begin
|
||||
if((Minstret != 0) && (Minstret % 'd100000 == 0)) $display("Reached %d instructions", Minstret);
|
||||
if((Minstret == INSTR_LIMIT) & (INSTR_LIMIT!=0)) begin $stop; $stop; end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ImperasDV Co-simulator hooks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`ifdef USE_IMPERAS_DV
|
||||
|
||||
rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi();
|
||||
wallyTracer #(P) wallyTracer(rvvi);
|
||||
|
||||
trace2log idv_trace2log(rvvi);
|
||||
// trace2cov idv_trace2cov(rvvi);
|
||||
|
||||
// enabling of comparison types
|
||||
trace2api #(.CMP_PC (1),
|
||||
.CMP_INS (1),
|
||||
.CMP_GPR (1),
|
||||
.CMP_FPR (1),
|
||||
.CMP_VR (0),
|
||||
.CMP_CSR (1)
|
||||
) idv_trace2api(rvvi);
|
||||
|
||||
initial begin
|
||||
int iter;
|
||||
#1;
|
||||
IDV_MAX_ERRORS = 3;
|
||||
|
||||
// Initialize REF (do this before initializing the DUT)
|
||||
if (!rvviVersionCheck(RVVI_API_VERSION)) begin
|
||||
$display($sformatf("%m @ t=%0t: Expecting RVVI API version %0d.", $time, RVVI_API_VERSION));
|
||||
$fatal;
|
||||
end
|
||||
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"));
|
||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56));
|
||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
|
||||
|
||||
if (!rvviRefInit("")) begin
|
||||
$display($sformatf("%m @ t=%0t: rvviRefInit failed", $time));
|
||||
$fatal;
|
||||
end
|
||||
|
||||
// Volatile CSRs
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC00)); // CYCLE
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB00)); // MCYCLE
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
||||
|
||||
// User HPMCOUNTER3 - HPMCOUNTER31
|
||||
for (iter='hC03; iter<='hC1F; iter++) begin
|
||||
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
|
||||
end
|
||||
|
||||
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
|
||||
for (iter='hB03; iter<='hB1F; iter++) begin
|
||||
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
|
||||
end
|
||||
|
||||
// cannot predict this register due to latency between
|
||||
// pending and taken
|
||||
void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP
|
||||
void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP
|
||||
|
||||
// Privileges for PMA are set in the imperas.ic
|
||||
// volatile (IO) regions are defined here
|
||||
// only real ROM/RAM areas are BOOTROM and UNCORE_RAM
|
||||
if (P.CLINT_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE)));
|
||||
end
|
||||
if (P.GPIO_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE)));
|
||||
end
|
||||
if (P.UART_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE)));
|
||||
end
|
||||
if (P.PLIC_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE)));
|
||||
end
|
||||
if (P.SDC_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE)));
|
||||
end
|
||||
if (P.SPI_SUPPORTED) begin
|
||||
void'(rvviRefMemorySetVolatile(P.SPI_BASE, (P.SPI_BASE + P.SPI_RANGE)));
|
||||
end
|
||||
|
||||
if(P.XLEN==32) begin
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH
|
||||
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
|
||||
end
|
||||
|
||||
void'(rvviRefCsrSetVolatile(0, 32'h104)); // SIE - Temporary!!!!
|
||||
|
||||
// Load memory
|
||||
// *** RT: This section can probably be moved into the same chunk of code which
|
||||
// loads the memories. However I'm not sure that ImperasDV supports reloading
|
||||
// the memories without relaunching the simulator.
|
||||
begin
|
||||
longint x64;
|
||||
int x32[2];
|
||||
longint index;
|
||||
string memfilenameImperasDV, bootmemfilenameImperasDV;
|
||||
|
||||
memfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/ram.bin"};
|
||||
bootmemfilenameImperasDV = {RISCV_DIR, "/linux-testvectors/bootmem.bin"};
|
||||
|
||||
$display("RVVI Loading bootmem.bin");
|
||||
memFile = $fopen(bootmemfilenameImperasDV, "rb");
|
||||
index = 'h1000 - 8;
|
||||
while(!$feof(memFile)) begin
|
||||
index+=8;
|
||||
readResult = $fread(x64, memFile);
|
||||
if (x64 == 0) continue;
|
||||
x32[0] = x64 & 'hffffffff;
|
||||
x32[1] = x64 >> 32;
|
||||
rvviRefMemoryWrite(0, index+0, x32[0], 4);
|
||||
rvviRefMemoryWrite(0, index+4, x32[1], 4);
|
||||
//$display("boot %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]);
|
||||
end
|
||||
$fclose(memFile);
|
||||
|
||||
$display("RVVI Loading ram.bin");
|
||||
memFile = $fopen(memfilenameImperasDV, "rb");
|
||||
index = 'h80000000 - 8;
|
||||
while(!$feof(memFile)) begin
|
||||
index+=8;
|
||||
readResult = $fread(x64, memFile);
|
||||
if (x64 == 0) continue;
|
||||
x32[0] = x64 & 'hffffffff;
|
||||
x32[1] = x64 >> 32;
|
||||
rvviRefMemoryWrite(0, index+0, x32[0], 4);
|
||||
rvviRefMemoryWrite(0, index+4, x32[1], 4);
|
||||
//$display("ram %08X x32[0]=%08X x32[1]=%08X", index, x32[0], x32[1]);
|
||||
end
|
||||
$fclose(memFile);
|
||||
|
||||
$display("RVVI Loading Complete");
|
||||
|
||||
void'(rvviRefPcSet(0, P.RESET_VECTOR)); // set BOOTROM address
|
||||
end
|
||||
end
|
||||
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
|
||||
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
|
||||
|
||||
final begin
|
||||
void'(rvviRefShutdown());
|
||||
end
|
||||
|
||||
`endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// END of ImperasDV Co-simulator hooks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
task automatic CheckSignature;
|
||||
// This task must be declared inside this module as it needs access to parameter P. There is
|
||||
// no way to pass P to the task unless we convert it to a module.
|
||||
@ -601,7 +801,7 @@ module testbench;
|
||||
errors = errors+1;
|
||||
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DTIM_SUPPORTED) = %h, signature = %h",
|
||||
TestName, i, (testadr+i)*(P.XLEN/8), testbench.DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]);
|
||||
$stop;
|
||||
$stop; // if this is changed to $finish, wally-batch.do does not get to the next step to run coverage
|
||||
end
|
||||
end
|
||||
if (errors) $display("%s failed with %d errors. :(", TestName, errors);
|
||||
|
@ -31,6 +31,7 @@
|
||||
`define EMBENCH "4"
|
||||
`define CUSTOM "5"
|
||||
`define COVERAGE "6"
|
||||
`define BUILDROOT "7"
|
||||
|
||||
string tvpaths[] = '{
|
||||
"$RISCV/imperas-riscv-tests/work/",
|
||||
@ -71,6 +72,11 @@ string tvpaths[] = '{
|
||||
"pmpadrdecs"
|
||||
};
|
||||
|
||||
string buildroot[] = '{
|
||||
`BUILDROOT,
|
||||
"buildroot"
|
||||
};
|
||||
|
||||
string coremark[] = '{
|
||||
`COREMARK,
|
||||
"coremark.bare.riscv"
|
||||
@ -1126,6 +1132,14 @@ string imperas32f[] = '{
|
||||
// "rv64i_m/F/src/fnmsub_b15-01.S"
|
||||
};
|
||||
|
||||
string arch64zfh_fma[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv64i_m/Zfh/src/fmadd_b15-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b15-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b15-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b15-01.S"
|
||||
};
|
||||
|
||||
string arch64f_divsqrt[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv64i_m/F/src/fdiv_b20-01.S",
|
||||
@ -1393,7 +1407,55 @@ string imperas32f[] = '{
|
||||
"rv64i_m/Zfh/src/fsub_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fsh-align-01.S"
|
||||
"rv64i_m/Zfh/src/fsh-align-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b14-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b16-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b17-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b18-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fmadd_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b14-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b16-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b17-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b18-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fmsub_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b14-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b16-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b17-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b18-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fnmadd_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b14-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b16-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b17-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b18-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fnmsub_b8-01.S"
|
||||
};
|
||||
|
||||
|
||||
@ -1975,7 +2037,55 @@ string arch64zbs[] = '{
|
||||
"rv32i_m/Zfh/src/fsub_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fsh-align-01.S"
|
||||
"rv32i_m/Zfh/src/fsh-align-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b14-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b16-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b17-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b18-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fmadd_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b14-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b16-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b17-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b18-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b14-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b16-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b17-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b18-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b14-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b16-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b17-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b18-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b8-01.S"
|
||||
};
|
||||
|
||||
string arch32zfaf[] = '{
|
||||
@ -2066,6 +2176,14 @@ string arch64zbs[] = '{
|
||||
"rv32i_m/D/src/fnmsub.d_b15-01.S"
|
||||
};
|
||||
|
||||
string arch32zfh_fma[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/Zfh/src/fmadd_b15-01.S",
|
||||
"rv32i_m/Zfh/src/fmsub_b15-01.S",
|
||||
"rv32i_m/Zfh/src/fnmadd_b15-01.S",
|
||||
"rv32i_m/Zfh/src/fnmsub_b15-01.S"
|
||||
};
|
||||
|
||||
string arch32d_divsqrt[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/D/src/fdiv.d_b1-01.S",
|
||||
@ -2472,7 +2590,12 @@ string arch64zbs[] = '{
|
||||
};
|
||||
|
||||
|
||||
string ahb[] = '{
|
||||
string ahb64[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv64i_m/F/src/fadd_b11-01.S"
|
||||
};
|
||||
|
||||
string ahb32[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/F/src/fadd_b11-01.S"
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ all: $(OBJECTS)
|
||||
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
|
||||
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \
|
||||
-nostartfiles -T../../examples/link/link.ld $<
|
||||
riscv64-unknown-elf-objdump -S $@ > $@.objdump
|
||||
riscv64-unknown-elf-objdump -S -D $@ > $@.objdump
|
||||
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile
|
||||
extractFunctionRadix.sh $@.objdump
|
||||
|
||||
|
@ -37,6 +37,26 @@ main:
|
||||
flw ft0, 0(t0)
|
||||
fclass.s t1, ft0
|
||||
|
||||
# zfa instructions (because Zfa tests aren't running yet)
|
||||
fli.d fs0, 16
|
||||
fcvtmod.w.d t0, fs0, rtz
|
||||
# fminm.d fs1, fs0, fs0
|
||||
# fmaxm.d fs1, fs0, fs0
|
||||
# fltq.d t0, fs1, ft0
|
||||
# fleq.d t0, fs1, ft0
|
||||
fcvt.d.q fs1, fs0
|
||||
fcvt.h.q fs1, fs0
|
||||
fcvt.s.q fs1, fs0
|
||||
# round for now because these tests are excluded from Zfa until rounding is implemented
|
||||
fround.s fs1, fs0
|
||||
froundnx.s fs1, fs0
|
||||
fround.d fs1, fs0
|
||||
froundnx.d fs1, fs0
|
||||
fround.h fs1, fs0
|
||||
froundnx.h fs1, fs0
|
||||
fround.s fs1, fs0
|
||||
froundnx.s fs1, fs0
|
||||
|
||||
#Result Sign Test Coverage
|
||||
la t0, TestData2
|
||||
flw ft0, 0(t0)
|
||||
@ -109,6 +129,12 @@ main:
|
||||
# fcvt.w.q a0, ft0
|
||||
# fcvt.q.d ft3, ft0
|
||||
|
||||
# half-precision NaN boxing
|
||||
la t0, TestData3
|
||||
fld ft2, 0(t0) // bad NaN-boxed number
|
||||
fmadd.h ft1, ft2, ft2, ft2 // Test NaN boxing
|
||||
fmadd.s ft1, ft2, ft2, ft2 // Test NaN boxing
|
||||
|
||||
// fdivsqrt: test busy->idle transition caused by a FlushE while divider is busy (when interrupt arrives)
|
||||
// This code doesn't actually trigger a busy->idle transition because the pending timer interrupt doesn't occur until the division finishes.
|
||||
li t0, 0x3F812345 # random value slightly bigger than 1
|
||||
@ -159,6 +185,10 @@ main:
|
||||
.word 0xD5F00053 // illegal fcvt.h.* (bad Rs2D)
|
||||
.word 0xC5F00053 // illegal fcvt.*.h (bad Rs2D)
|
||||
.word 0x04000043 // illegal fmadd.h (h not supported)
|
||||
.word 0xC2800053 // illegal fcvtmod.w.d with rm rne
|
||||
.word 0xF0101053 // illegal fli with Funct3D not 0
|
||||
.word 0xF0400053 // illegal fli with Rs2D not 1
|
||||
.word 0x44200053 // illegal instruction for f.cvt.h.h
|
||||
|
||||
// Test divide by zero with rounding mode toward zero
|
||||
li t0, 1
|
||||
@ -206,4 +236,6 @@ TestData2:
|
||||
.int 0xbf800000 #FP -1.0
|
||||
.int 0x7fa00000 #SNaN
|
||||
.int 0x3fffffff #OverFlow Test
|
||||
TestData3:
|
||||
.dword 0xABCD543212345678 # NaN box test
|
||||
DivTestData:
|
||||
|
@ -4,7 +4,8 @@
|
||||
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||
// nlimpert@hmc.edu
|
||||
//
|
||||
// Purpose: Test coverage for LSU
|
||||
// Purpose: Test coverage for IFU TLB camlines with mismatched ASID values. This file tests odd
|
||||
// numbered camlines. tlbASID2.S covers even numbered tlb camlines. These two files are identical.
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
@ -25,6 +26,8 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
// load code to initalize stack, handle interrupts, terminate
|
||||
|
||||
#include "WALLY-init-lib.h"
|
||||
@ -43,11 +46,12 @@ main:
|
||||
|
||||
li t0, 0xC0000000
|
||||
|
||||
li t2, 0 # i = 0
|
||||
li t2, 0 # i = 0
|
||||
li t5, 0 # j = 0 // now use as a counter for new asid loop
|
||||
li t3, 32 # Max amount of Loops = 32
|
||||
li t3, 32 # Max amount of Loops = 32
|
||||
|
||||
loop: bge t2, t3, finished # exit loop if i >= loops
|
||||
sfence.vma
|
||||
li t1, 0x00008067 #load in jalr
|
||||
sw t1, 0(t0)
|
||||
fence.I
|
||||
@ -55,7 +59,7 @@ loop: bge t2, t3, finished # exit loop if i >= loops
|
||||
li t5, 0x9001000000080080 // try making asid = 1
|
||||
csrw satp, t5
|
||||
jalr t0
|
||||
li t5, 0x9000000000080080 // try making asid = 0
|
||||
li t5, 0x9000000000080080 // try making asid = 0
|
||||
csrw satp, t5
|
||||
li t4, 0x1000
|
||||
add t0, t0, t4
|
||||
@ -71,7 +75,7 @@ finished:
|
||||
pagetable:
|
||||
.8byte 0x200204C1
|
||||
|
||||
.align 12 // level 2 page table, contains direction to a gigapageg
|
||||
.align 12 // level 2 page table, contains direction to a gigapage
|
||||
.8byte 0x0
|
||||
.8byte 0x0
|
||||
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
|
||||
|
@ -55,14 +55,24 @@ main:
|
||||
li t4, 0x1000 # address step size
|
||||
li a2, 0x80216000 # Test NAPOT pages
|
||||
jal a1, looptest
|
||||
|
||||
sfence.vma
|
||||
li t4, 0x200000 # address step size
|
||||
li a2, 0x80215240 # Test NAPOT pages
|
||||
jal a1, looptest
|
||||
li a2, 0xC0215240 # Test ill-formed NAPOT pages
|
||||
jal a1, looptest
|
||||
li a2, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT
|
||||
jal a1, looptest
|
||||
|
||||
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
|
||||
ecall
|
||||
j done
|
||||
|
||||
looptest:
|
||||
mv t0, a2 # base address
|
||||
li t2, 0 # i = 0
|
||||
li t3, 35 # Max amount of Loops = 34
|
||||
li t2, 0 # i = 0
|
||||
li t3, 32 # Max amount of Loops = 32
|
||||
li t5, 0x8082 # return instruction opcode
|
||||
|
||||
loop: bge t2, t3, finished # exit loop if i >= loops
|
||||
|
@ -96,6 +96,49 @@ main:
|
||||
sw t1, 0(t0) # write to page
|
||||
jalr ra, t0 # jump to page
|
||||
|
||||
# AMO at page has PBMT = 2 or 1 (uncached)
|
||||
li t0, 0x80401000
|
||||
li t1, 10
|
||||
amoadd.w t1, t1, (t0)
|
||||
|
||||
la t2, SpecialPage
|
||||
li t0, 0x200000000 # an address to a specific 1 GiB page
|
||||
j ConcurrentICacheMissDTLBMiss
|
||||
|
||||
.align 6
|
||||
ConcurrentICacheMissDTLBMiss:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
lw t1, 0(t0)
|
||||
|
||||
# write a cacheline length (512 bits) to memory in uncached region
|
||||
li t0, 0x80401000
|
||||
cbo.zero (t0)
|
||||
|
||||
# Nonleaf PTE has PBMT != 0 causes a page fault during page walking. H
|
||||
li t0, 0x80600000
|
||||
lw t1, 0(t0) # read from page
|
||||
@ -163,6 +206,10 @@ main:
|
||||
# change back to default trap handler after checking everything that might cause an instruction page fault
|
||||
jal changetodefaulthandler
|
||||
|
||||
# uncachable AMO access
|
||||
li t0, 0x80401000 # PBMT sets as uncachable
|
||||
amoadd.w t0, t0, 0(t0)
|
||||
|
||||
# exercise CBOM instructions with various permissions
|
||||
li t0, 0x80800000
|
||||
cbo.zero (t0)
|
||||
@ -294,6 +341,12 @@ pagetable:
|
||||
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000
|
||||
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
|
||||
.8byte 0x00000000000000C1 # gigapage at VA 0xC0000000 causes access fault
|
||||
.8byte 0x0
|
||||
.8byte 0x0
|
||||
.8byte 0x0
|
||||
.8byte 0x0
|
||||
SpecialPage:
|
||||
.8byte 0x00000000200000CF # 0x2_0000_0000 1GiB page1
|
||||
|
||||
|
||||
# Next page table at 0x80012000 for gigapage at 0x80000000
|
||||
@ -408,7 +461,8 @@ pagetable:
|
||||
# Leaf page table at 0x80014000 with PBMT pages
|
||||
.align 12
|
||||
#80400000
|
||||
.8byte 0x60000000200020CF # reserved entry
|
||||
.8byte 0x60000000200020CF # reserved entry VA 80400000
|
||||
.8byte 0x40000000201000CF # non-cache non-idempotent VA 80401000
|
||||
|
||||
# Leaf page table at 0x80015000 with various permissions for testing CBOM and CBOZ
|
||||
.align 12
|
||||
|
Loading…
Reference in New Issue
Block a user