diff --git a/config/buildroot/config.vh b/config/buildroot/config.vh deleted file mode 100644 index 6629af297..000000000 --- a/config/buildroot/config.vh +++ /dev/null @@ -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" diff --git a/config/derivlist.txt b/config/derivlist.txt index 581922b9c..558cedbe3 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -41,8 +41,8 @@ RESET_VECTOR 64'h1000 UNCORE_RAM_RANGE 64'h0FFFFFFF UNCORE_RAM_PRELOAD 1 GPIO_LOOPBACK_TEST 0 -SPI_LOOPBACK_TEST 0 -UART_PRESCALE 0 +SPI_LOOPBACK_TEST 0 +UART_PRESCALE 32'd0 PLIC_NUM_SRC 32'd53 # fpga is used for FPGA hardware. It adds the SDC and DDR (EXT_MEM) @@ -119,26 +119,33 @@ MISA (32'h00000104 | 1 << 18 | 1 << 20) deriv div_2_1_rv32gc rv32gc RADIX 32'd2 DIVCOPIES 32'd1 +IDIV_ON_FPU 0 deriv div_2_2_rv32gc rv32gc RADIX 32'd2 DIVCOPIES 32'd2 +IDIV_ON_FPU 0 deriv div_2_4_rv32gc rv32gc RADIX 32'd2 DIVCOPIES 32'd4 +IDIV_ON_FPU 0 deriv div_4_1_rv32gc rv32gc RADIX 32'd4 DIVCOPIES 32'd1 +IDIV_ON_FPU 0 deriv div_4_2_rv32gc rv32gc RADIX 32'd4 +IDIV_ON_FPU 0 DIVCOPIES 32'd2 +IDIV_ON_FPU 0 deriv div_4_4_rv32gc rv32gc RADIX 32'd4 DIVCOPIES 32'd4 +IDIV_ON_FPU 0 deriv div_2_1i_rv32gc rv32gc div_2_1_rv32gc IDIV_ON_FPU 1 @@ -161,26 +168,32 @@ IDIV_ON_FPU 1 deriv div_2_1_rv64gc rv64gc RADIX 32'd2 DIVCOPIES 32'd1 +IDIV_ON_FPU 0 deriv div_2_2_rv64gc rv64gc RADIX 32'd2 DIVCOPIES 32'd2 +IDIV_ON_FPU 0 deriv div_2_4_rv64gc rv64gc RADIX 32'd2 DIVCOPIES 32'd4 +IDIV_ON_FPU 0 deriv div_4_1_rv64gc rv64gc RADIX 32'd4 DIVCOPIES 32'd1 +IDIV_ON_FPU 0 deriv div_4_2_rv64gc rv64gc RADIX 32'd4 DIVCOPIES 32'd2 +IDIV_ON_FPU 0 deriv div_4_4_rv64gc rv64gc RADIX 32'd4 DIVCOPIES 32'd4 +IDIV_ON_FPU 0 deriv div_2_1i_rv64gc rv64gc div_2_1_rv64gc IDIV_ON_FPU 1 @@ -366,6 +379,7 @@ INSTR_CLASS_PRED 0 deriv noicache_rv32gc rv32gc ICACHE_SUPPORTED 0 +VIRTMEM_SUPPORTED 0 deriv nodcache_rv32gc rv32gc DCACHE_SUPPORTED 0 @@ -374,6 +388,31 @@ deriv nocache_rv32gc rv32gc ICACHE_SUPPORTED 0 DCACHE_SUPPORTED 0 +deriv noicache_rv64gc rv64gc +ICACHE_SUPPORTED 0 +VIRTMEM_SUPPORTED 0 +SVPBMT_SUPPORTED 0 +SVNAPOT_SUPPORTED 0 + +deriv nodcache_rv64gc rv64gc +DCACHE_SUPPORTED 0 +VIRTMEM_SUPPORTED 0 +ZICBOM_SUPPORTED 0 +ZICBOZ_SUPPORTED 0 +SVPBMT_SUPPORTED 0 +SVNAPOT_SUPPORTED 0 +MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12) + +deriv nocache_rv64gc rv64gc +ICACHE_SUPPORTED 0 +DCACHE_SUPPORTED 0 +VIRTMEM_SUPPORTED 0 +ZICBOM_SUPPORTED 0 +ZICBOZ_SUPPORTED 0 +SVPBMT_SUPPORTED 0 +SVNAPOT_SUPPORTED 0 +MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12) + deriv way_1_4096_512_rv32gc rv32gc DCACHE_NUMWAYS 32'd1 DCACHE_WAYSIZEINBYTES 32'd4096 @@ -402,20 +441,6 @@ deriv way_4_4096_256_rv32gc rv32gc way_4_4096_512_rv32gc DCACHE_LINELENINBITS 32'd256 ICACHE_LINELENINBITS 32'd256 -deriv way_4_4096_1024_rv32gc rv32gc way_4_4096_512_rv32gc -DCACHE_LINELENINBITS 32'd1024 -ICACHE_LINELENINBITS 32'd1024 - -deriv noicache_rv64gc rv64gc -ICACHE_SUPPORTED 0 - -deriv nodcache_rv64gc rv64gc -DCACHE_SUPPORTED 0 - -deriv nocache_rv64gc rv64gc -ICACHE_SUPPORTED 0 -DCACHE_SUPPORTED 0 - deriv way_1_4096_512_rv64gc rv64gc DCACHE_NUMWAYS 32'd1 DCACHE_WAYSIZEINBYTES 32'd4096 diff --git a/config/shared/config-shared.vh b/config/shared/config-shared.vh index ba215785c..6f25b0cc5 100644 --- a/config/shared/config-shared.vh +++ b/config/shared/config-shared.vh @@ -103,7 +103,7 @@ localparam RESBITS = DIVMINb + LOGR; // number of bits in a result: r intege localparam FPDUR = (RESBITS-1)/RK + 1 ; // ceiling((r+b)/rk) localparam DIVb = FPDUR*RK - LOGR; // divsqrt fractional bits, so total number of bits is a multiple of rk after r integer bits localparam DURLEN = $clog2(FPDUR); // enough bits to count the duration -localparam DIVBLEN = $clog2(DIVb); // enough bits to count number of fractional bits +localparam DIVBLEN = $clog2(DIVb+1); // enough bits to count number of fractional bits + 1 integer bit // largest length in IEU/FPU localparam CVTLEN = ((NF 0 ]; then + echo -e "${RED}Linting failed for $fails of ${#configs[@]} configurations" + exit 1 +fi +echo -e "${GREEN}All ${#configs[@]} lints run with no errors or warnings" # --lint-only just runs lint rather than trying to compile and simulate # -I points to the include directory where files such as `include config.vh are found diff --git a/sim/regression-wally b/sim/regression-wally index 07c3774ed..5f4e68bf1 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -85,7 +85,7 @@ for test in tests64i: configs.append(tc) tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused -tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zfh", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zfad", +tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zicond", "arch32zba", "arch32zbb", "arch32zbs", "arch32zfh", "arch32zfaf", "wally32a", "wally32priv", "wally32periph"] # "arch32zbc", "arch32zfad", #tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"] for test in tests32gc: tc = TestCase( @@ -124,16 +124,7 @@ for test in tests32e: grepstr="All tests ran without failures") configs.append(tc) -ahbTests = [("0", "0"), ("0", "1"), ("1", "0"), ("1", "1"), ("2", "0"), ("2", "1")] -for test in ahbTests: - tc = TestCase( - name="ram_latency_" + test[0] + "_burst_en_" + test[1], - variant="ahb", - cmd="vsim > {} -c < XLEN +# ["nodcache_rv32gc", ["ahb32"]], +# ["nocache_rv32gc", ["ahb32"]], + ["noicache_rv64gc", ["ahb64"]], + ["nodcache_rv64gc", ["ahb64"]], + ["nocache_rv64gc", ["ahb64"]], + + ### add misaligned tests + ["div_2_1_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]], ["div_2_1i_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]], ["div_2_2_rv32gc", ["arch32f_divsqrt", "arch32d_divsqrt", "arch32m"]], @@ -215,6 +215,19 @@ if (nightly): ["div_4_4_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]], ["div_4_4i_rv64gc", ["arch64f_divsqrt", "arch64d_divsqrt", "arch64m"]], +# enable floating-point tests when lint is fixed +# ["f_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma"]], +# ["fh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32zfh", "arch32zfh_divsqrt"]], +# ["fdh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]], +# ["fdq_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]], +# ["fdqh_rv32gc", ["arch32f", "arch32f_divsqrt", "arch32f_fma", "arch32d", "arch32d_divsqrt", "arch32d_fma", "arch32zfh", "arch32zfh_divsqrt"]], +# ["f_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma"]], +# ["fh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64zfh", "arch64zfh_divsqrt"]], # hanging 1/31/24 dh; try again when lint is fixed +# ["fdh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]], +# ["fdq_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]], +# ["fdqh_rv64gc", ["arch64f", "arch64f_divsqrt", "arch64f_fma", "arch64d", "arch64d_divsqrt", "arch64d_fma", "arch64zfh", "arch64zfh_divsqrt"]], + + ] for test in derivconfigtests: config = test[0]; diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 8af2848a8..7f8c52997 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -21,14 +21,7 @@ onbreak {resume} # create library -if {$2 eq "ahb"} { - if [file exists wkdir/work_${1}_${2}_${3}_${4}] { - vdel -lib wkdir/work_${1}_${2}_${3}_${4} -all - } - vlib wkdir/work_${1}_${2}_${3}_${4} - - -} elseif {$2 eq "configOptions"} { +if {$2 eq "configOptions"} { if [file exists wkdir/work_${1}_${3}_${4}] { vdel -lib wkdir/work_${1}_${3}_${4} -all } @@ -86,22 +79,6 @@ if {$2 eq "buildroot"} { 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} { diff --git a/sim/wally.do b/sim/wally.do index bc987e3d3..4c1a22074 100644 --- a/sim/wally.do +++ b/sim/wally.do @@ -77,12 +77,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { run 20 ms } else { - if {$2 eq "ahb"} { - vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4 - } else { - # *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings. - vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 - } + vlog +incdir+../config/$1 +incdir+../config/shared ../src/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt vsim workopt +nowarn3829 -fatal 7 diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index 85021d269..54957d530 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -278,9 +278,14 @@ module fpu import cvw::*; #(parameter cvw_t P) ( end else assign FliResE = '0; // fmv.*.x: NaN Box SrcA to extend integer to requested FP size - if(P.FPSIZES == 1) assign PreIntSrcE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}; + if(P.FPSIZES == 1) + if (P.FLEN >= P.XLEN) assign PreIntSrcE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}; + else assign PreIntSrcE = ForwardedSrcAE[P.FLEN-1:0]; else if(P.FPSIZES == 2) - mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, PreIntSrcE); + if (P.FLEN >= P.XLEN) + mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, PreIntSrcE); + else + mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, ForwardedSrcAE[P.FLEN-1:0], FmtE, PreIntSrcE); else if(P.FPSIZES == 3 | P.FPSIZES == 4) begin localparam XD_LEN = P.D_LEN < P.XLEN ? P.D_LEN : P.XLEN; // shorter of D_LEN and XLEN mux3 #(P.FLEN) SrcAMux ({{P.FLEN-P.S_LEN{1'b1}}, ForwardedSrcAE[P.S_LEN-1:0]}, diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index c997d58ff..2d0fd101e 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -406,7 +406,11 @@ module lsu import cvw::*; #(parameter cvw_t P) ( end if (P.F_SUPPORTED) - mux2 #(P.LLEN) datamux({{{P.LLEN-P.XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM); + if (P.FLEN >= P.XLEN) + mux2 #(P.LLEN) datamux({{{P.LLEN-P.XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM); + else + mux2 #(P.LLEN) datamux(IMAWriteDataM, {{{P.XLEN-P.FLEN}{1'b0}}, FWriteDataM}, FpLoadStoreM, IMAFWriteDataM); + else assign IMAFWriteDataM = IMAWriteDataM; ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv index dcbe7e32a..2fc7e06a8 100644 --- a/testbench/common/riscvassertions.sv +++ b/testbench/common/riscvassertions.sv @@ -21,53 +21,52 @@ module riscvassertions import cvw::*; #(parameter cvw_t P); initial begin - assert (P.PMP_ENTRIES == 0 || P.PMP_ENTRIES==16 || P.PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); - assert (P.S_SUPPORTED || P.VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); - assert (P.IDIV_BITSPERCYCLE == 1 || P.IDIV_BITSPERCYCLE==2 || P.IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); - assert (P.F_SUPPORTED || ~P.D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)"); - assert (P.D_SUPPORTED || ~P.Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)"); - assert (P.F_SUPPORTED || ~P.ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); - assert (P.DCACHE_SUPPORTED || ~P.F_SUPPORTED || P.FLEN <= P.XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); - assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $error("Exactly one of I and E must be supported"); - assert (P.FLEN<=P.XLEN || P.DCACHE_SUPPORTED || P.DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); - assert (P.DCACHE_WAYSIZEINBYTES <= 4096 || (!P.DCACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (P.DCACHE_LINELENINBITS >= 128 || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); - assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); - assert (P.ICACHE_WAYSIZEINBYTES <= 4096 || (!P.ICACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (P.ICACHE_LINELENINBITS >= 32 || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); - assert (P.ICACHE_LINELENINBITS < P.ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); - assert (2**$clog2(P.DCACHE_LINELENINBITS) == P.DCACHE_LINELENINBITS || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(P.DCACHE_WAYSIZEINBYTES) == P.DCACHE_WAYSIZEINBYTES || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(P.ICACHE_LINELENINBITS) == P.ICACHE_LINELENINBITS || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(P.ICACHE_WAYSIZEINBYTES) == P.ICACHE_WAYSIZEINBYTES || (!P.ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(P.ITLB_ENTRIES) == P.ITLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); - assert (2**$clog2(P.DTLB_ENTRIES) == P.DTLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); + assert (P.PMP_ENTRIES == 0 || P.PMP_ENTRIES==16 || P.PMP_ENTRIES==64) else $fatal(1, "Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); + assert (P.S_SUPPORTED || P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "Virtual memory requires S mode support"); + assert (P.IDIV_BITSPERCYCLE == 1 || P.IDIV_BITSPERCYCLE==2 || P.IDIV_BITSPERCYCLE==4) else $fatal(1, "Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); + assert (P.F_SUPPORTED || ~P.D_SUPPORTED) else $fatal(1, "Can't support double fp (D) without supporting float (F)"); + assert (P.D_SUPPORTED || ~P.Q_SUPPORTED) else $fatal(1, "Can't support quad fp (Q) without supporting double (D)"); + assert (P.F_SUPPORTED || ~P.ZFH_SUPPORTED) else $fatal(1, "Can't support half-precision fp (ZFH) without supporting float (F)"); + assert (P.DCACHE_SUPPORTED || ~P.F_SUPPORTED || P.FLEN <= P.XLEN) else $fatal(1, "Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); + assert (P.I_SUPPORTED ^ P.E_SUPPORTED) else $fatal(1, "Exactly one of I and E must be supported"); + assert (P.FLEN<=P.XLEN || P.DCACHE_SUPPORTED || P.DTIM_SUPPORTED) else $fatal(1, "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_LINELENINBITS >= 128 || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); + assert (P.DCACHE_LINELENINBITS < P.DCACHE_WAYSIZEINBYTES*8) else $fatal(1, "DCACHE_LINELENINBITS must be smaller than way size"); + assert (P.ICACHE_WAYSIZEINBYTES <= 4096 || (!P.ICACHE_SUPPORTED) || P.VIRTMEM_SUPPORTED == 0) else $fatal(1, "ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); + assert (P.ICACHE_LINELENINBITS >= 32 || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); + assert (P.ICACHE_LINELENINBITS < P.ICACHE_WAYSIZEINBYTES*8) else $fatal(1, "ICACHE_LINELENINBITS must be smaller than way size"); + assert (2**$clog2(P.DCACHE_LINELENINBITS) == P.DCACHE_LINELENINBITS || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must be a power of 2"); + assert (2**$clog2(P.DCACHE_WAYSIZEINBYTES) == P.DCACHE_WAYSIZEINBYTES || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_WAYSIZEINBYTES must be a power of 2"); + assert (2**$clog2(P.ICACHE_LINELENINBITS) == P.ICACHE_LINELENINBITS || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_LINELENINBITS must be a power of 2"); + assert (2**$clog2(P.ICACHE_WAYSIZEINBYTES) == P.ICACHE_WAYSIZEINBYTES || (!P.ICACHE_SUPPORTED)) else $fatal(1, "ICACHE_WAYSIZEINBYTES must be a power of 2"); + assert (2**$clog2(P.ITLB_ENTRIES) == P.ITLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $fatal(1, "ITLB_ENTRIES must be a power of 2"); + assert (2**$clog2(P.DTLB_ENTRIES) == P.DTLB_ENTRIES || P.VIRTMEM_SUPPORTED==0) else $fatal(1, "DTLB_ENTRIES must be a power of 2"); assert (P.UNCORE_RAM_RANGE >= 64'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 64'h07FFFFFF"); - assert (P.ZICSR_SUPPORTED == 1 || (P.PMP_ENTRIES == 0 && P.VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); - assert (P.ZICSR_SUPPORTED == 1 || (P.S_SUPPORTED == 0 && P.U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported"); + assert (P.ZICSR_SUPPORTED == 1 || (P.PMP_ENTRIES == 0 && P.VIRTMEM_SUPPORTED == 0)) else $fatal(1, "PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); + assert (P.ZICSR_SUPPORTED == 1 || (P.S_SUPPORTED == 0 && P.U_SUPPORTED == 0)) else $fatal(1, "S and U modes not supported if ZICSR not supported"); assert (P.U_SUPPORTED || (P.S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported"); - assert (P.VIRTMEM_SUPPORTED == 0 || (P.DTIM_SUPPORTED == 0 && P.IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); - assert (P.DCACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); - assert (P.ICACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); - assert ((P.DCACHE_SUPPORTED == 0 && P.ICACHE_SUPPORTED == 0) || P.BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED."); - assert (P.DCACHE_LINELENINBITS <= P.XLEN*16 || (!P.DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); - assert (P.DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); - assert (P.DCACHE_SUPPORTED || (P.A_SUPPORTED == 0)) else $error("Atomic extension (A) requires cache on Wally."); - assert (P.IDIV_ON_FPU == 0 || P.F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); - assert (P.SSTC_SUPPORTED == 0 || (P.S_SUPPORTED)) else $error("SSTC requires S_SUPPORTED"); - assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled"); - assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED"); - assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $error("ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED"); - assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOM requires DCACHE_SUPPORTED"); - assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOZ requires DCACHE_SUPPORTED"); - assert ((P.ZICBOP_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOP requires DCACHE_SUPPORTED"); - assert ((P.SVPBMT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVPBMT requires VIRTMEM_SUPPORTED and RV64"); - assert ((P.SVNAPOT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $error("SVNAPOT requires VIRTMEM_SUPPORTED and RV64"); - assert ((P.ZCB_SUPPORTED == 0) || (P.M_SUPPORTED == 1 && (P.ZBA_SUPPORTED == 1 || P.XLEN == 32) && P.ZBB_SUPPORTED == 1)) else $error("ZCB requires M and ZBB (and also ZBA for RV64)"); - assert ((P.C_SUPPORTED == 0) || (P.ZCA_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0 && P.ZCD_SUPPORTED == 0)) else $error("C and ZCA/ZCD/ZCF cannot simultaneously be supported"); - assert ((P.ZCA_SUPPORTED == 1) || (P.ZCD_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0)) else $error("ZCF or ZCD requires ZCA"); - assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $error("ZCF requires F"); - assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $error("ZCD requires D"); + assert (P.VIRTMEM_SUPPORTED == 0 || (P.DTIM_SUPPORTED == 0 && P.IROM_SUPPORTED == 0)) else $fatal(1, "Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); + assert (P.DCACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $fatal(1, "Virtual memory needs dcache"); + assert (P.ICACHE_SUPPORTED || P.VIRTMEM_SUPPORTED ==0) else $fatal(1, "Virtual memory needs icache"); + assert ((P.DCACHE_SUPPORTED == 0 && P.ICACHE_SUPPORTED == 0) || P.BUS_SUPPORTED) else $fatal(1, "Dcache and Icache requires DBUS_SUPPORTED."); + assert (P.DCACHE_LINELENINBITS <= P.XLEN*16 || (!P.DCACHE_SUPPORTED)) else $fatal(1, "DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 16"); + assert (P.DCACHE_LINELENINBITS % 4 == 0) else $fatal(1, "DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); + assert (P.DCACHE_SUPPORTED || (P.A_SUPPORTED == 0)) else $fatal(1, "Atomic extension (A) requires cache on Wally."); + assert (P.IDIV_ON_FPU == 0 || P.F_SUPPORTED) else $fatal(1, "IDIV on FPU needs F_SUPPORTED"); + assert (P.SSTC_SUPPORTED == 0 || (P.S_SUPPORTED)) else $fatal(1, "SSTC requires S_SUPPORTED"); + assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $fatal(1, "At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled"); + assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $fatal(1, "ZICNTR_SUPPORTED requires ZICSR_SUPPORTED"); + assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $fatal(1, "ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED"); + assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICBOM requires DCACHE_SUPPORTED"); + assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICBOZ requires DCACHE_SUPPORTED"); + assert ((P.SVPBMT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $fatal(1, "SVPBMT requires VIRTMEM_SUPPORTED and RV64"); + assert ((P.SVNAPOT_SUPPORTED == 0) || (P.VIRTMEM_SUPPORTED == 1 && P.XLEN==64)) else $fatal(1, "SVNAPOT requires VIRTMEM_SUPPORTED and RV64"); + assert ((P.ZCB_SUPPORTED == 0) || (P.M_SUPPORTED == 1 && (P.ZBA_SUPPORTED == 1 || P.XLEN == 32) && P.ZBB_SUPPORTED == 1)) else $fatal(1, "ZCB requires M and ZBB (and also ZBA for RV64)"); + assert ((P.C_SUPPORTED == 0) || (P.ZCA_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0 && P.ZCD_SUPPORTED == 0)) else $fatal(1, "C and ZCA/ZCD/ZCF cannot simultaneously be supported"); + assert ((P.ZCA_SUPPORTED == 1) || (P.ZCD_SUPPORTED == 0 && P.ZCF_SUPPORTED == 0)) else $fatal(1, "ZCF or ZCD requires ZCA"); + assert ((P.ZCF_SUPPORTED == 0) || (P.F_SUPPORTED == 1)) else $fatal(1, "ZCF requires F"); + assert ((P.ZCD_SUPPORTED == 0) || (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D"); end endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 893eb678b..eafcce2e6 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -121,7 +121,7 @@ module testbench; "wally64periph": tests = wally64periph; "coremark": tests = coremark; "fpga": tests = fpga; - "ahb" : tests = ahb; + "ahb64" : tests = ahb64; "coverage64gc" : tests = coverage64gc; "arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba; "arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb; @@ -162,6 +162,7 @@ module testbench; "wally32i": tests = wally32i; "wally32priv": tests = wally32priv; "wally32periph": tests = wally32periph; + "ahb32" : tests = ahb32; "embench": tests = embench; "coremark": tests = coremark; "arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba; diff --git a/testbench/tests.vh b/testbench/tests.vh index f5c9cc0ac..42f3d703a 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -2472,7 +2472,12 @@ string arch64zbs[] = '{ }; - string ahb[] = '{ + string ahb64[] = '{ `RISCVARCHTEST, "rv64i_m/F/src/fadd_b11-01.S" }; + + string ahb32[] = '{ + `RISCVARCHTEST, + "rv32i_m/F/src/fadd_b11-01.S" + };