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
|
Terminal on Mac, cmd on Windows, xterm on Linux
|
||||||
See A.1 about ssh -Y login from a terminal
|
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
|
If you don't already have a Github account, create one
|
||||||
In a web browser, visit https://github.com/openhwgroup/cvw
|
In a web browser, visit https://github.com/openhwgroup/cvw
|
||||||
In the upper right part of the screen, click on Fork
|
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
|
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.
|
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
|
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
|
||||||
$ cd cvw
|
$ cd cvw
|
||||||
$ git remote add upstream https://github.com/openhwgroup/cvw
|
$ git remote add upstream https://github.com/openhwgroup/cvw
|
||||||
|
@ -33,13 +33,14 @@
|
|||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
import os;
|
import os;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
my $curderiv = "";
|
my $curderiv = "";
|
||||||
my @derivlist = ();
|
my @derivlist = ();
|
||||||
my %derivs;
|
my %derivs;
|
||||||
my %basederiv;
|
my %basederiv;
|
||||||
|
my @derivnames = ();
|
||||||
|
|
||||||
if ($#ARGV != -1) {
|
if ($#ARGV != -1) {
|
||||||
die("Usage: $0")
|
die("Usage: $0")
|
||||||
@ -69,13 +70,20 @@ foreach my $line (<$fh>) {
|
|||||||
}
|
}
|
||||||
&terminateDeriv();
|
&terminateDeriv();
|
||||||
close($fh);
|
close($fh);
|
||||||
foreach my $key (keys %derivs) {
|
#foreach my $key (keys %derivs) {
|
||||||
|
foreach my $key (@derivnames) {
|
||||||
my $dir = "$ENV{WALLY}/config/deriv/$key";
|
my $dir = "$ENV{WALLY}/config/deriv/$key";
|
||||||
system("rm -rf $dir");
|
system("rm -rf $dir");
|
||||||
system("mkdir -p $dir");
|
system("mkdir -p $dir");
|
||||||
my $configunmod = "$dir/config_unmod.vh";
|
my $configunmod = "$dir/config_unmod.vh";
|
||||||
my $config = "$dir/config.vh";
|
my $config = "$dir/config.vh";
|
||||||
my $base = "$ENV{WALLY}/config/$basederiv{$key}/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");
|
system("cp $base $configunmod");
|
||||||
open(my $unmod, $configunmod) or die "Could not open file '$configunmod' $!";
|
open(my $unmod, $configunmod) or die "Could not open file '$configunmod' $!";
|
||||||
open(my $fh, '>>', $config) or die "Could not open file '$config' $!";
|
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
|
if ($curderiv ne "") { # close out the previous derivative
|
||||||
my @dl = @derivlist;
|
my @dl = @derivlist;
|
||||||
$derivs{$curderiv} = \@dl;
|
$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_RANGE 64'h0FFFFFFF
|
||||||
UNCORE_RAM_PRELOAD 1
|
UNCORE_RAM_PRELOAD 1
|
||||||
GPIO_LOOPBACK_TEST 0
|
GPIO_LOOPBACK_TEST 0
|
||||||
SPI_LOOPBACK_TEST 0
|
SPI_LOOPBACK_TEST 0
|
||||||
UART_PRESCALE 0
|
UART_PRESCALE 32'd0
|
||||||
PLIC_NUM_SRC 32'd53
|
PLIC_NUM_SRC 32'd53
|
||||||
|
|
||||||
# fpga is used for FPGA hardware. It adds the SDC and DDR (EXT_MEM)
|
# fpga is used for FPGA hardware. It adds the SDC and DDR (EXT_MEM)
|
||||||
deriv fpga rv64gc buildroot
|
deriv fpga buildroot
|
||||||
BOOTROM_PRELOAD 1
|
BOOTROM_PRELOAD 1
|
||||||
UNCORE_RAM_BASE 64'h2000
|
UNCORE_RAM_BASE 64'h2000
|
||||||
UNCORE_RAM_RANGE 64'hFFF
|
UNCORE_RAM_RANGE 64'hFFF
|
||||||
@ -71,7 +71,7 @@ BTB_SIZE 32'd5
|
|||||||
# The other syn configurations have the same trimming
|
# The other syn configurations have the same trimming
|
||||||
deriv syn_rv32i rv32i syn_rv32e
|
deriv syn_rv32i rv32i syn_rv32e
|
||||||
deriv syn_rv32imc rv32imc 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_rv64i rv64i syn_rv32e
|
||||||
deriv syn_rv64gc rv64gc syn_rv32e
|
deriv syn_rv64gc rv64gc syn_rv32e
|
||||||
|
|
||||||
@ -84,34 +84,34 @@ USE_SRAM 1
|
|||||||
# The other syn configurations have the same trimming
|
# The other syn configurations have the same trimming
|
||||||
deriv syn_sram_rv32i rv32i syn_sram_rv32e
|
deriv syn_sram_rv32i rv32i syn_sram_rv32e
|
||||||
deriv syn_sram_rv32imc rv32imc 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_rv64i rv64i syn_sram_rv32e
|
||||||
deriv syn_sram_rv64gc rv64gc syn_sram_rv32e
|
deriv syn_sram_rv64gc rv64gc syn_sram_rv32e
|
||||||
|
|
||||||
# The following syn configurations gradually turn off features
|
# 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
|
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
|
PMP_ENTRIES 32'd0
|
||||||
|
|
||||||
deriv syn_noPriv_rv64gc rv64gc syn_pmp0_rv64gc
|
deriv syn_noPriv_rv64gc syn_pmp0_rv64gc
|
||||||
ZICSR_SUPPORTED 0
|
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
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
MISA (32'h00000104 | 1 << 18 | 1 << 20)
|
||||||
|
|
||||||
# Divider variants to check logical correctness
|
# Divider variants to check logical correctness
|
||||||
@ -119,85 +119,98 @@ MISA (32'h00000104 | 1 << 18 | 1 << 20)
|
|||||||
deriv div_2_1_rv32gc rv32gc
|
deriv div_2_1_rv32gc rv32gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd1
|
DIVCOPIES 32'd1
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_2_2_rv32gc rv32gc
|
deriv div_2_2_rv32gc rv32gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd2
|
DIVCOPIES 32'd2
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_2_4_rv32gc rv32gc
|
deriv div_2_4_rv32gc rv32gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd4
|
DIVCOPIES 32'd4
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_1_rv32gc rv32gc
|
deriv div_4_1_rv32gc rv32gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
DIVCOPIES 32'd1
|
DIVCOPIES 32'd1
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_2_rv32gc rv32gc
|
deriv div_4_2_rv32gc rv32gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
|
IDIV_ON_FPU 0
|
||||||
DIVCOPIES 32'd2
|
DIVCOPIES 32'd2
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_4_rv32gc rv32gc
|
deriv div_4_4_rv32gc rv32gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
DIVCOPIES 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
|
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
|
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
|
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
|
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
|
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
|
IDIV_ON_FPU 1
|
||||||
|
|
||||||
deriv div_2_1_rv64gc rv64gc
|
deriv div_2_1_rv64gc rv64gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd1
|
DIVCOPIES 32'd1
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_2_2_rv64gc rv64gc
|
deriv div_2_2_rv64gc rv64gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd2
|
DIVCOPIES 32'd2
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_2_4_rv64gc rv64gc
|
deriv div_2_4_rv64gc rv64gc
|
||||||
RADIX 32'd2
|
RADIX 32'd2
|
||||||
DIVCOPIES 32'd4
|
DIVCOPIES 32'd4
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_1_rv64gc rv64gc
|
deriv div_4_1_rv64gc rv64gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
DIVCOPIES 32'd1
|
DIVCOPIES 32'd1
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_2_rv64gc rv64gc
|
deriv div_4_2_rv64gc rv64gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
DIVCOPIES 32'd2
|
DIVCOPIES 32'd2
|
||||||
|
IDIV_ON_FPU 0
|
||||||
|
|
||||||
deriv div_4_4_rv64gc rv64gc
|
deriv div_4_4_rv64gc rv64gc
|
||||||
RADIX 32'd4
|
RADIX 32'd4
|
||||||
DIVCOPIES 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
|
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
|
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
|
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
|
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
|
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
|
IDIV_ON_FPU 1
|
||||||
|
|
||||||
# RAM latency and Burst mode for bus stress testing
|
# 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
|
deriv bpred_GSHARE_16_16_10_1_rv32gc rv32gc
|
||||||
BPRED_SIZE 32'd16
|
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
|
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
|
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
|
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
|
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
|
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
|
BPRED_TYPE `BP_TWOBIT
|
||||||
|
|
||||||
deriv bpred_GSHARE_10_2_10_1_rv32gc rv32gc
|
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
|
deriv bpred_GSHARE_10_6_10_1_rv32gc rv32gc
|
||||||
RAS_SIZE 32'd6
|
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
|
RAS_SIZE 32'd10
|
||||||
|
|
||||||
deriv bpred_GSHARE_10_16_10_1_rv32gc rv32gc
|
deriv bpred_GSHARE_10_16_10_1_rv32gc rv32gc
|
||||||
RAS_SIZE 32'd16
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
INSTR_CLASS_PRED 0
|
||||||
|
|
||||||
# Cache configurations
|
# Cache configurations
|
||||||
|
|
||||||
deriv noicache_rv32gc rv32gc
|
deriv noicache_rv32gc rv32gc
|
||||||
ICACHE_SUPPORTED 0
|
ICACHE_SUPPORTED 0
|
||||||
|
VIRTMEM_SUPPORTED 0
|
||||||
|
|
||||||
deriv nodcache_rv32gc rv32gc
|
deriv nodcache_rv32gc rv32gc
|
||||||
DCACHE_SUPPORTED 0
|
DCACHE_SUPPORTED 0
|
||||||
@ -374,6 +391,31 @@ deriv nocache_rv32gc rv32gc
|
|||||||
ICACHE_SUPPORTED 0
|
ICACHE_SUPPORTED 0
|
||||||
DCACHE_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
|
deriv way_1_4096_512_rv32gc rv32gc
|
||||||
DCACHE_NUMWAYS 32'd1
|
DCACHE_NUMWAYS 32'd1
|
||||||
DCACHE_WAYSIZEINBYTES 32'd4096
|
DCACHE_WAYSIZEINBYTES 32'd4096
|
||||||
@ -382,40 +424,26 @@ ICACHE_NUMWAYS 32'd1
|
|||||||
ICACHE_WAYSIZEINBYTES 32'd4096
|
ICACHE_WAYSIZEINBYTES 32'd4096
|
||||||
ICACHE_LINELENINBITS 32'd512
|
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
|
DCACHE_NUMWAYS 32'd1
|
||||||
ICACHE_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
|
DCACHE_NUMWAYS 32'd4
|
||||||
ICACHE_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
|
DCACHE_NUMWAYS 32'd8
|
||||||
ICACHE_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
|
DCACHE_WAYSIZEINBYTES 32'd2048
|
||||||
ICACHE_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
|
DCACHE_LINELENINBITS 32'd256
|
||||||
ICACHE_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
|
deriv way_1_4096_512_rv64gc rv64gc
|
||||||
DCACHE_NUMWAYS 32'd1
|
DCACHE_NUMWAYS 32'd1
|
||||||
DCACHE_WAYSIZEINBYTES 32'd4096
|
DCACHE_WAYSIZEINBYTES 32'd4096
|
||||||
@ -424,27 +452,27 @@ ICACHE_NUMWAYS 32'd1
|
|||||||
ICACHE_WAYSIZEINBYTES 32'd4096
|
ICACHE_WAYSIZEINBYTES 32'd4096
|
||||||
ICACHE_LINELENINBITS 32'd512
|
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
|
DCACHE_NUMWAYS 32'd1
|
||||||
ICACHE_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
|
DCACHE_NUMWAYS 32'd4
|
||||||
ICACHE_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
|
DCACHE_NUMWAYS 32'd8
|
||||||
ICACHE_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
|
DCACHE_WAYSIZEINBYTES 32'd2048
|
||||||
ICACHE_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
|
DCACHE_LINELENINBITS 32'd256
|
||||||
ICACHE_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
|
DCACHE_LINELENINBITS 32'd1024
|
||||||
ICACHE_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)
|
MISA (32'h00000104 | 1 << 5 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||||
ZFH_SUPPORTED 1
|
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
|
deriv fdh_rv32gc rv32gc
|
||||||
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0)
|
||||||
ZFH_SUPPORTED 1
|
ZFH_SUPPORTED 1
|
||||||
@ -524,32 +556,35 @@ ZFH_SUPPORTED 1
|
|||||||
|
|
||||||
# IEEE compatible variants for TestFloat
|
# IEEE compatible variants for TestFloat
|
||||||
|
|
||||||
deriv f_ieee_rv32gc rv32gc f_rv32gc
|
deriv f_ieee_rv32gc f_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fh_ieee_v32gc rv32gc fh_rv32gc
|
deriv fh_ieee_rv32gc fh_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fdh_ieee_rv32gc rv32gc fdh_rv32gc
|
deriv fd_ieee_rv32gc fd_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fdq_ieee_rv32gc rv32gc fdq_rv32gc
|
deriv fdh_ieee_rv32gc fdh_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fdqh_ieee_rv32gc rv32gc fdqh_rv32gc
|
deriv fdq_ieee_rv32gc fdq_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv f_ieee_rv64gc rv64gc f_rv64gc
|
deriv fdqh_ieee_rv32gc fdqh_rv32gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fh_ieee_rv64gc rv64gc fh_rv64gc
|
deriv f_ieee_rv64gc f_rv64gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fd_ieee_rv64gc rv64gc fd_rv64gc
|
deriv fh_ieee_rv64gc fh_rv64gc
|
||||||
IEEE754 1
|
IEEE754 1
|
||||||
|
|
||||||
deriv fdq_ieee_rv64gc rv64gc fdq_rv64gc
|
deriv fd_ieee_rv64gc fd_rv64gc
|
||||||
IEEE754 1
|
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
|
IEEE754 1
|
||||||
|
@ -154,22 +154,11 @@ localparam PLIC_SPI_ID = 32'd6;
|
|||||||
localparam PLIC_SDC_ID = 32'd9;
|
localparam PLIC_SDC_ID = 32'd9;
|
||||||
|
|
||||||
localparam BPRED_SUPPORTED = 1;
|
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_TYPE = `BP_GSHARE; // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT
|
||||||
localparam BPRED_SIZE = 32'd10;
|
localparam BPRED_SIZE = 32'd10;
|
||||||
`endif
|
|
||||||
localparam BPRED_NUM_LHR = 32'd6;
|
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 BTB_SIZE = 32'd10;
|
||||||
localparam RAS_SIZE = 32'd16;
|
localparam RAS_SIZE = 32'd16;
|
||||||
`endif
|
|
||||||
localparam INSTR_CLASS_PRED = 1;
|
localparam INSTR_CLASS_PRED = 1;
|
||||||
|
|
||||||
localparam SVADU_SUPPORTED = 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 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 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 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
|
// largest length in IEU/FPU
|
||||||
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
|
localparam CVTLEN = ((NF<XLEN) ? (XLEN) : (NF)); // max(XLEN, NF)
|
||||||
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
|
localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($unsigned(FLEN)));
|
||||||
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
|
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 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
|
// Disable spurious Verilator warnings
|
||||||
|
@ -48,29 +48,14 @@ IP_Arty: $(dst)/xlnx_proc_sys_reset.log \
|
|||||||
|
|
||||||
|
|
||||||
PreProcessFiles:
|
PreProcessFiles:
|
||||||
|
$(MAKE) -C ../../sim deriv
|
||||||
rm -rf ../src/CopiedFiles_do_not_add_to_repo/
|
rm -rf ../src/CopiedFiles_do_not_add_to_repo/
|
||||||
cp -r ../../src/ ../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/
|
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
|
./insert_debug_comment.sh
|
||||||
# modify config *** RT: eventually setup for variably defined sized memory
|
# 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/EXT_MEM_RANGE.*/EXT_MEM_RANGE = 64'h0FFFFFFF;/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
|
|
||||||
# This line allows the Bootloader to be loaded in a Block RAM on the FPGA
|
# 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
|
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
|
exit 1
|
||||||
fi
|
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 no images directory, images have not been built
|
||||||
if [ ! -d $IMAGES ] ; then
|
if [ ! -d $IMAGES ] ; then
|
||||||
echo -e "$ERRORTEXT Buildroot images directory does not exist"
|
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"
|
DD_FLAGS="bs=4k iflag=fullblock oflag=direct conv=fsync status=progress"
|
||||||
|
|
||||||
echo -e "$NAME Copying device tree"
|
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"
|
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"
|
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 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
|
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;
|
# *** Build old tests/imperas-riscv-tests for now;
|
||||||
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
|
# 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
|
# DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired
|
||||||
@ -54,7 +54,7 @@ riscoftests:
|
|||||||
wallyriscoftests:
|
wallyriscoftests:
|
||||||
# Builds riscv-arch-test 64 and 32-bit versions and builds wally-riscv-arch-test 64 and 32-bit versions
|
# 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
|
make -C ../tests/riscof/ wally-riscv-arch-test
|
||||||
|
|
||||||
memfiles:
|
memfiles:
|
||||||
make -f makefile-memfile wally-sim-files --jobs
|
make -f makefile-memfile wally-sim-files --jobs
|
||||||
|
|
||||||
@ -63,4 +63,10 @@ coveragetests:
|
|||||||
|
|
||||||
deriv:
|
deriv:
|
||||||
derivgen.pl
|
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/bpred_GSHARE_6_16_10_0_rv32gc_embench.log gshare 6
|
||||||
../logs/rv32gc_gshare8.log gshare 8
|
../logs/bpred_GSHARE_8_16_10_0_rv32gc_embench.log gshare 8
|
||||||
../logs/rv32gc_gshare10.log gshare 10
|
../logs/bpred_GSHARE_10_16_10_0_rv32gc_embench.log gshare 10
|
||||||
../logs/rv32gc_gshare12.log gshare 12
|
../logs/bpred_GSHARE_12_16_10_0_rv32gc_embench.log gshare 12
|
||||||
../logs/rv32gc_gshare14.log gshare 14
|
../logs/bpred_GSHARE_14_16_10_0_rv32gc_embench.log gshare 14
|
||||||
../logs/rv32gc_gshare16.log gshare 16
|
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log gshare 16
|
||||||
../logs/rv32gc_twobit6.log twobit 6
|
../logs/bpred_TWOBIT_6_16_10_0_rv32gc_embench.log twobit 6
|
||||||
../logs/rv32gc_twobit8.log twobit 8
|
../logs/bpred_TWOBIT_8_16_10_0_rv32gc_embench.log twobit 8
|
||||||
../logs/rv32gc_twobit10.log twobit 10
|
../logs/bpred_TWOBIT_10_16_10_0_rv32gc_embench.log twobit 10
|
||||||
../logs/rv32gc_twobit12.log twobit 12
|
../logs/bpred_TWOBIT_12_16_10_0_rv32gc_embench.log twobit 12
|
||||||
../logs/rv32gc_twobit14.log twobit 14
|
../logs/bpred_TWOBIT_14_16_10_0_rv32gc_embench.log twobit 14
|
||||||
../logs/rv32gc_twobit16.log twobit 16
|
../logs/bpred_TWOBIT_16_16_10_0_rv32gc_embench.log twobit 16
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
../logs/rv32gc_BTB6.log btb 6
|
../logs/bpred_GSHARE_16_16_6_0_rv32gc_embench.log btb 6
|
||||||
../logs/rv32gc_BTB8.log btb 8
|
../logs/bpred_GSHARE_16_16_8_0_rv32gc_embench.log btb 8
|
||||||
../logs/rv32gc_BTB10.log btb 10
|
../logs/bpred_GSHARE_16_16_10_0_rv32gc_embench.log btb 10
|
||||||
../logs/rv32gc_BTB12.log btb 12
|
../logs/bpred_GSHARE_16_16_12_0_rv32gc_embench.log btb 12
|
||||||
../logs/rv32gc_BTB14.log btb 14
|
../logs/bpred_GSHARE_16_16_14_0_rv32gc_embench.log btb 14
|
||||||
../logs/rv32gc_BTB16.log btb 16
|
../logs/bpred_GSHARE_16_16_16_0_rv32gc_embench.log btb 16
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
../logs/rv32gc_class6.log class 6
|
../logs/bpred_GSHARE_16_16_6_1_rv32gc_embench.log btb 6
|
||||||
../logs/rv32gc_class8.log class 8
|
../logs/bpred_GSHARE_16_16_8_1_rv32gc_embench.log btb 8
|
||||||
../logs/rv32gc_class10.log class 10
|
../logs/bpred_GSHARE_16_16_10_1_rv32gc_embench.log btb 10
|
||||||
../logs/rv32gc_class12.log class 12
|
../logs/bpred_GSHARE_16_16_12_1_rv32gc_embench.log btb 12
|
||||||
../logs/rv32gc_class14.log class 14
|
../logs/bpred_GSHARE_16_16_14_1_rv32gc_embench.log btb 14
|
||||||
../logs/rv32gc_class16.log class 16
|
../logs/bpred_GSHARE_16_16_16_1_rv32gc_embench.log btb 16
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
../logs/rv32gc_RAS3.log ras 3
|
../logs/bpred_GSHARE_10_3_10_0_rv32gc_embench.log ras 3
|
||||||
../logs/rv32gc_RAS4.log ras 4
|
../logs/bpred_GSHARE_10_4_10_0_rv32gc_embench.log ras 4
|
||||||
../logs/rv32gc_RAS6.log ras 6
|
../logs/bpred_GSHARE_10_6_10_0_rv32gc_embench.log ras 6
|
||||||
../logs/rv32gc_RAS10.log ras 10
|
../logs/bpred_GSHARE_10_10_10_0_rv32gc_embench.log ras 10
|
||||||
../logs/rv32gc_RAS16.log ras 16
|
../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)
|
# 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.
|
# 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 -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.
|
# 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
|
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
|
# 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 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
|
# exclude the unreachable logic
|
||||||
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
|
set start [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-start: icache case"]
|
||||||
set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: 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 $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 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 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
|
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
|
# 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/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
|
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$
|
# 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
|
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.
|
## D$ Exclusions.
|
||||||
# InvalidateCache is I$ only:
|
# 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.
|
# 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 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
|
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
|
# 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
|
# 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/ddr4dec
|
||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec
|
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"]
|
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/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
|
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
|
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
|
# 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/bootromdec
|
||||||
# coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec
|
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
|
# The following peripherals are always supported
|
||||||
# coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec
|
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
|
#Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0
|
||||||
set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
|
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
|
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"]
|
# 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/dtimdec
|
||||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec
|
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/ddr4dec
|
||||||
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec
|
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
|
# 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
|
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"]
|
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
|
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"]
|
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
|
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"]
|
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\\("]
|
set line [GetLineNum ../src/ebu/ebufsmarb.sv "FinalBeatReg\\("]
|
||||||
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1
|
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
|
# 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
|
# This is a blunt instrument; perhaps there is a more graceful exclusion
|
||||||
coverage exclude -srcfile priorityonehot.sv
|
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/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
|
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
|
# EBU
|
||||||
####################
|
####################
|
||||||
|
@ -6,26 +6,43 @@ export PATH=$PATH:/usr/local/bin/
|
|||||||
verilator=`which verilator`
|
verilator=`which verilator`
|
||||||
|
|
||||||
basepath=$(dirname $0)/..
|
basepath=$(dirname $0)/..
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
fails=0
|
||||||
|
|
||||||
if [ "$1" == "-nightly" ]; then
|
if [ "$1" == "-nightly" ]; then
|
||||||
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
|
configs=(rv32e rv64gc rv32gc rv32imc rv32i rv64i) # fdqh_rv64gc
|
||||||
derivconfigs=`ls $WALLY/config/deriv`
|
derivconfigs=`ls $WALLY/config/deriv`
|
||||||
for entry in $derivconfigs
|
for entry in $derivconfigs
|
||||||
do
|
do
|
||||||
configs[${#configs[@]}]=$entry
|
if [[ $entry != *"syn_sram"* ]]; then # ignore syn_sram* configs that contain undefined module
|
||||||
|
configs[${#configs[@]}]=$entry
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
else
|
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
|
fi
|
||||||
|
|
||||||
for config in ${configs[@]}; do
|
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
|
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"
|
if [ "$1" == "-nightly" ]; then
|
||||||
exit 1
|
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
|
fi
|
||||||
done
|
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
|
# --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
|
# -I points to the include directory where files such as `include config.vh are found
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#
|
#
|
||||||
##################################
|
##################################
|
||||||
import sys,os,shutil
|
import sys,os,shutil
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class bcolors:
|
class bcolors:
|
||||||
HEADER = '\033[95m'
|
HEADER = '\033[95m'
|
||||||
@ -51,7 +54,7 @@ else:
|
|||||||
name="lints",
|
name="lints",
|
||||||
variant="all",
|
variant="all",
|
||||||
cmd="./lint-wally " + nightMode + " | tee {}",
|
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!"
|
BRcmd="vsim > {} -c <<!\ndo wally-batch.do buildroot buildroot $RISCV "+str(INSTR_LIMIT)+" 1 0 -coverage\n!"
|
||||||
else:
|
else:
|
||||||
print( "buildroot no coverage")
|
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"
|
BRgrepstr=str(INSTR_LIMIT)+" instructions"
|
||||||
return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
|
return TestCase(name,variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
|
||||||
|
|
||||||
@ -85,7 +88,7 @@ for test in tests64i:
|
|||||||
configs.append(tc)
|
configs.append(tc)
|
||||||
|
|
||||||
tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused
|
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"]
|
#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:
|
for test in tests32gc:
|
||||||
tc = TestCase(
|
tc = TestCase(
|
||||||
@ -124,16 +127,7 @@ for test in tests32e:
|
|||||||
grepstr="All tests ran without failures")
|
grepstr="All tests ran without failures")
|
||||||
configs.append(tc)
|
configs.append(tc)
|
||||||
|
|
||||||
ahbTests = [("0", "0"), ("0", "1"), ("1", "0"), ("1", "1"), ("2", "0"), ("2", "1")]
|
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64f_divsqrt", "arch64d_divsqrt", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", "arch64zfh", "arch64zfh_divsqrt", "arch64zfh_fma", "arch64zfaf", "arch64zfad",
|
||||||
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",
|
|
||||||
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "arch64zicond", "wally64a", "wally64periph", "wally64priv"] # add arch64zfh_fma when available; arch64zicobz, arch64zcb when working
|
"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",
|
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
||||||
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
|
# "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 = []
|
configs = []
|
||||||
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
|
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
|
||||||
"arch64zifencei", "arch64zicond", "arch64a", "wally64a", "wally64periph", "wally64priv",
|
"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):
|
if (fp):
|
||||||
tests64gc.append("arch64f")
|
tests64gc.append("arch64f")
|
||||||
tests64gc.append("arch64d")
|
tests64gc.append("arch64d")
|
||||||
tests64gc.append("arch64zfh")
|
tests64gc.append("arch64zfh")
|
||||||
tests64gc.append("arch64f_fma")
|
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("arch64f_divsqrt")
|
||||||
tests64gc.append("arch64d_divsqrt")
|
tests64gc.append("arch64d_divsqrt")
|
||||||
tests64gc.append("arch64zfh_divsqrt")
|
tests64gc.append("arch64zfh_divsqrt")
|
||||||
@ -176,7 +171,6 @@ if (nightly):
|
|||||||
["way_8_4096_512_rv32gc", ["arch32i"]],
|
["way_8_4096_512_rv32gc", ["arch32i"]],
|
||||||
["way_4_2048_512_rv32gc", ["arch32i"]],
|
["way_4_2048_512_rv32gc", ["arch32i"]],
|
||||||
["way_4_4096_256_rv32gc", ["arch32i"]],
|
["way_4_4096_256_rv32gc", ["arch32i"]],
|
||||||
["way_4_4096_1024_rv32gc", ["arch32i"]],
|
|
||||||
["way_1_4096_512_rv64gc", ["arch64i"]],
|
["way_1_4096_512_rv64gc", ["arch64i"]],
|
||||||
["way_2_4096_512_rv64gc", ["arch64i"]],
|
["way_2_4096_512_rv64gc", ["arch64i"]],
|
||||||
["way_8_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_256_rv64gc", ["arch64i"]],
|
||||||
["way_4_4096_1024_rv64gc", ["arch64i"]],
|
["way_4_4096_1024_rv64gc", ["arch64i"]],
|
||||||
|
|
||||||
["ram_0_0_rv64gc", ["ahb"]],
|
["ram_0_0_rv64gc", ["ahb64"]],
|
||||||
["ram_1_0_rv64gc", ["ahb"]],
|
["ram_1_0_rv64gc", ["ahb64"]],
|
||||||
["ram_1_1_rv64gc", ["ahb"]],
|
["ram_1_1_rv64gc", ["ahb64"]],
|
||||||
["ram_2_0_rv64gc", ["ahb"]],
|
["ram_2_0_rv64gc", ["ahb64"]],
|
||||||
["ram_2_1_rv64gc", ["ahb"]],
|
["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_1_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
||||||
["div_2_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
["div_2_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]],
|
||||||
["div_2_2_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_4_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]],
|
||||||
["div_4_4i_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:
|
for test in derivconfigtests:
|
||||||
config = test[0];
|
config = test[0];
|
||||||
tests = test[1];
|
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:
|
for t in tests:
|
||||||
tc = TestCase(
|
tc = TestCase(
|
||||||
name=t,
|
name=t,
|
||||||
variant=config,
|
variant=config,
|
||||||
cmd="vsim > {} -c <<!\ndo wally-batch.do "+config+" "+t+"\n!",
|
cmd=cmdPrefix+" "+t+" configOptions "+configOptions+"\n!",
|
||||||
grepstr="All tests ran without failures")
|
grepstr="All tests ran without failures")
|
||||||
configs.append(tc)
|
configs.append(tc)
|
||||||
|
|
||||||
@ -293,13 +365,16 @@ def main():
|
|||||||
# Also it is slow to run.
|
# Also it is slow to run.
|
||||||
# configs.append(getBuildrootTC(boot=False))
|
# configs.append(getBuildrootTC(boot=False))
|
||||||
os.system('rm -f cov/*.ucdb')
|
os.system('rm -f cov/*.ucdb')
|
||||||
|
elif '-nightly' in sys.argv:
|
||||||
|
TIMEOUT_DUR = 60*1440 # 1 day
|
||||||
|
configs.append(getBuildrootTC(boot=False))
|
||||||
else:
|
else:
|
||||||
TIMEOUT_DUR = 10*60 # seconds
|
TIMEOUT_DUR = 10*60 # seconds
|
||||||
configs.append(getBuildrootTC(boot=False))
|
configs.append(getBuildrootTC(boot=False))
|
||||||
|
|
||||||
# Scale the number of concurrent processes to the number of test cases, but
|
# 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
|
# 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
|
num_fail = 0
|
||||||
results = {}
|
results = {}
|
||||||
for config in configs:
|
for config in configs:
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#export RISCV=/scratch/moore/RISCV
|
#export RISCV=/scratch/moore/RISCV
|
||||||
|
|
||||||
export IMPERAS_TOOLS=$(pwd)/imperas.ic
|
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="+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}
|
onbreak {resume}
|
||||||
|
|
||||||
# create library
|
# create library
|
||||||
if {$2 eq "ahb"} {
|
if [file exists wkdir/work_${1}_${2}] {
|
||||||
if [file exists wkdir/work_${1}_${2}_${3}_${4}] {
|
vdel -lib wkdir/work_${1}_${2} -all
|
||||||
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}
|
|
||||||
}
|
}
|
||||||
|
vlib wkdir/work_${1}_${2}
|
||||||
# Create directory for coverage data
|
# Create directory for coverage data
|
||||||
mkdir -p cov
|
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 {$argc >= 3} {
|
||||||
if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
|
if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} {
|
||||||
set coverage 1
|
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:
|
# default to config/rv64ic, but allow this to be overridden at the command line. For example:
|
||||||
# do wally-pipelined-batch.do ../config/rv32imc rv32imc
|
# 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
|
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 -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
|
|
||||||
|
|
||||||
#-- Run the Simulation
|
# start and run simulation
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||||
echo "Don't forget to change DEBUG_LEVEL = 0."
|
vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 ${configOptions} -o testbenchopt ${CoverageVoptArg}
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 ${CoverageVsimArg}
|
||||||
run -all
|
|
||||||
run -all
|
|
||||||
exec ./slack-notifier/slack-notifier.py
|
|
||||||
|
|
||||||
} 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
|
# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829
|
||||||
# power add generates the logging necessary for said generation.
|
# power add generates the logging necessary for said generation.
|
||||||
# power add -r /dut/core/*
|
# power add -r /dut/core/*
|
||||||
run -all
|
run -all
|
||||||
# power off -r /dut/core/*
|
# power off -r /dut/core/*
|
||||||
}
|
|
||||||
|
|
||||||
if {$coverage} {
|
if {$coverage} {
|
||||||
echo "Saving coverage to ${1}_${2}.ucdb"
|
echo "Saving coverage to ${1}_${2}.ucdb"
|
||||||
|
@ -32,25 +32,10 @@ vlib work
|
|||||||
|
|
||||||
# start and run simulation
|
# start and run simulation
|
||||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||||
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
if {$2 eq "buildroot"} {
|
||||||
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"} {
|
|
||||||
vlog -lint -work work_${1}_${2} \
|
vlog -lint -work work_${1}_${2} \
|
||||||
+define+USE_IMPERAS_DV \
|
+define+USE_IMPERAS_DV \
|
||||||
+incdir+../config/$1 \
|
+incdir+../config/deriv/$1 \
|
||||||
+incdir+../config/shared \
|
+incdir+../config/shared \
|
||||||
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
|
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
|
||||||
+incdir+$env(IMPERAS_HOME)/ImpProprietary/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/trace2cov.sv \
|
||||||
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
|
$env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2bin.sv \
|
||||||
../src/cvw.sv \
|
../src/cvw.sv \
|
||||||
../testbench/testbench-linux-imperas.sv \
|
../testbench/testbench.sv \
|
||||||
../testbench/common/*.sv ../src/*/*.sv \
|
../testbench/common/*.sv ../src/*/*.sv \
|
||||||
../src/*/*/*.sv -suppress 2583
|
../src/*/*/*.sv -suppress 2583
|
||||||
|
|
||||||
@ -76,7 +61,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
|||||||
# visualizer -fprofile+perf+dir=fprofile
|
# visualizer -fprofile+perf+dir=fprofile
|
||||||
#
|
#
|
||||||
eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
|
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 \
|
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 \
|
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
|
||||||
$env(OTHERFLAGS)
|
$env(OTHERFLAGS)
|
||||||
@ -96,60 +81,4 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
|
|||||||
|
|
||||||
exec ./slack-notifier/slack-notifier.py
|
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
|
run 20 ms
|
||||||
|
|
||||||
} else {
|
} 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
|
||||||
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
|
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
|
||||||
|
|
||||||
vsim workopt +nowarn3829 -fatal 7
|
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.
|
// This is a two port memory.
|
||||||
// Every cycle must read from CacheSetData and each load/store must write the new LRU.
|
// Every cycle must read from CacheSetData and each load/store must write the new LRU.
|
||||||
always_ff @(posedge clk) begin
|
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(CacheEn) begin
|
||||||
if(ClearValid & ~FlushStage)
|
if(ClearValid & ~FlushStage)
|
||||||
LRUMemory[PAdr] <= '0;
|
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;
|
NextState = STATE_READY;
|
||||||
case (CurrState) // exclusion-tag: icache state-case
|
case (CurrState) // exclusion-tag: icache state-case
|
||||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
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 & (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;
|
else NextState = STATE_READY;
|
||||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||||
else if(CacheBusAck) NextState = STATE_READY;
|
|
||||||
else NextState = STATE_FETCH;
|
else NextState = STATE_FETCH;
|
||||||
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
|
STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
|
||||||
STATE_READ_HOLD: if(Stall) 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]);
|
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
|
||||||
assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
|
assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
|
||||||
(CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
|
(CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
|
||||||
// coverage off -item e 1 -fecexprrow 8
|
|
||||||
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
|
||||||
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
|
||||||
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
|
(CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
|
||||||
@ -190,8 +188,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
|
|||||||
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
|
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
|
||||||
|
|
||||||
logic LoadMiss;
|
logic LoadMiss;
|
||||||
|
|
||||||
//assign StoreMiss = (CacheRW[0]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
|
||||||
assign LoadMiss = (CacheRW[1]) & ~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
|
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_WRITEBACK) |
|
||||||
(CurrState == STATE_WRITE_LINE) |
|
(CurrState == STATE_WRITE_LINE) |
|
||||||
resetDelay;
|
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_FETCH) |
|
||||||
(CurrState == STATE_WRITEBACK) |
|
(CurrState == STATE_WRITEBACK) |
|
||||||
(CurrState == STATE_WRITE_LINE) |
|
(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 [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid
|
||||||
output logic HitWay, // This way hits
|
output logic HitWay, // This way hits
|
||||||
output logic ValidWay, // This way is valid
|
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 DirtyWay , // The selected way is dirty
|
||||||
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
|
output logic [TAGLEN-1:0] TagWay); // This way's tag if valid
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ module buscachefsm #(
|
|||||||
logic CacheAccess;
|
logic CacheAccess;
|
||||||
logic BusWrite;
|
logic BusWrite;
|
||||||
|
|
||||||
assign BusWrite = CacheBusRW[0] | BusCMOZero;
|
assign BusWrite = (CacheBusRW[0] | BusCMOZero) & ~READ_ONLY_CACHE;
|
||||||
|
|
||||||
always_ff @(posedge HCLK)
|
always_ff @(posedge HCLK)
|
||||||
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
|
||||||
@ -87,28 +87,28 @@ module buscachefsm #(
|
|||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(CurrState)
|
case(CurrState)
|
||||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; // exclusion-tag: buscachefsm HREADY0
|
||||||
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
|
else if (HREADY & BusWrite & ~READ_ONLY_CACHE) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm HREADY1
|
||||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADYread
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE;
|
DATA_PHASE: if(HREADY & BusAtomic & ~READ_ONLY_CACHE) NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm HREADY2
|
||||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
else if(HREADY & ~BusAtomic) NextState = MEM3; // exclusion-tag: buscachefsm HREADY3
|
||||||
else NextState = DATA_PHASE;
|
else NextState = DATA_PHASE;
|
||||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE;
|
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicReadData
|
||||||
else NextState = ATOMIC_READ_DATA_PHASE;
|
else NextState = ATOMIC_READ_DATA_PHASE; // exclusion-tag: buscachefsm AtomicElse
|
||||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3;
|
ATOMIC_PHASE: if(HREADY) NextState = MEM3; // exclusion-tag: buscachefsm AtomicPhase
|
||||||
else NextState = ATOMIC_PHASE;
|
else NextState = ATOMIC_PHASE; // exclusion-tag: buscachefsm AtomicWait
|
||||||
MEM3: if(Stall) NextState = MEM3;
|
MEM3: if(Stall) NextState = MEM3;
|
||||||
else NextState = ADR_PHASE;
|
else NextState = ADR_PHASE;
|
||||||
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
|
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm FetchWriteback
|
||||||
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
|
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm FetchWait
|
||||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||||
else NextState = CACHE_FETCH;
|
else NextState = CACHE_FETCH;
|
||||||
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) 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;
|
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; // exclusion-tag: buscachefsm HREADY4
|
||||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3;
|
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3; // exclusion-tag: buscachefsm HREADY5
|
||||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; // exclusion-tag: buscachefsm HREADY6
|
||||||
else NextState = CACHE_WRITEBACK;
|
else NextState = CACHE_WRITEBACK; // exclusion-tag: buscachefsm WritebackWriteback2
|
||||||
default: NextState = ADR_PHASE;
|
default: NextState = ADR_PHASE;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
@ -139,12 +139,12 @@ module buscachefsm #(
|
|||||||
|
|
||||||
// AHB bus interface
|
// AHB bus interface
|
||||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) |
|
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 & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request
|
||||||
(CacheAccess & |BeatCount) ? (BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
|
(CacheAccess & |BeatCount) ? (BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
|
||||||
|
|
||||||
assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
assign HWRITE = (((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||||
(CurrState == CACHE_WRITEBACK & |BeatCount);
|
(CurrState == CACHE_WRITEBACK & |BeatCount)) & ~READ_ONLY_CACHE;
|
||||||
assign HBURST = BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
assign HBURST = BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
||||||
|
|
||||||
always_comb begin
|
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'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
|
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu
|
||||||
endcase
|
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)
|
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
|
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)
|
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)
|
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa)
|
||||||
// coverage on
|
// coverage on
|
||||||
|
@ -278,9 +278,14 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
|||||||
end else assign FliResE = '0;
|
end else assign FliResE = '0;
|
||||||
|
|
||||||
// fmv.*.x: NaN Box SrcA to extend integer to requested FP size
|
// 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)
|
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
|
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
|
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]},
|
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
|
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] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
||||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||||
logic ResSubnorm; // is the result Subnormal
|
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
|
// 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
|
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 if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
|
||||||
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
||||||
|
|
||||||
|
@ -140,15 +140,12 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
|
|||||||
endcase
|
endcase
|
||||||
|
|
||||||
always_comb
|
always_comb
|
||||||
if (BadNaNBox) begin
|
if (BadNaNBox & Fmt == P.FMT1)
|
||||||
case (Fmt)
|
PostBox = {{(P.FLEN-P.LEN1){1'b1}}, 1'b1, {(P.NE1+1){1'b1}}, {(P.LEN1-P.NE1-2){1'b0}}};
|
||||||
P.FMT: PostBox = In;
|
else if (BadNaNBox) // Fmt == P.FMT2
|
||||||
P.FMT1: PostBox = {{(P.FLEN-P.LEN1){1'b1}}, 1'b1, {(P.NE1+1){1'b1}}, {(P.LEN1-P.NE1-2){1'b0}}};
|
PostBox = {{(P.FLEN-P.LEN2){1'b1}}, 1'b1, {(P.NE2+1){1'b1}}, {(P.LEN2-P.NE2-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}}};
|
else
|
||||||
default: PostBox = 'x;
|
PostBox = In;
|
||||||
endcase
|
|
||||||
end else
|
|
||||||
PostBox = In;
|
|
||||||
|
|
||||||
// extract the sign bit
|
// extract the sign bit
|
||||||
always_comb
|
always_comb
|
||||||
|
@ -42,6 +42,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic BranchD, // Branch instruction
|
output logic BranchD, // Branch instruction
|
||||||
output logic StructuralStallD, // Structural stalls detected by controller
|
output logic StructuralStallD, // Structural stalls detected by controller
|
||||||
output logic LoadStallD, // Structural stalls for load, sent to performance counters
|
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
|
output logic [4:0] Rs1D, Rs2D, // Register sources to read in Decode or Execute stage
|
||||||
// Execute stage control signals
|
// Execute stage control signals
|
||||||
input logic StallE, FlushE, // Stall, flush Execute stage
|
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 CMOStallD; // Structural hazards from cache management ops
|
||||||
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
|
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 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)
|
logic FunctCZeroD; // Funct7 and Funct3 indicate czero.* (not including Op check)
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
|
@ -76,6 +76,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
|
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
|
||||||
output logic StructuralStallD, // IEU detects structural hazard in Decode stage
|
output logic StructuralStallD, // IEU detects structural hazard in Decode stage
|
||||||
output logic LoadStallD, // Structural stalls for load, sent to performance counters
|
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 CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
|
||||||
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
|
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(
|
controller #(P) c(
|
||||||
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
|
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
|
||||||
.IllegalIEUFPUInstrD, .IllegalBaseInstrD,
|
.IllegalIEUFPUInstrD, .IllegalBaseInstrD,
|
||||||
.StructuralStallD, .LoadStallD, .Rs1D, .Rs2D,
|
.StructuralStallD, .LoadStallD, .StoreStallD, .Rs1D, .Rs2D,
|
||||||
.StallE, .FlushE, .FlagsE, .FWriteIntE,
|
.StallE, .FlushE, .FlagsE, .FWriteIntE,
|
||||||
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
|
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
|
||||||
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
|
.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 [P.XLEN-1:0] BPBTAD;
|
||||||
|
|
||||||
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
|
||||||
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
|
||||||
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
|
||||||
logic ReturnD, CallD;
|
logic ReturnD, CallD;
|
||||||
logic ReturnE, CallE;
|
logic ReturnE, CallE;
|
||||||
logic BranchM, JumpM, ReturnM, CallM;
|
logic BranchM, JumpM, ReturnM, CallM;
|
||||||
logic BranchW, JumpW, ReturnW, CallW;
|
logic BranchW, JumpW, ReturnW, CallW;
|
||||||
logic BPReturnWrongD;
|
logic BPReturnWrongD;
|
||||||
logic [P.XLEN-1:0] BPBTAE;
|
logic [P.XLEN-1:0] BPBTAE;
|
||||||
|
logic BPBTAWrongM;
|
||||||
|
logic PCSrcM;
|
||||||
|
|
||||||
// Part 1 branch direction prediction
|
// Part 1 branch direction prediction
|
||||||
if (P.BPRED_TYPE == `BP_TWOBIT) begin:Predictor
|
if (P.BPRED_TYPE == `BP_TWOBIT) begin:Predictor
|
||||||
@ -144,6 +146,8 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||||||
.BranchD, .BranchE, .BranchM, .PCSrcE);
|
.BranchD, .BranchE, .BranchM, .PCSrcE);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM);
|
||||||
|
|
||||||
// Part 2 Branch target address prediction
|
// Part 2 Branch target address prediction
|
||||||
// BTB contains target address for all CFI
|
// BTB contains target address for all CFI
|
||||||
|
|
||||||
@ -152,6 +156,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||||||
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
.PCNextF, .PCF, .PCD, .PCE, .PCM,
|
||||||
.BPBTAF, .BPBTAD, .BPBTAE,
|
.BPBTAF, .BPBTAD, .BPBTAE,
|
||||||
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
|
||||||
|
.BPBTAWrongM,
|
||||||
.IClassWrongM, .IClassWrongE,
|
.IClassWrongM, .IClassWrongE,
|
||||||
.IEUAdrE, .IEUAdrM,
|
.IEUAdrE, .IEUAdrM,
|
||||||
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
.InstrClassD({CallD, ReturnD, JumpD, BranchD}),
|
||||||
@ -196,7 +201,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
if(P.ZIHPM_SUPPORTED) begin
|
if(P.ZIHPM_SUPPORTED) begin
|
||||||
logic [P.XLEN-1:0] RASPCD, RASPCE;
|
logic [P.XLEN-1:0] RASPCD, RASPCE;
|
||||||
logic BTAWrongE, RASPredPCWrongE;
|
logic RASPredPCWrongE;
|
||||||
// performance counters
|
// performance counters
|
||||||
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
|
// 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)
|
// 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
|
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
|
||||||
// both without the above inaccuracies.
|
// both without the above inaccuracies.
|
||||||
// **** use BPBTAWrongM from BTB.
|
// **** use BPBTAWrongM from BTB.
|
||||||
assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
|
|
||||||
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
|
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
|
||||||
|
|
||||||
flopenrc #(P.XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
flopenrc #(P.XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
|
||||||
flopenrc #(P.XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
flopenrc #(P.XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
|
||||||
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
flopenrc #(2) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
|
||||||
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
|
{BPDirPredWrongE, RASPredPCWrongE},
|
||||||
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
|
{BPDirPredWrongM, RASPredPCWrongM});
|
||||||
|
|
||||||
|
assign BTAWrongM = BPBTAWrongM & PCSrcM;
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
assign {BTAWrongM, RASPredPCWrongM} = '0;
|
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] BPBTAD,
|
||||||
output logic [P.XLEN-1:0] BPBTAE,
|
output logic [P.XLEN-1:0] BPBTAE,
|
||||||
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
output logic [3:0] BTBIClassF, // BTB's guess at instruction class
|
||||||
|
output logic BPBTAWrongM,
|
||||||
// update
|
// update
|
||||||
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
input logic IClassWrongM, // BTB's instruction class guess was wrong
|
||||||
input logic IClassWrongE,
|
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] IEUAdrW;
|
||||||
logic [P.XLEN-1:0] PCW;
|
logic [P.XLEN-1:0] PCW;
|
||||||
logic BTBWrongE, BPBTAWrongE;
|
logic BTBWrongE, BPBTAWrongE;
|
||||||
logic BTBWrongM, BPBTAWrongM;
|
logic BTBWrongM;
|
||||||
|
|
||||||
|
|
||||||
// hashing function for indexing the PC
|
// 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),
|
ahbinterface #(P.XLEN, 1'b1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
.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));
|
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||||
|
|
||||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
// 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]);
|
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 LSUHBURST = 3'b0;
|
||||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||||
end
|
end
|
||||||
@ -406,7 +406,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (P.F_SUPPORTED)
|
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;
|
else assign IMAFWriteDataM = IMAWriteDataM;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -49,5 +49,5 @@ module adrdec #(parameter PA_BITS) (
|
|||||||
assign SizeValid = SizeMask[Size];
|
assign SizeValid = SizeMask[Size];
|
||||||
|
|
||||||
// Select this peripheral if the address matches, the peripheral is supported, and the type and size of access is ok
|
// 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
|
endmodule
|
||||||
|
@ -54,7 +54,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [3:0] CauseM, // Trap cause
|
input logic [3:0] CauseM, // Trap cause
|
||||||
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
||||||
// inputs for performance counters
|
// inputs for performance counters
|
||||||
input logic LoadStallD,
|
input logic LoadStallD, StoreStallD,
|
||||||
input logic ICacheStallF,
|
input logic ICacheStallF,
|
||||||
input logic DCacheStallM,
|
input logic DCacheStallM,
|
||||||
input logic BPDirPredWrongM,
|
input logic BPDirPredWrongM,
|
||||||
@ -275,7 +275,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
if (P.ZICNTR_SUPPORTED) begin:counters
|
if (P.ZICNTR_SUPPORTED) begin:counters
|
||||||
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
|
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
|
||||||
.InstrValidNotFlushedM, .LoadStallD, .CSRWriteM, .CSRMWriteM,
|
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM,
|
||||||
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
|
||||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
|
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
|
||||||
.InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
.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 clk, reset,
|
||||||
input logic StallE, StallM,
|
input logic StallE, StallM,
|
||||||
input logic FlushM,
|
input logic FlushM,
|
||||||
input logic InstrValidNotFlushedM, LoadStallD,
|
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
|
||||||
input logic CSRMWriteM, CSRWriteM,
|
input logic CSRMWriteM, CSRWriteM,
|
||||||
input logic BPDirPredWrongM,
|
input logic BPDirPredWrongM,
|
||||||
input logic BTAWrongM,
|
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] HPMCOUNTER_REGW[P.COUNTERS-1:0];
|
||||||
logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0];
|
logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0];
|
||||||
logic LoadStallE, LoadStallM;
|
logic LoadStallE, LoadStallM;
|
||||||
|
logic StoreStallE, StoreStallM;
|
||||||
logic [P.COUNTERS-1:0] WriteHPMCOUNTERM;
|
logic [P.COUNTERS-1:0] WriteHPMCOUNTERM;
|
||||||
logic [P.COUNTERS-1:0] CounterEvent;
|
logic [P.COUNTERS-1:0] CounterEvent;
|
||||||
logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0];
|
logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0];
|
||||||
@ -85,6 +86,9 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
|||||||
// Interface signals
|
// 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) 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) 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
|
// Determine when to increment each counter
|
||||||
assign CounterEvent[0] = 1'b1; // MCYCLE always increments
|
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[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
|
||||||
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
|
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[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[13] = DCacheAccess; // data cache access
|
||||||
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
|
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
|
||||||
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles
|
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
|
// processor events for performance counter logging
|
||||||
input logic FRegWriteM, // instruction will write floating-point registers
|
input logic FRegWriteM, // instruction will write floating-point registers
|
||||||
input logic LoadStallD, // load instruction is stalling
|
input logic LoadStallD, // load instruction is stalling
|
||||||
|
input logic StoreStallD, // store instruction is stalling
|
||||||
input logic ICacheStallF, // I cache stalled
|
input logic ICacheStallF, // I cache stalled
|
||||||
input logic DCacheStallM, // D cache stalled
|
input logic DCacheStallM, // D cache stalled
|
||||||
input logic BPDirPredWrongM, // branch predictor guessed wrong direction
|
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,
|
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM,
|
||||||
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
|
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
|
||||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||||
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
|
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD,
|
||||||
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
|
||||||
.sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
.sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
|
||||||
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
|
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,
|
||||||
|
@ -78,6 +78,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic DivBusyE;
|
logic DivBusyE;
|
||||||
logic StructuralStallD;
|
logic StructuralStallD;
|
||||||
logic LoadStallD;
|
logic LoadStallD;
|
||||||
|
logic StoreStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
logic MDUActiveE; // Mul/Div instruction being executed
|
logic MDUActiveE; // Mul/Div instruction being executed
|
||||||
logic ENVCFG_ADUE; // HPTW A/D Update enable
|
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,
|
.InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
|
||||||
// hazards
|
// hazards
|
||||||
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.StructuralStallD, .LoadStallD, .PCSrcE,
|
.StructuralStallD, .LoadStallD, .StoreStallD, .PCSrcE,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM);
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM);
|
||||||
|
|
||||||
lsu #(P) lsu(
|
lsu #(P) lsu(
|
||||||
@ -286,7 +287,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
.InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM,
|
.InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM,
|
||||||
.RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
|
.RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
|
||||||
.InstrValidM, .CommittedM, .CommittedF,
|
.InstrValidM, .CommittedM, .CommittedF,
|
||||||
.FRegWriteM, .LoadStallD,
|
.FRegWriteM, .LoadStallD, .StoreStallD,
|
||||||
.BPDirPredWrongM, .BTAWrongM, .BPWrongM,
|
.BPDirPredWrongM, .BTAWrongM, .BPWrongM,
|
||||||
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
|
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
|
||||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
||||||
|
@ -21,53 +21,51 @@
|
|||||||
|
|
||||||
module riscvassertions import cvw::*; #(parameter cvw_t P);
|
module riscvassertions import cvw::*; #(parameter cvw_t P);
|
||||||
initial begin
|
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.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 $error("Virtual memory requires S mode support");
|
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 $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");
|
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 $error("Can't support double fp (D) without supporting float (F)");
|
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 $error("Can't support quad fp (Q) without supporting double (D)");
|
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 $error("Can't support half-precision fp (ZFH) without supporting float (F)");
|
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 $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN");
|
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 $error("Exactly one of I and E must be supported");
|
assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $fatal(1, "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 $fatal(1, "DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||||
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 $fatal(1, "DCACHE_LINELENINBITS must be at least 128 when caches are enabled");
|
||||||
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 $fatal(1, "DCACHE_LINELENINBITS must be smaller than way size");
|
||||||
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 $fatal(1, "ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
|
||||||
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 $fatal(1, "ICACHE_LINELENINBITS must be at least 32 when caches are enabled");
|
||||||
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 $fatal(1, "ICACHE_LINELENINBITS must be smaller than way size");
|
||||||
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 $fatal(1, "DCACHE_LINELENINBITS must be a power of 2");
|
||||||
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 $fatal(1, "DCACHE_WAYSIZEINBYTES 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 $fatal(1, "ICACHE_LINELENINBITS 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 $fatal(1, "ICACHE_WAYSIZEINBYTES 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 $fatal(1, "ITLB_ENTRIES 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 $fatal(1, "DTLB_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.UNCORE_RAM_RANGE >= 64'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 64'h07FFFFFF");
|
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.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 $error("S and U modes not supported 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.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.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 $error("Virtual memory needs dcache");
|
assert (P.DCACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $fatal(1, "Virtual memory needs dcache");
|
||||||
assert (P.ICACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache");
|
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 $error("Dcache and Icache requires DBUS_SUPPORTED.");
|
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 $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1");
|
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 $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words");
|
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 $error("Atomic extension (A) requires cache on Wally.");
|
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 $error("IDIV on FPU needs F_SUPPORTED");
|
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 $error("SSTC requires S_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 $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled");
|
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 $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED");
|
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 $error("ZIPHM_SUPPORTED requires ZICNTR_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 $error("ZICBOM requires DCACHE_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 $error("ZICBOZ requires DCACHE_SUPPORTED");
|
assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "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 $fatal(1, "SVPBMT requires VIRTMEM_SUPPORTED and RV64");
|
||||||
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 $fatal(1, "SVNAPOT 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 $fatal(1, "ZCB requires M and ZBB (and also ZBA for 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 $fatal(1, "C and ZCA/ZCD/ZCF cannot simultaneously be supported");
|
||||||
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 $fatal(1, "ZCF or ZCD requires ZCA");
|
||||||
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 $fatal(1, "ZCF requires F");
|
||||||
assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $error("ZCF requires F");
|
assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D");
|
||||||
assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $error("ZCD requires D");
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
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 "tests.vh"
|
||||||
`include "BranchPredictorType.vh"
|
`include "BranchPredictorType.vh"
|
||||||
|
|
||||||
|
`ifdef USE_IMPERAS_DV
|
||||||
|
`include "idv/idv.svh"
|
||||||
|
`endif
|
||||||
|
|
||||||
import cvw::*;
|
import cvw::*;
|
||||||
|
|
||||||
module testbench;
|
module testbench;
|
||||||
@ -40,7 +44,15 @@ module testbench;
|
|||||||
parameter BPRED_LOGGER=0;
|
parameter BPRED_LOGGER=0;
|
||||||
parameter I_CACHE_ADDR_LOGGER=0;
|
parameter I_CACHE_ADDR_LOGGER=0;
|
||||||
parameter D_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"
|
`include "parameter-defs.vh"
|
||||||
|
|
||||||
logic clk;
|
logic clk;
|
||||||
@ -121,7 +133,7 @@ module testbench;
|
|||||||
"wally64periph": tests = wally64periph;
|
"wally64periph": tests = wally64periph;
|
||||||
"coremark": tests = coremark;
|
"coremark": tests = coremark;
|
||||||
"fpga": tests = fpga;
|
"fpga": tests = fpga;
|
||||||
"ahb" : tests = ahb;
|
"ahb64" : tests = ahb64;
|
||||||
"coverage64gc" : tests = coverage64gc;
|
"coverage64gc" : tests = coverage64gc;
|
||||||
"arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba;
|
"arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba;
|
||||||
"arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb;
|
"arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb;
|
||||||
@ -130,10 +142,11 @@ module testbench;
|
|||||||
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
|
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
|
||||||
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
|
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
|
||||||
"arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh;
|
"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;
|
"arch64zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch64zfh_divsqrt;
|
||||||
"arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf;
|
"arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf;
|
||||||
"arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad;
|
"arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad;
|
||||||
|
"buildroot": tests = buildroot;
|
||||||
endcase
|
endcase
|
||||||
end else begin // RV32
|
end else begin // RV32
|
||||||
case (TEST)
|
case (TEST)
|
||||||
@ -162,6 +175,7 @@ module testbench;
|
|||||||
"wally32i": tests = wally32i;
|
"wally32i": tests = wally32i;
|
||||||
"wally32priv": tests = wally32priv;
|
"wally32priv": tests = wally32priv;
|
||||||
"wally32periph": tests = wally32periph;
|
"wally32periph": tests = wally32periph;
|
||||||
|
"ahb32" : tests = ahb32;
|
||||||
"embench": tests = embench;
|
"embench": tests = embench;
|
||||||
"coremark": tests = coremark;
|
"coremark": tests = coremark;
|
||||||
"arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba;
|
"arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba;
|
||||||
@ -171,7 +185,7 @@ module testbench;
|
|||||||
"arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz;
|
"arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz;
|
||||||
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
|
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
|
||||||
"arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh;
|
"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;
|
"arch32zfh_divsqrt": if (P.ZFH_SUPPORTED) tests = arch32zfh_divsqrt;
|
||||||
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
|
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
|
||||||
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
|
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
|
||||||
@ -179,7 +193,7 @@ module testbench;
|
|||||||
end
|
end
|
||||||
if (tests.size() == 0) begin
|
if (tests.size() == 0) begin
|
||||||
$display("TEST %s not supported in this configuration", TEST);
|
$display("TEST %s not supported in this configuration", TEST);
|
||||||
$stop;
|
$finish;
|
||||||
end
|
end
|
||||||
end // initial begin
|
end // initial begin
|
||||||
|
|
||||||
@ -209,7 +223,7 @@ module testbench;
|
|||||||
logic ResetCntRst;
|
logic ResetCntRst;
|
||||||
logic CopyRAM;
|
logic CopyRAM;
|
||||||
|
|
||||||
string signame, memfilename, pathname;
|
string signame, memfilename, bootmemfilename, pathname;
|
||||||
integer begin_signature_addr, end_signature_addr, signature_size;
|
integer begin_signature_addr, end_signature_addr, signature_size;
|
||||||
|
|
||||||
assign ResetThreshold = 3'd5;
|
assign ResetThreshold = 3'd5;
|
||||||
@ -278,10 +292,17 @@ module testbench;
|
|||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if(SelectTest) begin
|
if(SelectTest) begin
|
||||||
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
|
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"};
|
else memfilename = {pathname, tests[test], ".elf.memfile"};
|
||||||
if (riscofTest) begin
|
if (riscofTest) begin
|
||||||
ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"};
|
ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"};
|
||||||
ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"};
|
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
|
end else begin
|
||||||
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
|
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
|
||||||
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
|
||||||
@ -325,19 +346,18 @@ module testbench;
|
|||||||
end else begin
|
end else begin
|
||||||
// for tests with no self checking mechanism, read .signature.output file and compare to check for errors
|
// 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
|
// 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
|
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.
|
test = test + 1; // *** this probably needs to be moved.
|
||||||
if (test == tests.size()) begin
|
if (test == tests.size()) begin
|
||||||
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
|
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
|
||||||
else $display("FAIL: %d test programs had errors", totalerrors);
|
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
|
end
|
||||||
end
|
end
|
||||||
@ -352,6 +372,8 @@ module testbench;
|
|||||||
integer StartIndex;
|
integer StartIndex;
|
||||||
integer EndIndex;
|
integer EndIndex;
|
||||||
integer BaseIndex;
|
integer BaseIndex;
|
||||||
|
integer memFile;
|
||||||
|
integer readResult;
|
||||||
if (P.SDC_SUPPORTED) begin
|
if (P.SDC_SUPPORTED) begin
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (LoadMem) begin
|
if (LoadMem) begin
|
||||||
@ -373,7 +395,16 @@ module testbench;
|
|||||||
end else if (P.BUS_SUPPORTED) begin : bus_supported
|
end else if (P.BUS_SUPPORTED) begin : bus_supported
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (LoadMem) 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
|
end
|
||||||
if (CopyRAM) begin
|
if (CopyRAM) begin
|
||||||
LogXLEN = (1 + P.XLEN/32); // 2 for rv32 and 3 for rv64
|
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));
|
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;
|
task automatic CheckSignature;
|
||||||
// This task must be declared inside this module as it needs access to parameter P. There is
|
// 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.
|
// no way to pass P to the task unless we convert it to a module.
|
||||||
@ -601,7 +801,7 @@ module testbench;
|
|||||||
errors = errors+1;
|
errors = errors+1;
|
||||||
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DTIM_SUPPORTED) = %h, signature = %h",
|
$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]);
|
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
|
||||||
end
|
end
|
||||||
if (errors) $display("%s failed with %d errors. :(", TestName, errors);
|
if (errors) $display("%s failed with %d errors. :(", TestName, errors);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
`define EMBENCH "4"
|
`define EMBENCH "4"
|
||||||
`define CUSTOM "5"
|
`define CUSTOM "5"
|
||||||
`define COVERAGE "6"
|
`define COVERAGE "6"
|
||||||
|
`define BUILDROOT "7"
|
||||||
|
|
||||||
string tvpaths[] = '{
|
string tvpaths[] = '{
|
||||||
"$RISCV/imperas-riscv-tests/work/",
|
"$RISCV/imperas-riscv-tests/work/",
|
||||||
@ -71,6 +72,11 @@ string tvpaths[] = '{
|
|||||||
"pmpadrdecs"
|
"pmpadrdecs"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
string buildroot[] = '{
|
||||||
|
`BUILDROOT,
|
||||||
|
"buildroot"
|
||||||
|
};
|
||||||
|
|
||||||
string coremark[] = '{
|
string coremark[] = '{
|
||||||
`COREMARK,
|
`COREMARK,
|
||||||
"coremark.bare.riscv"
|
"coremark.bare.riscv"
|
||||||
@ -1126,6 +1132,14 @@ string imperas32f[] = '{
|
|||||||
// "rv64i_m/F/src/fnmsub_b15-01.S"
|
// "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[] = '{
|
string arch64f_divsqrt[] = '{
|
||||||
`RISCVARCHTEST,
|
`RISCVARCHTEST,
|
||||||
"rv64i_m/F/src/fdiv_b20-01.S",
|
"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_b5-01.S",
|
||||||
"rv64i_m/Zfh/src/fsub_b7-01.S",
|
"rv64i_m/Zfh/src/fsub_b7-01.S",
|
||||||
"rv64i_m/Zfh/src/fsub_b8-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_b5-01.S",
|
||||||
"rv32i_m/Zfh/src/fsub_b7-01.S",
|
"rv32i_m/Zfh/src/fsub_b7-01.S",
|
||||||
"rv32i_m/Zfh/src/fsub_b8-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[] = '{
|
string arch32zfaf[] = '{
|
||||||
@ -2066,6 +2176,14 @@ string arch64zbs[] = '{
|
|||||||
"rv32i_m/D/src/fnmsub.d_b15-01.S"
|
"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[] = '{
|
string arch32d_divsqrt[] = '{
|
||||||
`RISCVARCHTEST,
|
`RISCVARCHTEST,
|
||||||
"rv32i_m/D/src/fdiv.d_b1-01.S",
|
"rv32i_m/D/src/fdiv.d_b1-01.S",
|
||||||
@ -2472,7 +2590,12 @@ string arch64zbs[] = '{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
string ahb[] = '{
|
string ahb64[] = '{
|
||||||
`RISCVARCHTEST,
|
`RISCVARCHTEST,
|
||||||
"rv64i_m/F/src/fadd_b11-01.S"
|
"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
|
%.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 \
|
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 $<
|
-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
|
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile
|
||||||
extractFunctionRadix.sh $@.objdump
|
extractFunctionRadix.sh $@.objdump
|
||||||
|
|
||||||
|
@ -37,6 +37,26 @@ main:
|
|||||||
flw ft0, 0(t0)
|
flw ft0, 0(t0)
|
||||||
fclass.s t1, ft0
|
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
|
#Result Sign Test Coverage
|
||||||
la t0, TestData2
|
la t0, TestData2
|
||||||
flw ft0, 0(t0)
|
flw ft0, 0(t0)
|
||||||
@ -109,6 +129,12 @@ main:
|
|||||||
# fcvt.w.q a0, ft0
|
# fcvt.w.q a0, ft0
|
||||||
# fcvt.q.d ft3, 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)
|
// 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.
|
// 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
|
li t0, 0x3F812345 # random value slightly bigger than 1
|
||||||
@ -159,6 +185,10 @@ main:
|
|||||||
.word 0xD5F00053 // illegal fcvt.h.* (bad Rs2D)
|
.word 0xD5F00053 // illegal fcvt.h.* (bad Rs2D)
|
||||||
.word 0xC5F00053 // illegal fcvt.*.h (bad Rs2D)
|
.word 0xC5F00053 // illegal fcvt.*.h (bad Rs2D)
|
||||||
.word 0x04000043 // illegal fmadd.h (h not supported)
|
.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
|
// Test divide by zero with rounding mode toward zero
|
||||||
li t0, 1
|
li t0, 1
|
||||||
@ -206,4 +236,6 @@ TestData2:
|
|||||||
.int 0xbf800000 #FP -1.0
|
.int 0xbf800000 #FP -1.0
|
||||||
.int 0x7fa00000 #SNaN
|
.int 0x7fa00000 #SNaN
|
||||||
.int 0x3fffffff #OverFlow Test
|
.int 0x3fffffff #OverFlow Test
|
||||||
|
TestData3:
|
||||||
|
.dword 0xABCD543212345678 # NaN box test
|
||||||
DivTestData:
|
DivTestData:
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||||
// nlimpert@hmc.edu
|
// 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.
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
// https://github.com/openhwgroup/cvw
|
// https://github.com/openhwgroup/cvw
|
||||||
@ -25,6 +26,8 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// load code to initalize stack, handle interrupts, terminate
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
#include "WALLY-init-lib.h"
|
#include "WALLY-init-lib.h"
|
||||||
@ -43,11 +46,12 @@ main:
|
|||||||
|
|
||||||
li t0, 0xC0000000
|
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 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
|
loop: bge t2, t3, finished # exit loop if i >= loops
|
||||||
|
sfence.vma
|
||||||
li t1, 0x00008067 #load in jalr
|
li t1, 0x00008067 #load in jalr
|
||||||
sw t1, 0(t0)
|
sw t1, 0(t0)
|
||||||
fence.I
|
fence.I
|
||||||
@ -55,7 +59,7 @@ loop: bge t2, t3, finished # exit loop if i >= loops
|
|||||||
li t5, 0x9001000000080080 // try making asid = 1
|
li t5, 0x9001000000080080 // try making asid = 1
|
||||||
csrw satp, t5
|
csrw satp, t5
|
||||||
jalr t0
|
jalr t0
|
||||||
li t5, 0x9000000000080080 // try making asid = 0
|
li t5, 0x9000000000080080 // try making asid = 0
|
||||||
csrw satp, t5
|
csrw satp, t5
|
||||||
li t4, 0x1000
|
li t4, 0x1000
|
||||||
add t0, t0, t4
|
add t0, t0, t4
|
||||||
@ -71,7 +75,7 @@ finished:
|
|||||||
pagetable:
|
pagetable:
|
||||||
.8byte 0x200204C1
|
.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 0x0
|
.8byte 0x0
|
||||||
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
|
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
|
||||||
|
@ -55,14 +55,24 @@ main:
|
|||||||
li t4, 0x1000 # address step size
|
li t4, 0x1000 # address step size
|
||||||
li a2, 0x80216000 # Test NAPOT pages
|
li a2, 0x80216000 # Test NAPOT pages
|
||||||
jal a1, looptest
|
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
|
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
|
||||||
ecall
|
ecall
|
||||||
j done
|
j done
|
||||||
|
|
||||||
looptest:
|
looptest:
|
||||||
mv t0, a2 # base address
|
mv t0, a2 # base address
|
||||||
li t2, 0 # i = 0
|
li t2, 0 # i = 0
|
||||||
li t3, 35 # Max amount of Loops = 34
|
li t3, 32 # Max amount of Loops = 32
|
||||||
li t5, 0x8082 # return instruction opcode
|
li t5, 0x8082 # return instruction opcode
|
||||||
|
|
||||||
loop: bge t2, t3, finished # exit loop if i >= loops
|
loop: bge t2, t3, finished # exit loop if i >= loops
|
||||||
|
@ -96,6 +96,49 @@ main:
|
|||||||
sw t1, 0(t0) # write to page
|
sw t1, 0(t0) # write to page
|
||||||
jalr ra, t0 # jump 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
|
# Nonleaf PTE has PBMT != 0 causes a page fault during page walking. H
|
||||||
li t0, 0x80600000
|
li t0, 0x80600000
|
||||||
lw t1, 0(t0) # read from page
|
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
|
# change back to default trap handler after checking everything that might cause an instruction page fault
|
||||||
jal changetodefaulthandler
|
jal changetodefaulthandler
|
||||||
|
|
||||||
|
# uncachable AMO access
|
||||||
|
li t0, 0x80401000 # PBMT sets as uncachable
|
||||||
|
amoadd.w t0, t0, 0(t0)
|
||||||
|
|
||||||
# exercise CBOM instructions with various permissions
|
# exercise CBOM instructions with various permissions
|
||||||
li t0, 0x80800000
|
li t0, 0x80800000
|
||||||
cbo.zero (t0)
|
cbo.zero (t0)
|
||||||
@ -294,6 +341,12 @@ pagetable:
|
|||||||
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000
|
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000
|
||||||
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
|
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
|
||||||
.8byte 0x00000000000000C1 # gigapage at VA 0xC0000000 causes access fault
|
.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
|
# Next page table at 0x80012000 for gigapage at 0x80000000
|
||||||
@ -408,7 +461,8 @@ pagetable:
|
|||||||
# Leaf page table at 0x80014000 with PBMT pages
|
# Leaf page table at 0x80014000 with PBMT pages
|
||||||
.align 12
|
.align 12
|
||||||
#80400000
|
#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
|
# Leaf page table at 0x80015000 with various permissions for testing CBOM and CBOZ
|
||||||
.align 12
|
.align 12
|
||||||
|
Loading…
Reference in New Issue
Block a user