Merge branch 'openhwgroup:main' into main

This commit is contained in:
Thomas Kidd 2024-02-12 14:52:52 -06:00 committed by GitHub
commit 639870598a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 1057 additions and 2653 deletions

View File

@ -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

View File

@ -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);
} }
}; };

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
#################### ####################

View File

@ -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

View File

@ -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:

View File

@ -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"

View File

@ -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"

View File

@ -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
#}

View File

@ -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

View File

@ -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
View File

@ -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) |

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]},

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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"
};

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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