diff --git a/benchmarks/embench/Makefile b/benchmarks/embench/Makefile index 538fb64f9..3dba4daaa 100644 --- a/benchmarks/embench/Makefile +++ b/benchmarks/embench/Makefile @@ -16,10 +16,18 @@ buildsize: build_speedopt_size build_sizeopt_size # uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for speed and size build_speedopt_speed: $(embench_dir)/build_all.py --builddir=bd_speedopt_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-O2 -nostartfiles" + # remove files not used in embench1.0 When changing to 2.0, restore these files + #rm -rf $(embench_dir)/bd_speedopt_speed/src/md5sum + #rm -rf $(embench_dir)/bd_speedopt_speed/src/tarfind + #rm -rf $(embench_dir)/bd_speedopt_speed/src/primecount find $(embench_dir)/bd_speedopt_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done build_sizeopt_speed: $(embench_dir)/build_all.py --builddir=bd_sizeopt_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-Os -nostartfiles" + # remove files not used in embench1.0 When changing to 2.0, restore these files + #rm -rf $(embench_dir)/bd_sizeopt_speed/src/md5sum + #rm -rf $(embench_dir)/bd_sizeopt_speed/src/tarfind + #rm -rf $(embench_dir)/bd_sizeopt_speed/src/primecount find $(embench_dir)/bd_sizeopt_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done # uses the build_all.py python file to build the tests in addins/embench-iot/bd_speed/ optimized for speed and size diff --git a/config/rv32e/wally-config.vh b/config/rv32e/wally-config.vh deleted file mode 100644 index 700117e3d..000000000 --- a/config/rv32e/wally-config.vh +++ /dev/null @@ -1,156 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 32 - -// IEEE 754 compliance -`define IEEE754 0 - -// E -`define MISA (32'h00000010) -`define ZICSR_SUPPORTED 0 -`define ZIFENCEI_SUPPORTED 0 -`define COUNTERS 0 -`define ZICOUNTERS_SUPPORTED 0 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 0 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 1 -`define DCACHE_SUPPORTED 0 -`define ICACHE_SUPPORTED 0 -`define VIRTMEM_SUPPORTED 0 -`define VECTORED_INTERRUPTS_SUPPORTED 0 -`define BIGENDIAN_SUPPORTED 0 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 0 -`define DTLB_ENTRIES 0 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 1 -`define IDIV_ON_FPU 0 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 0 - -// Address space -`define RESET_VECTOR 32'h80000000 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// 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 -`define DTIM_SUPPORTED 1'b0 -`define DTIM_BASE 34'h80000000 -`define DTIM_RANGE 34'h007FFFFF -`define IROM_SUPPORTED 1'b0 -`define IROM_BASE 34'h80000000 -`define IROM_RANGE 34'h007FFFFF -`define BOOTROM_SUPPORTED 1'b1 -`define BOOTROM_BASE 34'h00001000 -`define BOOTROM_RANGE 34'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b1 -`define UNCORE_RAM_BASE 34'h80000000 -`define UNCORE_RAM_RANGE 34'h07FFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 34'h80000000 -`define EXT_MEM_RANGE 34'h07FFFFFF -`define CLINT_SUPPORTED 1'b0 -`define CLINT_BASE 34'h02000000 -`define CLINT_RANGE 34'h0000FFFF -`define GPIO_SUPPORTED 1'b0 -`define GPIO_BASE 34'h10060000 -`define GPIO_RANGE 34'h000000FF -`define UART_SUPPORTED 1'b0 -`define UART_BASE 34'h10000000 -`define UART_RANGE 34'h00000007 -`define PLIC_SUPPORTED 1'b0 -`define PLIC_BASE 34'h0C000000 -`define PLIC_RANGE 34'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 34'h00012100 -`define SDC_RANGE 34'h0000001F - -// Bus Interface width -`define AHBW 32 - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 6 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 0 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 0 -`define ZBB_SUPPORTED 0 -`define ZBC_SUPPORTED 0 -`define ZBS_SUPPORTED 0 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv32gc/wally-config.vh b/config/rv32gc/wally-config.vh deleted file mode 100644 index 4eb71c54e..000000000 --- a/config/rv32gc/wally-config.vh +++ /dev/null @@ -1,155 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 32 - -// IEEE 754 compliance -`define IEEE754 0 - -`define MISA (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12 | 1 << 0 | 1 <<3 | 1 << 5) -`define ZICSR_SUPPORTED 1 -`define ZIFENCEI_SUPPORTED 1 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 1 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 1 -`define DCACHE_SUPPORTED 1 -`define ICACHE_SUPPORTED 1 -`define VIRTMEM_SUPPORTED 1 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 1 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 32 -`define DTLB_ENTRIES 32 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 4 -`define IDIV_ON_FPU 1 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 16 - -// Address space -`define RESET_VECTOR 32'h80000000 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// 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 -`define DTIM_SUPPORTED 1'b0 -`define DTIM_BASE 34'h80000000 -`define DTIM_RANGE 34'h007FFFFF -`define IROM_SUPPORTED 1'b0 -`define IROM_BASE 34'h80000000 -`define IROM_RANGE 34'h007FFFFF -`define BOOTROM_SUPPORTED 1'b1 -`define BOOTROM_BASE 34'h00001000 -`define BOOTROM_RANGE 34'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b1 -`define UNCORE_RAM_BASE 34'h80000000 -`define UNCORE_RAM_RANGE 34'h07FFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 34'h80000000 -`define EXT_MEM_RANGE 34'h07FFFFFF -`define CLINT_SUPPORTED 1'b1 -`define CLINT_BASE 34'h02000000 -`define CLINT_RANGE 34'h0000FFFF -`define GPIO_SUPPORTED 1'b1 -`define GPIO_BASE 34'h10060000 -`define GPIO_RANGE 34'h000000FF -`define UART_SUPPORTED 1'b1 -`define UART_BASE 34'h10000000 -`define UART_RANGE 34'h00000007 -`define PLIC_SUPPORTED 1'b1 -`define PLIC_BASE 34'h0C000000 -`define PLIC_RANGE 34'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 34'h00012100 -`define SDC_RANGE 34'h0000001F - -// Bus Interface width -`define AHBW 32 - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE" // "BP_LOCAL_REPAIR" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 16 -`define BPRED_NUM_LHR 8 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 1 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 1 -`define ZBB_SUPPORTED 1 -`define ZBC_SUPPORTED 1 -`define ZBS_SUPPORTED 1 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv32i/wally-config.vh b/config/rv32i/wally-config.vh deleted file mode 100644 index 585499169..000000000 --- a/config/rv32i/wally-config.vh +++ /dev/null @@ -1,156 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 32 - -// IEEE 754 compliance -`define IEEE754 0 - -// I -`define MISA (32'h00000104) -`define ZICSR_SUPPORTED 0 -`define ZIFENCEI_SUPPORTED 0 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 0 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 0 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 0 -`define DCACHE_SUPPORTED 0 -`define ICACHE_SUPPORTED 0 -`define VIRTMEM_SUPPORTED 0 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 0 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 32 -`define DTLB_ENTRIES 32 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 4 -`define IDIV_ON_FPU 0 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 0 - -// Address space -`define RESET_VECTOR 32'h80000000 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// 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 -`define DTIM_SUPPORTED 1'b1 -`define DTIM_BASE 34'h80000000 -`define DTIM_RANGE 34'h007FFFFF -`define IROM_SUPPORTED 1'b1 -`define IROM_BASE 34'h80000000 -`define IROM_RANGE 34'h007FFFFF -`define BOOTROM_SUPPORTED 1'b0 -`define BOOTROM_BASE 34'h00001000 -`define BOOTROM_RANGE 34'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b0 -`define UNCORE_RAM_BASE 34'h80000000 -`define UNCORE_RAM_RANGE 34'h07FFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 34'h80000000 -`define EXT_MEM_RANGE 34'h07FFFFFF -`define CLINT_SUPPORTED 1'b0 -`define CLINT_BASE 34'h02000000 -`define CLINT_RANGE 34'h0000FFFF -`define GPIO_SUPPORTED 1'b0 -`define GPIO_BASE 34'h10060000 -`define GPIO_RANGE 34'h000000FF -`define UART_SUPPORTED 1'b0 -`define UART_BASE 34'h10000000 -`define UART_RANGE 34'h00000007 -`define PLIC_SUPPORTED 1'b0 -`define PLIC_BASE 34'h0C000000 -`define PLIC_RANGE 34'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 34'h00012100 -`define SDC_RANGE 34'h0000001F - -// Bus Interface width -`define AHBW 32 - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 6 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 0 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 0 -`define ZBB_SUPPORTED 0 -`define ZBC_SUPPORTED 0 -`define ZBS_SUPPORTED 0 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv32imc/wally-config.vh b/config/rv32imc/wally-config.vh deleted file mode 100644 index 093d92bd7..000000000 --- a/config/rv32imc/wally-config.vh +++ /dev/null @@ -1,155 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 32 - -// IEEE 754 compliance -`define IEEE754 0 - -`define MISA (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12) -`define ZICSR_SUPPORTED 1 -`define ZIFENCEI_SUPPORTED 1 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 0 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 1 -`define DCACHE_SUPPORTED 0 -`define ICACHE_SUPPORTED 0 -`define VIRTMEM_SUPPORTED 0 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 0 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 0 -`define DTLB_ENTRIES 0 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 2 -`define IDIV_ON_FPU 0 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 0 - -// Address space -`define RESET_VECTOR 32'h80000000 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// 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 -`define DTIM_SUPPORTED 1'b1 -`define DTIM_BASE 34'h80000000 -`define DTIM_RANGE 34'h007FFFFF -`define IROM_SUPPORTED 1'b1 -`define IROM_BASE 34'h80000000 -`define IROM_RANGE 34'h007FFFFF -`define BOOTROM_SUPPORTED 1'b0 -`define BOOTROM_BASE 34'h00001000 -`define BOOTROM_RANGE 34'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b0 -`define UNCORE_RAM_BASE 34'h80000000 -`define UNCORE_RAM_RANGE 34'h07FFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 34'h80000000 -`define EXT_MEM_RANGE 34'h07FFFFFF -`define CLINT_SUPPORTED 1'b1 -`define CLINT_BASE 34'h02000000 -`define CLINT_RANGE 34'h0000FFFF -`define GPIO_SUPPORTED 1'b1 -`define GPIO_BASE 34'h10060000 -`define GPIO_RANGE 34'h000000FF -`define UART_SUPPORTED 1'b1 -`define UART_BASE 34'h10000000 -`define UART_RANGE 34'h00000007 -`define PLIC_SUPPORTED 1'b1 -`define PLIC_BASE 34'h0C000000 -`define PLIC_RANGE 34'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 34'h00012100 -`define SDC_RANGE 34'h0000001F - -// Bus Interface width -`define AHBW 32 - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 6 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 0 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 0 -`define ZBB_SUPPORTED 0 -`define ZBC_SUPPORTED 0 -`define ZBS_SUPPORTED 0 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv64fpquad/wally-config.vh b/config/rv64fpquad/wally-config.vh deleted file mode 100644 index 45725645f..000000000 --- a/config/rv64fpquad/wally-config.vh +++ /dev/null @@ -1,158 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 64 - -// IEEE 754 compliance -`define IEEE754 0 - -// MISA RISC-V configuration per specification -`define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 ) -`define ZICSR_SUPPORTED 1 -`define ZIFENCEI_SUPPORTED 1 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 1 -`define SSTC_SUPPORTED 0 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 1 -`define DCACHE_SUPPORTED 1 -`define ICACHE_SUPPORTED 1 -`define VIRTMEM_SUPPORTED 1 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 1 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 32 -`define DTLB_ENTRIES 32 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 4 -`define IDIV_ON_FPU 1 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 16 - -// Address space -`define RESET_VECTOR 64'h0000000080000000 - -// Bus Interface width -`define AHBW 64 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// Peripheral Physiccal 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 - -// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file? -`define DTIM_SUPPORTED 1'b0 -`define DTIM_BASE 56'h80000000 -`define DTIM_RANGE 56'h007FFFFF -`define IROM_SUPPORTED 1'b0 -`define IROM_BASE 56'h80000000 -`define IROM_RANGE 56'h007FFFFF -`define BOOTROM_SUPPORTED 1'b1 -`define BOOTROM_BASE 56'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder -`define BOOTROM_RANGE 56'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b1 -`define UNCORE_RAM_BASE 56'h80000000 -`define UNCORE_RAM_RANGE 56'h7FFFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 56'h80000000 -`define EXT_MEM_RANGE 56'h07FFFFFF -`define CLINT_SUPPORTED 1'b1 -`define CLINT_BASE 56'h02000000 -`define CLINT_RANGE 56'h0000FFFF -`define GPIO_SUPPORTED 1'b1 -`define GPIO_BASE 56'h10060000 -`define GPIO_RANGE 56'h000000FF -`define UART_SUPPORTED 1'b1 -`define UART_BASE 56'h10000000 -`define UART_RANGE 56'h00000007 -`define PLIC_SUPPORTED 1'b1 -`define PLIC_BASE 56'h0C000000 -`define PLIC_RANGE 56'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 56'h00012100 -`define SDC_RANGE 56'h0000001F - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 1 -`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 6 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 0 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 0 -`define ZBB_SUPPORTED 0 -`define ZBC_SUPPORTED 0 -`define ZBS_SUPPORTED 0 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv64gc/wally-config.vh b/config/rv64gc/wally-config.vh deleted file mode 100644 index 1dd3d7f4f..000000000 --- a/config/rv64gc/wally-config.vh +++ /dev/null @@ -1,159 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 64 - -// IEEE 754 compliance -`define IEEE754 0 - -// MISA RISC-V configuration per specification -`define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 ) -`define ZICSR_SUPPORTED 1 -`define ZIFENCEI_SUPPORTED 1 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 1 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 1 -`define DCACHE_SUPPORTED 1 -`define ICACHE_SUPPORTED 1 -`define VIRTMEM_SUPPORTED 1 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 1 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 32 -`define DTLB_ENTRIES 32 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 4 -`define IDIV_ON_FPU 1 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 16 - -// Address space -`define RESET_VECTOR 64'h0000000080000000 - -// Bus Interface width -`define AHBW 64 - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// Peripheral Physical 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 - -// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file? -`define DTIM_SUPPORTED 1'b0 -`define DTIM_BASE 56'h80000000 -`define DTIM_RANGE 56'h007FFFFF -`define IROM_SUPPORTED 1'b0 -`define IROM_BASE 56'h80000000 -`define IROM_RANGE 56'h007FFFFF -`define BOOTROM_SUPPORTED 1'b1 -`define BOOTROM_BASE 56'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder -`define BOOTROM_RANGE 56'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b1 -`define UNCORE_RAM_BASE 56'h80000000 -`define UNCORE_RAM_RANGE 56'h7FFFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 56'h80000000 -`define EXT_MEM_RANGE 56'h07FFFFFF -`define CLINT_SUPPORTED 1'b1 -`define CLINT_BASE 56'h02000000 -`define CLINT_RANGE 56'h0000FFFF -`define GPIO_SUPPORTED 1'b1 -`define GPIO_BASE 56'h10060000 -`define GPIO_RANGE 56'h000000FF -`define UART_SUPPORTED 1'b1 -`define UART_BASE 56'h10000000 -`define UART_RANGE 56'h00000007 -`define PLIC_SUPPORTED 1'b1 -`define PLIC_BASE 56'h0C000000 -`define PLIC_RANGE 56'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 56'h00012100 -`define SDC_RANGE 56'h0000001F - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 1 -//`define BPRED_TYPE "BP_GLOBAL_BASIC" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_TYPE "BP_GSHARE" // "BP_LOCAL_REPAIR" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 4 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 1 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 1 -`define ZBB_SUPPORTED 1 -`define ZBC_SUPPORTED 1 -`define ZBS_SUPPORTED 1 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/rv64i/wally-config.vh b/config/rv64i/wally-config.vh deleted file mode 100644 index 61ac725db..000000000 --- a/config/rv64i/wally-config.vh +++ /dev/null @@ -1,158 +0,0 @@ -////////////////////////////////////////// -// wally-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 "wally-shared.vh" - -`define FPGA 0 -`define QEMU 0 - -// RV32 or RV64: XLEN = 32 or 64 -`define XLEN 64 - -// IEEE 754 compliance -`define IEEE754 0 - -// MISA RISC-V configuration per specification -`define MISA (32'h00000104) -`define ZICSR_SUPPORTED 0 -`define ZIFENCEI_SUPPORTED 0 -`define COUNTERS 32 -`define ZICOUNTERS_SUPPORTED 0 -`define ZFH_SUPPORTED 0 -`define SSTC_SUPPORTED 0 - -// LSU microarchitectural Features -`define BUS_SUPPORTED 0 -`define DCACHE_SUPPORTED 0 -`define ICACHE_SUPPORTED 0 -`define VIRTMEM_SUPPORTED 0 -`define VECTORED_INTERRUPTS_SUPPORTED 1 -`define BIGENDIAN_SUPPORTED 0 - -// TLB configuration. Entries should be a power of 2 -`define ITLB_ENTRIES 0 -`define DTLB_ENTRIES 0 - -// Cache configuration. Sizes should be a power of two -// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines -`define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 4096 -`define DCACHE_LINELENINBITS 512 -`define ICACHE_NUMWAYS 4 -`define ICACHE_WAYSIZEINBYTES 4096 -`define ICACHE_LINELENINBITS 512 - -// Integer Divider Configuration -// IDIV_BITSPERCYCLE must be 1, 2, or 4 -`define IDIV_BITSPERCYCLE 4 -`define IDIV_ON_FPU 0 - -// Legal number of PMP entries are 0, 16, or 64 -`define PMP_ENTRIES 0 - -// Address space -`define RESET_VECTOR 64'h0000000080000000 - -// Bus Interface width -`define AHBW (`XLEN) - -// WFI Timeout Wait -`define WFI_TIMEOUT_BIT 16 - -// Peripheral Physiccal 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 - -// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file? -`define DTIM_SUPPORTED 1'b1 -`define DTIM_BASE 56'h80000000 -`define DTIM_RANGE 56'h007FFFFF -`define IROM_SUPPORTED 1'b1 -`define IROM_BASE 56'h80000000 -`define IROM_RANGE 56'h007FFFFF -`define BOOTROM_SUPPORTED 1'b0 -`define BOOTROM_BASE 56'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder -`define BOOTROM_RANGE 56'h00000FFF -`define UNCORE_RAM_SUPPORTED 1'b0 -`define UNCORE_RAM_BASE 56'h80000000 -`define UNCORE_RAM_RANGE 56'h7FFFFFFF -`define EXT_MEM_SUPPORTED 1'b0 -`define EXT_MEM_BASE 56'h80000000 -`define EXT_MEM_RANGE 56'h07FFFFFF -`define CLINT_SUPPORTED 1'b0 -`define CLINT_BASE 56'h02000000 -`define CLINT_RANGE 56'h0000FFFF -`define GPIO_SUPPORTED 1'b0 -`define GPIO_BASE 56'h10060000 -`define GPIO_RANGE 56'h000000FF -`define UART_SUPPORTED 1'b0 -`define UART_BASE 56'h10000000 -`define UART_RANGE 56'h00000007 -`define PLIC_SUPPORTED 1'b0 -`define PLIC_BASE 56'h0C000000 -`define PLIC_RANGE 56'h03FFFFFF -`define SDC_SUPPORTED 1'b0 -`define SDC_BASE 56'h00012100 -`define SDC_RANGE 56'h0000001F - -// Test modes - -// Tie GPIO outputs back to inputs -`define GPIO_LOOPBACK_TEST 1 - -// Hardware configuration -`define UART_PRESCALE 1 - -// Interrupt configuration -`define PLIC_NUM_SRC 10 -// comment out the following if >=32 sources -`define PLIC_NUM_SRC_LT_32 -`define PLIC_GPIO_ID 3 -`define PLIC_UART_ID 10 - -`define BPRED_SUPPORTED 0 -`define BPRED_TYPE "BP_GSHARE" // BP_GSHARE_BASIC, BP_GLOBAL, BP_GLOBAL_BASIC, BP_TWOBIT -`define BPRED_SIZE 10 -`define BPRED_NUM_LHR 6 -`define BTB_SIZE 10 - -`define SVADU_SUPPORTED 0 -`define ZMMUL_SUPPORTED 0 - -// FPU division architecture -`define RADIX 32'h4 -`define DIVCOPIES 32'h4 - -// bit manipulation -`define ZBA_SUPPORTED 0 -`define ZBB_SUPPORTED 0 -`define ZBC_SUPPORTED 0 -`define ZBS_SUPPORTED 0 - -// Memory synthesis configuration -`define USE_SRAM 0 diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index e897f3dd0..713a947e8 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -81,7 +81,7 @@ parameter cvw_t P = '{ // *** definitely need to fix this. // it thinks we are casting from the enum type to BPRED_TYPE. BPRED_TYPE : BPRED_TYPE, - /* verilator lint_off ENUMVALUE */ + /* verilator lint_on ENUMVALUE */ BPRED_SIZE : BPRED_SIZE, BPRED_NUM_LHR : BPRED_NUM_LHR, BTB_SIZE : BTB_SIZE, diff --git a/sim/FPbuild.txt b/sim/FPbuild.txt index edb4a645c..99f414804 100644 --- a/sim/FPbuild.txt +++ b/sim/FPbuild.txt @@ -34,18 +34,14 @@ other FP tests given by the great SoftFloat/TestFloat output. 4a.) Each test will test all its vectors - if you want to test a subset of the vectors (e.g., only binary16), you should modify the -cvw/testbench/tests-fp.h and comment out the tests you do not want to -test. The best way to do this is to comment out each item out with -the // comment option in SV. For example, - -string f128div[] = '{ -// "f128_div_rne.tv", -// "f128_div_rz.tv", -// "f128_div_ru.tv", -// "f128_div_rd.tv", -// "f128_div_rnm.tv" -}; +testfloat.do in the sim directory. Change the TEST_SIZE="all" to the +specific test you want to run. For example, if you want to run only +binary16, you should set this variable to TEST_SIZE="HP". +4b.) If you want to turn off the generation of wlf files while running +sim-testfloat-batch, you can modify testfloat.do in the sim +directory. Inside this DO file, modify the WAV file to 0 --> i.e., +set "quietly set WAV 0;" diff --git a/sim/imperas.ic b/sim/imperas.ic index d561b22f2..ad19aaf68 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -1,7 +1,7 @@ #--mpdconsole #--gdbconsole ---showoverrides ---showcommands +#--showoverrides +#--showcommands # Core settings --override cpu/priv_version=1.12 diff --git a/sim/lint-wally b/sim/lint-wally index acad750b6..6db56b0a9 100755 --- a/sim/lint-wally +++ b/sim/lint-wally @@ -8,7 +8,7 @@ basepath=$(dirname $0)/.. for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do #for config in rv64gc; do echo "$config linting..." - if !($verilator --no-timing --lint-only "$@" --top-module wallypipelinedsoc "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/wally/cvw.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" $basepath/src/cvw.sv $basepath/testbench/wallywrapper.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then echo "Exiting after $config lint due to errors or warnings" exit 1 fi diff --git a/sim/sim-testfloat-batch b/sim/sim-testfloat-batch index 4cb03792e..31ff21a6c 100755 --- a/sim/sim-testfloat-batch +++ b/sim/sim-testfloat-batch @@ -10,6 +10,3 @@ # sqrt - test square root # all - test everything -# nowave for 2nd argument supresses wlf files - -vsim -c -do "do testfloat.do rv64fpquad $1 $2" \ No newline at end of file diff --git a/sim/sim-wally-batch b/sim/sim-wally-batch index 46c35c75c..f2c2a3c30 100755 --- a/sim/sim-wally-batch +++ b/sim/sim-wally-batch @@ -1 +1 @@ -vsim -c -do "do wally-batch.do rv32gc wally32priv" +vsim -c -do "do wally-batch.do rv64gc wally64priv" diff --git a/sim/testfloat.do b/sim/testfloat.do index c8e8ae7b4..ffa03dc8d 100644 --- a/sim/testfloat.do +++ b/sim/testfloat.do @@ -27,12 +27,16 @@ vlib work # $num = the added words after the call vlog +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-fp.sv ../src/fpu/*.sv ../src/fpu/*/*.sv ../src/generic/*.sv ../src/generic/flop/*.sv -suppress 2583,7063,8607,2697 -vsim -voptargs=+acc work.testbenchfp -G TEST=$2 +# Change TEST_SIZE to only test certain FP width +# values are QP, DP, SP, HP +vsim -voptargs=+acc work.testbenchfp -GTEST=$2 -GTEST_SIZE="all" -# Determine if nowave argument is provided -# this removes any output to a wlf or wave window to reduce -# disk space. -if {($argc > 2) && ($3 eq "nowave")} { +# Set WAV variable to avoid having any output to wave (to limit disk space) +quietly set WAV 1; + +# Determine if nowave argument is provided this removes any output to +# a wlf or wave window to reduce disk space. +if {$WAV eq 0} { puts "No wave output is selected" } else { puts "wave output is selected" diff --git a/sim/verilate b/sim/verilate index 345e17ab9..9555322f9 100755 --- a/sim/verilate +++ b/sim/verilate @@ -7,8 +7,8 @@ verilator=`which verilator` basepath=$(dirname $0)/.. #for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do for config in rv64gc; do - echo "$config linting..." - if !($verilator --cc "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/testbench/testbench.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then + echo "$config simulating..." + if !($verilator --timescale "1ns/1ns" --timing --cc "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/wally/cvw.sv $basepath/testbench/common/*.sv $basepath/testbench/testbench.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then echo "Exiting after $config lint due to errors or warnings" exit 1 fi diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 6b5acbb92..29d31bd25 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -59,7 +59,7 @@ if {$argc >= 3} { # default to config/rv64ic, but allow this to be overridden at the command line. For example: # do wally-pipelined-batch.do ../config/rv32imc rv32imc if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { - vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + vlog -lint -work wkdir/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 if { $coverage } { echo "wally-batch buildroot coverage" @@ -88,7 +88,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { exec ./slack-notifier/slack-notifier.py } elseif {$2 eq "ahb"} { - vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$1 +incdir+../config/shared ../src/wally/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 + vlog -lint -work wkdir/work_${1}_${2}_${3}_${4} +incdir+../config/$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 @@ -112,7 +112,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # **** 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/shared ../src/wally/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 $5 $6 $7 + vlog -lint -work wkdir/work_${1}_${3}_${4} +incdir+../config/$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 @@ -126,7 +126,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # power off -r /dut/core/* } else { - vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 + vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$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} { diff --git a/sim/wally-imperas-cov.do b/sim/wally-imperas-cov.do index a8beb12f1..2309b01df 100644 --- a/sim/wally-imperas-cov.do +++ b/sim/wally-imperas-cov.do @@ -29,21 +29,21 @@ vlog +incdir+../config/$1 \ +define+USE_IMPERAS_DV \ +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-trace.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/rvvi-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/imperasDV-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2api.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2log.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \ \ +define+INCLUDE_TRACE2COV +define+COVER_BASE_RV64I +define+COVER_LEVEL_DV_PR_EXT \ +define+COVER_RV64I \ +define+COVER_RV64C \ +define+COVER_RV64M \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2cov.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ \ - ../src/wally/cvw.sv \ + ../src/cvw.sv \ ../testbench/testbench_imperas.sv \ ../testbench/common/*.sv \ ../src/*/*.sv \ diff --git a/sim/wally-imperas-no-idv.do b/sim/wally-imperas-no-idv.do index b9068da36..47d8bf07b 100644 --- a/sim/wally-imperas-no-idv.do +++ b/sim/wally-imperas-no-idv.do @@ -26,8 +26,8 @@ vlib work # *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings. vlog +incdir+../config/$1 \ +incdir+../config/shared \ - ../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvvi-trace.sv \ - ../src/wally/cvw.sv \ + ../../external/ImperasDV-HMC/Imperas/ImpPublic/source/host/rvvi/rvviTrace.sv \ + ../src/cvw.sv \ ../testbench/testbench_imperas.sv \ ../testbench/common/*.sv \ ../src/*/*.sv \ diff --git a/sim/wally-imperas.do b/sim/wally-imperas.do index 640bae491..7f0b060e2 100644 --- a/sim/wally-imperas.do +++ b/sim/wally-imperas.do @@ -30,14 +30,14 @@ vlog +incdir+../config/$1 \ +define+USE_IMPERAS_DV \ +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-trace.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/rvvi-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/imperasDV-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2api.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2log.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2cov.sv \ - ../src/wally/cvw.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ + ../src/cvw.sv \ ../testbench/testbench_imperas.sv \ ../testbench/common/*.sv \ ../src/*/*.sv \ diff --git a/sim/wally-linux-imperas.do b/sim/wally-linux-imperas.do index cd13c4193..fcf6ceec4 100644 --- a/sim/wally-linux-imperas.do +++ b/sim/wally-linux-imperas.do @@ -33,7 +33,7 @@ vlib work # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + 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 @@ -53,14 +53,14 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { +incdir+../config/shared \ +incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \ +incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-trace.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/rvvi-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/imperasDV-api-pkg.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2api.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2log.sv \ - $env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2cov.sv \ - ../src/wally/cvw.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviApiPkg.sv \ + $env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvviTrace.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/idvApiPkg.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2api.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2log.sv \ + $env(IMPERAS_HOME)/ImpProprietary/source/host/idv/trace2cov.sv \ + ../src/cvw.sv \ ../testbench/testbench-linux-imperas.sv \ ../testbench/common/*.sv ../src/*/*.sv \ ../src/*/*/*.sv -suppress 2583 @@ -94,7 +94,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } elseif {$2 eq "fpga"} { echo "hello" - vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/wally/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 + 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 @@ -104,10 +104,10 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } else { if {$2 eq "ahb"} { - vlog +incdir+../config/$1 +incdir+../config/shared ../src/wally/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 + 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/wally/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 diff --git a/sim/wally.do b/sim/wally.do index efe82742e..bc987e3d3 100644 --- a/sim/wally.do +++ b/sim/wally.do @@ -33,7 +33,7 @@ vlib work # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + 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 +acc 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 @@ -47,7 +47,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { exec ./slack-notifier/slack-notifier.py } elseif {$2 eq "buildroot-no-trace"} { - vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../src/wally/cvw.sv ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 + 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 +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 vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 @@ -68,7 +68,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } elseif {$2 eq "fpga"} { echo "hello" - vlog -work work +incdir+../config/fpga +incdir+../config/shared ../src/wally/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 + 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 @@ -78,10 +78,10 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } else { if {$2 eq "ahb"} { - vlog +incdir+../config/$1 +incdir+../config/shared ../src/wally/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 + 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/wally/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 diff --git a/sim/wave.do b/sim/wave.do index 2a48308ef..e9461d589 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -11,14 +11,14 @@ add wave -noupdate /testbench/FunctionName/FunctionName/FunctionAddr add wave -noupdate /testbench/FunctionName/FunctionName/ProgramAddrIndex add wave -noupdate /testbench/FunctionName/FunctionName/FunctionName add wave -noupdate /testbench/FunctionName/FunctionName/ProgramAddrMapLineCount -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM -add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LoadStallD -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallF -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/MDUStallD -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/RetM +add wave -noupdate -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM +add wave -noupdate -group HDU -group hazards /testbench/dut/core/MDUStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE +add wave -noupdate -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM @@ -61,10 +61,10 @@ add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/RegWriteD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/RdD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/Rs1D add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/Rs2D -add wave -noupdate -expand -group {Execution Stage} /testbench/dut/core/ifu/PCE -add wave -noupdate -expand -group {Execution Stage} /testbench/dut/core/ifu/InstrE -add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName -add wave -noupdate -expand -group {Execution Stage} /testbench/dut/core/ieu/c/InstrValidE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/PCE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/InstrE +add wave -noupdate -group {Execution Stage} /testbench/InstrEName +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/c/InstrValidE add wave -noupdate -expand -group {Memory Stage} /testbench/FunctionName/FunctionName/FunctionName add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/InstrValidM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/PCM @@ -94,13 +94,13 @@ add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/STVEC_REGW add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/FRM_REGW add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/FFLAGS_REGW add wave -noupdate -group CSRs -group {user mode} /testbench/dut/core/priv/priv/csr/csru/csru/STATUS_FS -add wave -noupdate -expand -group Bpred -expand -group {branch update selection inputs} -divider {class check} -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF -add wave -noupdate -expand -group Bpred -expand -group prediction -expand -group ex /testbench/dut/core/ifu/bpred/bpred/PCSrcE -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCF -add wave -noupdate -expand -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F +add wave -noupdate -group Bpred -expand -group {branch update selection inputs} -divider {class check} +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/core/ifu/bpred/bpred/RASPCF +add wave -noupdate -group Bpred -expand -group prediction -expand -group ex /testbench/dut/core/ifu/bpred/bpred/PCSrcE +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/bpred/bpred/NextValidPCE +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF +add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCPlus2or4F add wave -noupdate -group RegFile -expand /testbench/dut/core/ieu/dp/regf/rf add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a1 add wave -noupdate -group RegFile /testbench/dut/core/ieu/dp/regf/a2 @@ -170,6 +170,7 @@ add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HRESETn add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HREADY add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HRESP add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HADDR +add wave -noupdate -group AHB /testbench/dut/core/HRDATA add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HWDATA add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HWRITE add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HSIZE @@ -177,200 +178,200 @@ add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HBURST add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HPROT add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HTRANS add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HMASTLOCK -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallM -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM -add wave -noupdate -expand -group lsu -radix hexadecimal /testbench/dut/core/lsu/WriteDataM -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/FWriteDataM -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/bus/dcache/dcache/CacheStall -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/IgnoreRequestTLB -add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/ebu/ebu/HCLK -add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm/CurrState -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm/HREADY -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/BusStall -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/HTRANS -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/FetchBuffer -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/HRDATA -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/LSUHWDATA -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/BusStall -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/CacheBusRW -add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/CacheBusAck -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheRW -add wave -noupdate -expand -group lsu -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/HitWay -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetValid -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrE -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrM -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet -add wave -noupdate -expand -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ClearDirtyWay} -add wave -noupdate -expand -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/HitWay -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUWriteEn -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CacheSet -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} -color {Orange Red} {/testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory[0]} -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CurrLRU -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/NextLRU -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/VictimWay -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} -expand -group DETAILS -expand /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/Intermediate -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} -expand -group DETAILS /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUUpdate -add wave -noupdate -expand -group lsu -group dcache -group {replacement policy} -expand -group DETAILS /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/WayExpanded -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/LineDirty -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/NextFlushAdr -add wave -noupdate -expand -group lsu -group dcache -group flush -radix hexadecimal /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdr -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushWayFlag -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWayCntEn -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushAdrCntEn -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdrFlag -add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/SelFlush -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimWay -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/PAdr -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/NextLRU -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CurrLRU -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUWriteEn -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataLine -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/WordOffsetAddr -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/HitWay -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/ValidWay -add wave -noupdate -expand -group lsu -group dcache -group Victim {/testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory[0]} -add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelectedWriteWordEn} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetDirtyWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/CacheTagMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/DirtyBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word0 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/RAM[62]} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelectedWriteWordEn} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetDirtyWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/CacheTagMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/DirtyBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SelectedWriteWordEn} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetDirtyWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/CacheTagMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/DirtyBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SelectedWriteWordEn} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetDirtyWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/CacheTagMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/DirtyBits} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/wordram/CacheDataMem/we} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/wordram/CacheDataMem/RAM} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/HitWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ReadTag} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/HitWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Dirty} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ReadTag} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/HitWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Dirty} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ReadTag} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/HitWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidWay} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Dirty} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ReadTag} -add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/HitWay -add wave -noupdate -expand -group lsu -group dcache -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/NextSet -add wave -noupdate -expand -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAdr -add wave -noupdate -expand -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAck -add wave -noupdate -expand -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataWord -add wave -noupdate -expand -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/VAdr -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/EffectivePrivilegeMode -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/HitPageType -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Translate -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/DisableTranslation -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBMiss -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBHit -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/PhysicalAddress -add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/TLBPageFault -add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/LoadAccessFaultM -add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/StoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBPAdr -add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE -add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PageTypeWriteVal -add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBWrite -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PhysicalAddress -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/SelRegions -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Cacheable -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Idempotent -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PMAAccessFault -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAInstrAccessFaultF -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMALoadAccessFaultM -add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAStoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF -add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM -add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/SelHPTW -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWStall -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/DTLBWalk -add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/hptw/hptw/WalkerState -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWAdr -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PTE -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextPageType -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PageType -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/ValidNonLeafPTE -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/ITLBWriteF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/DTLBWriteM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/DCacheStallM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFaultF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSULoadAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUStoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LoadAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/StoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFault +add wave -noupdate -group lsu /testbench/dut/core/lsu/SelHPTW +add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUStallM +add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM +add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM +add wave -noupdate -group lsu -radix hexadecimal /testbench/dut/core/lsu/WriteDataM +add wave -noupdate -group lsu /testbench/dut/core/lsu/FWriteDataM +add wave -noupdate -group lsu /testbench/dut/core/lsu/bus/dcache/dcache/CacheStall +add wave -noupdate -group lsu /testbench/dut/core/lsu/IgnoreRequestTLB +add wave -noupdate -group lsu /testbench/dut/core/lsu/SelHPTW +add wave -noupdate -group lsu -group bus /testbench/dut/core/ebu/ebu/HCLK +add wave -noupdate -group lsu -group bus -color Gold /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm/CurrState +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/AHBBuscachefsm/HREADY +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/BusStall +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/HTRANS +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/FetchBuffer +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/HRDATA +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUHWDATA +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/BusStall +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/CacheBusRW +add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/bus/dcache/ahbcacheinterface/CacheBusAck +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheRW +add wave -noupdate -group lsu -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/HitWay +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetValid +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrE +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrM +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet +add wave -noupdate -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ClearDirtyWay} +add wave -noupdate -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/HitWay +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUWriteEn +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CacheSet +add wave -noupdate -group lsu -group dcache -group {replacement policy} -color {Orange Red} {/testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory[0]} +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CurrLRU +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/NextLRU +add wave -noupdate -group lsu -group dcache -group {replacement policy} /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/VictimWay +add wave -noupdate -group lsu -group dcache -group {replacement policy} -expand -group DETAILS -expand /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/Intermediate +add wave -noupdate -group lsu -group dcache -group {replacement policy} -expand -group DETAILS /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUUpdate +add wave -noupdate -group lsu -group dcache -group {replacement policy} -expand -group DETAILS /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/WayExpanded +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/LineDirty +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/NextFlushAdr +add wave -noupdate -group lsu -group dcache -group flush -radix hexadecimal /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdr +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushWayFlag +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWayCntEn +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushAdrCntEn +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdrFlag +add wave -noupdate -group lsu -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/SelFlush +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimWay +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/PAdr +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/NextLRU +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/CurrLRU +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUWriteEn +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataLine +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/WordOffsetAddr +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/HitWay +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/ValidWay +add wave -noupdate -group lsu -group dcache -group Victim {/testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory[0]} +add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/vict/cacheLRU/LRUMemory +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelectedWriteWordEn} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetDirtyWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/CacheTagMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/DirtyBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word0 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/RAM[62]} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelectedWriteWordEn} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetDirtyWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/CacheTagMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/DirtyBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SelectedWriteWordEn} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetDirtyWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/CacheTagMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/DirtyBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SelectedWriteWordEn} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetDirtyWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/CacheTagMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/DirtyBits} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 -expand {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/wordram/CacheDataMem/we} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/wordram/CacheDataMem/RAM} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/CacheSet +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/HitWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ReadTag} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/HitWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Dirty} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ReadTag} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/HitWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Dirty} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ReadTag} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/HitWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidWay} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Dirty} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ReadTag} +add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/HitWay +add wave -noupdate -group lsu -group dcache -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/NextSet +add wave -noupdate -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAdr +add wave -noupdate -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAck +add wave -noupdate -group lsu -group dcache -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataWord +add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/VAdr +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/EffectivePrivilegeMode +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/HitPageType +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Translate +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/DisableTranslation +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBMiss +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBHit +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/PhysicalAddress +add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/TLBPageFault +add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/LoadAccessFaultM +add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/StoreAmoAccessFaultM +add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBPAdr +add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE +add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PageTypeWriteVal +add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBWrite +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PhysicalAddress +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/SelRegions +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Cacheable +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Idempotent +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PMAAccessFault +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAInstrAccessFaultF +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMALoadAccessFaultM +add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAStoreAmoAccessFaultM +add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF +add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM +add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/SelHPTW +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWStall +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/DTLBWalk +add wave -noupdate -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/hptw/hptw/WalkerState +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWAdr +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PTE +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextPageType +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PageType +add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/ValidNonLeafPTE +add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF +add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/ITLBWriteF +add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/DTLBWriteM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/DCacheStallM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFaultF +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSULoadAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUStoreAmoAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LoadAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/StoreAmoAccessFaultM +add wave -noupdate -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFault add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/UARTIntr add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/GPIOIntr add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/MExtInt @@ -389,18 +390,6 @@ add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/un add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/max_priority_with_irqs add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/irqs_at_max_priority add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/threshMask -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOIN -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOOUT -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOEN -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOIntr -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PSEL -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PADDR -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PWRITE -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PRDATA -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PREADY -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PWDATA -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PSTRB -add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PENABLE add wave -noupdate -group CLINT /testbench/dut/uncore/uncore/clint/clint/MTIME add wave -noupdate -group CLINT /testbench/dut/uncore/uncore/clint/clint/MTIMECMP add wave -noupdate -group CLINT -expand -group {clint bus} /testbench/dut/uncore/uncore/clint/clint/PSEL @@ -458,13 +447,14 @@ add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/d add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/IFUCacheBusStallF add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/ITLBMissF add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/TakeSpillF -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HSIZE -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HBURST -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HTRANS -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HWRITE -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HADDR -add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/Flush -add wave -noupdate -group ifu -group bus -color Gold /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/CurrState +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HSIZE +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HBURST +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HTRANS +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HWRITE +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HADDR +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/Flush +add wave -noupdate -group ifu -expand -group bus -color Gold /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/AHBBuscachefsm/CurrState +add wave -noupdate -group ifu -expand -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HRDATA add wave -noupdate -group ifu -expand -group icache -color Gold /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CurrState add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/ITLBMissF add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/bus/icache/icache/SelAdr @@ -592,16 +582,39 @@ add wave -noupdate -group {branch direction} -expand -group conditions /testbenc add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushD add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/StallM add wave -noupdate -group {branch direction} /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/FlushM -add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PCNextF -add wave -noupdate /testbench/dut/core/ifu/PCF +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOIN +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOOUT +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOEN +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOIntr +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PSEL +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PADDR +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PWRITE +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PRDATA +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PREADY +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PWDATA +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PSTRB +add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/PENABLE +add wave -noupdate /testbench/LoadMem +add wave -noupdate /testbench/CurrState +add wave -noupdate /testbench/DCacheFlushStart +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/InstrMName +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ieu/c/InstrValidM +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ieu/dp/regf/a3 +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ieu/dp/regf/rf +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ieu/dp/regf/wd3 +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ieu/dp/regf/we3 +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/ifu/InstrM +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/dut/core/lsu/IEUAdrM +add wave -noupdate -label {Contributors: DCacheFlushStart} -group {Contributors: sim:/testbench/DCacheFlushStart} /testbench/ecf +add wave -noupdate /testbench/ecf +add wave -noupdate /testbench/dut/uncore/uncore/ram/ram/memory/ce +add wave -noupdate /testbench/dut/uncore/uncore/ram/ram/memory/we +add wave -noupdate /testbench/dut/uncore/uncore/ram/ram/memory/addr +add wave -noupdate /testbench/dut/uncore/uncore/ram/ram/memory/dout add wave -noupdate /testbench/reset -add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BPDirPredD -add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/BranchM -add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/NewBPDirPredM -add wave -noupdate /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/PHT/mem TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 4} {12208 ns} 1} {{Cursor 4} {1472797 ns} 0} -quietly wave cursor active 2 +WaveRestoreCursors {{Cursor 4} {320072 ns} 0} {{Cursor 4} {19809168 ns} 1} +quietly wave cursor active 1 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 configure wave -justifyvalue left @@ -616,4 +629,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {1472724 ns} {1472832 ns} +WaveRestoreZoom {319935 ns} {320329 ns} diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 55e2ef03d..1275d0cbc 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -27,7 +27,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module cache #(parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) ( +module cache import cvw::*; #(parameter cvw_t P, + parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) ( input logic clk, input logic reset, input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY @@ -112,7 +113,7 @@ module cache #(parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, W AdrSelMuxSel, CacheSet); // Array of cache ways, along with victim, hit, dirty, and read merging logic - cacheway #(PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( + cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( .clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .SetValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index bf7d16834..5fb00dc90 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module cacheLRU #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) ( input logic clk, diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 544e3454e..0909ae82d 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module cachefsm #(parameter READ_ONLY_CACHE = 0) ( input logic clk, input logic reset, diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 81431c3b0..0a5c7b6e5 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -27,7 +27,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = 26, +module cacheway import cvw::*; #(parameter cvw_t P, + parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = 26, OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) ( input logic clk, input logic reset, @@ -108,7 +109,7 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = // Tag Array ///////////////////////////////////////////////////////////////////////////////////////////// - ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), + ram1p1rwe #(.P(P), .DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), .addr(CacheSet), .dout(ReadTag), .din(PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); @@ -130,12 +131,12 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN = for(words = 0; words < NUMSRAM; words++) begin: word if (!READ_ONLY_CACHE) begin:wordram - ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), + ram1p1rwbe #(.P(P), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words])); end else begin:wordram // no byte-enable needed for i$. - ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), + ram1p1rwe #(.P(P), .DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .we(SelectedWriteWordEn)); diff --git a/src/cache/subcachelineread.sv b/src/cache/subcachelineread.sv index a70a80b1e..db80cfc83 100644 --- a/src/cache/subcachelineread.sv +++ b/src/cache/subcachelineread.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module subcachelineread #(parameter LINELEN, WORDLEN, parameter MUXINTERVAL )( // The number of bits between mux. Set to 16 for I$ to support compressed. Set to `LLEN for D$ input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr, // Physical address diff --git a/src/wally/cvw.sv b/src/cvw.sv similarity index 82% rename from src/wally/cvw.sv rename to src/cvw.sv index 239b93e45..896c3245b 100644 --- a/src/wally/cvw.sv +++ b/src/cvw.sv @@ -68,31 +68,31 @@ typedef struct packed { logic ICACHE_SUPPORTED; // TLB configuration. Entries should be a power of 2 - int ITLB_ENTRIES; - int DTLB_ENTRIES; + int ITLB_ENTRIES; + int DTLB_ENTRIES; // Cache configuration. Sizes should be a power of two // typical configuration 4 ways, 4096 ints per way, 256 bit or more lines - int DCACHE_NUMWAYS; - int DCACHE_WAYSIZEINBYTES; - int DCACHE_LINELENINBITS; - int ICACHE_NUMWAYS; - int ICACHE_WAYSIZEINBYTES; - int ICACHE_LINELENINBITS; + int DCACHE_NUMWAYS; + int DCACHE_WAYSIZEINBYTES; + int DCACHE_LINELENINBITS; + int ICACHE_NUMWAYS; + int ICACHE_WAYSIZEINBYTES; + int ICACHE_LINELENINBITS; // Integer Divider Configuration // IDIV_BITSPERCYCLE must be 1, 2, or 4 - int IDIV_BITSPERCYCLE; + int IDIV_BITSPERCYCLE; logic IDIV_ON_FPU; // Legal number of PMP entries are 0, 16, or 64 - int PMP_ENTRIES; + int PMP_ENTRIES; // Address space logic [63:0] RESET_VECTOR; // WFI Timeout Wait - int WFI_TIMEOUT_BIT; + int WFI_TIMEOUT_BIT; // Peripheral Addresses // Peripheral memory space extends from BASE to BASE+RANGE @@ -134,24 +134,23 @@ typedef struct packed { logic GPIO_LOOPBACK_TEST; // Hardware configuration - int UART_PRESCALE ; + int UART_PRESCALE ; // Interrupt configuration - int PLIC_NUM_SRC; + int PLIC_NUM_SRC; logic PLIC_NUM_SRC_LT_32; - int PLIC_GPIO_ID; - int PLIC_UART_ID; - - logic BPRED_SUPPORTED; - BranchPredictorType BPRED_TYPE; - int BPRED_NUM_LHR; - int BPRED_SIZE; - int BTB_SIZE; + int PLIC_GPIO_ID; + int PLIC_UART_ID; + logic BPRED_SUPPORTED; + BranchPredictorType BPRED_TYPE; + int BPRED_NUM_LHR; + int BPRED_SIZE; + int BTB_SIZE; // FPU division architecture - int RADIX; - int DIVCOPIES; + int RADIX; + int DIVCOPIES; // bit manipulation logic ZBA_SUPPORTED; @@ -204,47 +203,47 @@ typedef struct packed { int PMPCFG_ENTRIES; // Floating point constants for Quad, Double, Single, and Half precisions - int Q_LEN; - int Q_NE; - int Q_NF; - int Q_BIAS; + int Q_LEN; + int Q_NE; + int Q_NF; + int Q_BIAS; logic [1:0] Q_FMT; - int D_LEN; - int D_NE; - int D_NF; - int D_BIAS; + int D_LEN; + int D_NE; + int D_NF; + int D_BIAS; logic [1:0] D_FMT; - int S_LEN; - int S_NE; - int S_NF; - int S_BIAS; + int S_LEN; + int S_NE; + int S_NF; + int S_BIAS; logic [1:0] S_FMT; - int H_LEN; - int H_NE; - int H_NF; - int H_BIAS; + int H_LEN; + int H_NE; + int H_NF; + int H_BIAS; logic [1:0] H_FMT; // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits int FLEN; - int NE ; - int NF ; + int NE ; + int NF ; logic [1:0] FMT ; - int BIAS; + int BIAS; // Floating point constants needed for FPU paramerterization - int FPSIZES; - int FMTBITS; - int LEN1 ; - int NE1 ; - int NF1 ; + int FPSIZES; + int FMTBITS; + int LEN1 ; + int NE1 ; + int NF1 ; logic [1:0] FMT1 ; - int BIAS1; - int LEN2 ; - int NE2 ; - int NF2 ; + int BIAS1; + int LEN2 ; + int NE2 ; + int NF2 ; logic [1:0] FMT2 ; - int BIAS2; + int BIAS2; // largest length in IEU/FPU int CVTLEN; @@ -256,7 +255,7 @@ typedef struct packed { // division constants int DIVN ; - int LOGR; + int LOGR ; int RK ; int LOGRK ; int FPDUR ; diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index e10ba99c2..76855bf81 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -36,7 +36,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( input logic [2:0] FRM_REGW, // rounding mode from CSR input logic [1:0] STATUS_FS, // is FPU enabled? input logic FDivBusyE, // is the divider busy - // intruction + // instruction input logic [31:0] InstrD, // the full instruction input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision input logic [6:0] OpD, // bits 6:0 of instruction @@ -53,6 +53,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( output logic FpLoadStoreM, // FP load or store instruction output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage + output logic FPUActiveE, // FP instruction being executed // register control signals output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable output logic FWriteIntE, FWriteIntM, // Write to integer register @@ -308,9 +309,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( assign Adr3D = InstrD[31:27]; // D/E pipleine register - flopenrc #(13+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, - {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD}, - {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE}); + flopenrc #(14+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, + {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ~IllegalFPUInstrD}, + {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, FPUActiveE}); flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E}); flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE); flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE}); diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index 3d4981384..f71999471 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -82,6 +82,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation logic FRegWriteE; // Write floating-point register + logic FPUActiveE; // FP instruction being executed // regfile signals logic [P.FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage @@ -171,7 +172,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( .reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .FpLoadStoreM, .IllegalFPUInstrD, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, - .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, + .FResSelE, .FResSelM, .FResSelW, .FPUActiveE, .PostProcSelE, .PostProcSelM, .FCvtIntW, .Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E); // FP register file @@ -226,7 +227,7 @@ module fpu import cvw::*; #(parameter cvw_t P) ( // unpack unit: splits FP inputs into their parts and classifies SNaN, NaN, Subnorm, Norm, Zero, Infifnity unpack #(P) unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE), - .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE), + .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE), .FPUActive(FPUActiveE), .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE), .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE), .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), diff --git a/src/fpu/unpack.sv b/src/fpu/unpack.sv index 14e9a6f66..145d6a701 100644 --- a/src/fpu/unpack.sv +++ b/src/fpu/unpack.sv @@ -30,6 +30,7 @@ module unpack import cvw::*; #(parameter cvw_t P) ( input logic [P.FLEN-1:0] X, Y, Z, // inputs from register file input logic [P.FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half input logic XEn, YEn, ZEn, // input enables + input logic FPUActive, // Kill inputs when FPU is not active output logic Xs, Ys, Zs, // sign bits of XYZ output logic [P.NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) output logic [P.NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) @@ -46,17 +47,17 @@ module unpack import cvw::*; #(parameter cvw_t P) ( logic XFracZero, YFracZero, ZFracZero; // is the fraction zero logic YExpMax, ZExpMax; // is the exponent all 1s - unpackinput #(P) unpackinputX (.In(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn), + unpackinput #(P) unpackinputX (.A(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn), .FPUActive, .NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero), .Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero), .Subnorm(XSubnorm), .PostBox(XPostBox)); - unpackinput #(P) unpackinputY (.In(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn), + unpackinput #(P) unpackinputY (.A(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn), .FPUActive, .NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero), .Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero), .Subnorm(), .PostBox()); - unpackinput #(P) unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn), + unpackinput #(P) unpackinputZ (.A(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn), .FPUActive, .NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero), .Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero), .Subnorm(), .PostBox()); diff --git a/src/fpu/unpackinput.sv b/src/fpu/unpackinput.sv index 1d429ed4a..c551e8173 100644 --- a/src/fpu/unpackinput.sv +++ b/src/fpu/unpackinput.sv @@ -27,9 +27,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module unpackinput import cvw::*; #(parameter cvw_t P) ( - input logic [P.FLEN-1:0] In, // inputs from register file + input logic [P.FLEN-1:0] A, // inputs from register file input logic En, // enable the input input logic [P.FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half + input logic FPUActive, // Kill inputs when FPU is not active output logic Sgn, // sign bits of the number output logic [P.NE-1:0] Exp, // exponent of the number (converted to largest supported precision) output logic [P.NF:0] Man, // mantissa of the number (converted to largest supported precision) @@ -46,6 +47,10 @@ module unpackinput import cvw::*; #(parameter cvw_t P) ( logic [P.NF-1:0] Frac; // Fraction of XYZ logic BadNaNBox; // incorrectly NaN Boxed + logic [P.FLEN-1:0] In; + + // Gate input when FPU is not active to save power and simulation + assign In = A & {P.FLEN{FPUActive}}; if (P.FPSIZES == 1) begin // if there is only one floating point format supported assign BadNaNBox = 0; diff --git a/src/generic/adder.sv b/src/generic/adder.sv index 81b6f5043..4d341d6c1 100644 --- a/src/generic/adder.sv +++ b/src/generic/adder.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module adder #(parameter WIDTH=8) ( input logic [WIDTH-1:0] a, b, output logic [WIDTH-1:0] y diff --git a/src/generic/aplusbeq0.sv b/src/generic/aplusbeq0.sv index d322216b3..f8d675b33 100644 --- a/src/generic/aplusbeq0.sv +++ b/src/generic/aplusbeq0.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module aplusbeq0 #(parameter WIDTH = 8) ( input logic [WIDTH-1:0] a, b, output logic zero @@ -40,4 +38,4 @@ module aplusbeq0 #(parameter WIDTH = 8) ( assign x = a ^ b; assign orshift = {a[WIDTH-2:0] | b[WIDTH-2:0], 1'b0}; assign zero = (x == orshift); -endmodule \ No newline at end of file +endmodule diff --git a/src/generic/arrs.sv b/src/generic/arrs.sv index 5a9cf21f0..dd473b307 100644 --- a/src/generic/arrs.sv +++ b/src/generic/arrs.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module arrs( input logic clk, input logic areset, diff --git a/src/generic/clockgater.sv b/src/generic/clockgater.sv index c09f98f2c..c0150133c 100644 --- a/src/generic/clockgater.sv +++ b/src/generic/clockgater.sv @@ -24,16 +24,14 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module clockgater ( +module clockgater #(parameter FPGA) ( input logic E, input logic SE, input logic CLK, output logic ECLK ); - if (`FPGA) BUFGCE bufgce_i0 (.I(CLK), .CE(E | SE), .O(ECLK)); + if (FPGA) BUFGCE bufgce_i0 (.I(CLK), .CE(E | SE), .O(ECLK)); else begin // *** BUG // VERY IMPORTANT. diff --git a/src/generic/counter.sv b/src/generic/counter.sv index 3e63d87ee..faba2e5e5 100644 --- a/src/generic/counter.sv +++ b/src/generic/counter.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module counter #(parameter WIDTH=8) ( input logic clk, reset, en, output logic [WIDTH-1:0] q diff --git a/src/generic/decoder.sv b/src/generic/decoder.sv index 807a6d6ca..6284a454c 100644 --- a/src/generic/decoder.sv +++ b/src/generic/decoder.sv @@ -23,8 +23,6 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -`include "wally-config.vh" - module decoder #(parameter BINARY_BITS = 3) ( input logic [BINARY_BITS-1:0] binary, output logic [(2**BINARY_BITS)-1:0] onehot diff --git a/src/generic/flop/flop.sv b/src/generic/flop/flop.sv index 1e906dca8..97e0ac7e4 100644 --- a/src/generic/flop/flop.sv +++ b/src/generic/flop/flop.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flop #(parameter WIDTH = 8) ( input logic clk, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/flopen.sv b/src/generic/flop/flopen.sv index 32e0d7dd3..2e6432519 100644 --- a/src/generic/flop/flopen.sv +++ b/src/generic/flop/flopen.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopen #(parameter WIDTH = 8) ( input logic clk, en, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/flopenl.sv b/src/generic/flop/flopenl.sv index 094779c74..562c4565a 100644 --- a/src/generic/flop/flopenl.sv +++ b/src/generic/flop/flopenl.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopenl #(parameter WIDTH = 8, parameter type TYPE=logic [WIDTH-1:0]) ( input logic clk, load, en, input TYPE d, diff --git a/src/generic/flop/flopenr.sv b/src/generic/flop/flopenr.sv index 3b8129e40..2c2144ab8 100644 --- a/src/generic/flop/flopenr.sv +++ b/src/generic/flop/flopenr.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopenr #(parameter WIDTH = 8) ( input logic clk, reset, en, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/flopenrc.sv b/src/generic/flop/flopenrc.sv index b3d5a1e8e..94b2b3cb0 100644 --- a/src/generic/flop/flopenrc.sv +++ b/src/generic/flop/flopenrc.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopenrc #(parameter WIDTH = 8) ( input logic clk, reset, clear, en, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/flopens.sv b/src/generic/flop/flopens.sv index 1f4c18051..c4fc5d01b 100644 --- a/src/generic/flop/flopens.sv +++ b/src/generic/flop/flopens.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopens #(parameter WIDTH = 8) ( input logic clk, set, en, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/flopr.sv b/src/generic/flop/flopr.sv index b2f99b3cd..2e39ee8d6 100644 --- a/src/generic/flop/flopr.sv +++ b/src/generic/flop/flopr.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module flopr #(parameter WIDTH = 8) ( input logic clk, reset, input logic [WIDTH-1:0] d, diff --git a/src/generic/flop/floprc.sv b/src/generic/flop/floprc.sv index 8275a8f96..b35e9ccce 100644 --- a/src/generic/flop/floprc.sv +++ b/src/generic/flop/floprc.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module floprc #(parameter WIDTH = 8) ( input logic clk, input logic reset, diff --git a/src/generic/flop/synchronizer.sv b/src/generic/flop/synchronizer.sv index f10efaeaf..f99088af4 100644 --- a/src/generic/flop/synchronizer.sv +++ b/src/generic/flop/synchronizer.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module synchronizer ( input logic clk, input logic d, diff --git a/src/generic/mem/ram1p1rwbe.sv b/src/generic/mem/ram1p1rwbe.sv index 8905cc551..56637c0ce 100644 --- a/src/generic/mem/ram1p1rwbe.sv +++ b/src/generic/mem/ram1p1rwbe.sv @@ -32,9 +32,7 @@ // WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words -`include "wally-config.vh" - -module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) ( +module ram1p1rwbe import cvw::*; #(parameter cvw_t P, parameter DEPTH=64, WIDTH=44) ( input logic clk, input logic ce, input logic [$clog2(DEPTH)-1:0] addr, @@ -49,7 +47,7 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) ( // *************************************************************************** // TRUE SRAM macro // *************************************************************************** - if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray + if ((P.USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray genvar index; // 64 x 128-bit SRAM logic [WIDTH-1:0] BitWriteMask; @@ -59,7 +57,7 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) ( .A(addr), .D(din), .BWEB(~BitWriteMask), .Q(dout)); - end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag + end else if ((P.USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag genvar index; // 64 x 44-bit SRAM logic [WIDTH-1:0] BitWriteMask; @@ -69,7 +67,7 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) ( .A(addr), .D(din), .BWEB(~BitWriteMask), .Q(dout)); - end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag + end else if ((P.USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag genvar index; // 64 x 22-bit SRAM logic [WIDTH-1:0] BitWriteMask; diff --git a/src/generic/mem/ram1p1rwe.sv b/src/generic/mem/ram1p1rwe.sv index f3a8a2248..24d92ff7f 100644 --- a/src/generic/mem/ram1p1rwe.sv +++ b/src/generic/mem/ram1p1rwe.sv @@ -30,9 +30,8 @@ // WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words -`include "wally-config.vh" - -module ram1p1rwe #(parameter DEPTH=64, WIDTH=44) ( +module ram1p1rwe import cvw::* ; #(parameter cvw_t P, + parameter DEPTH=64, WIDTH=44) ( input logic clk, input logic ce, input logic [$clog2(DEPTH)-1:0] addr, @@ -46,21 +45,21 @@ module ram1p1rwe #(parameter DEPTH=64, WIDTH=44) ( // *************************************************************************** // TRUE SRAM macro // *************************************************************************** - if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray + if ((P.USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray // 64 x 128-bit SRAM ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we), .A(addr), .D(din), .BWEB('0), .Q(dout)); - end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag + end else if ((P.USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag // 64 x 44-bit SRAM ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we), .A(addr), .D(din), .BWEB('0), .Q(dout)); - end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag + end else if ((P.USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag // 64 x 22-bit SRAM - ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we), + ram1p1rwbe_64x22 sram1 (.CLK(clk), .CEB(~ce), .WEB(~we), .A(addr), .D(din), .BWEB('0), .Q(dout)); diff --git a/src/generic/mem/ram2p1r1wbe.sv b/src/generic/mem/ram2p1r1wbe.sv index 51e2871b4..202d0432b 100644 --- a/src/generic/mem/ram2p1r1wbe.sv +++ b/src/generic/mem/ram2p1r1wbe.sv @@ -31,9 +31,8 @@ // WIDTH is number of bits in one "word" of the memory, DEPTH is number of such words -`include "wally-config.vh" - -module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) ( +module ram2p1r1wbe import cvw::*; #(parameter cvw_t P, + parameter DEPTH=1024, WIDTH=68) ( input logic clk, input logic ce1, ce2, input logic [$clog2(DEPTH)-1:0] ra1, @@ -52,7 +51,7 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) ( // TRUE Smem macro // *************************************************************************** - if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin + if ((P.USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk), .CEBA(~ce1), .CEBB(~ce2), @@ -64,7 +63,7 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) ( .QA(rd1), .QB()); - end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin + end else if ((P.USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk), .CEBA(~ce1), .CEBB(~ce2), @@ -76,7 +75,7 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) ( .QA(rd1), .QB()); - end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin + end else if ((P.USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin logic [SRAMWIDTH-1:0] SRAMReadData; logic [SRAMWIDTH-1:0] SRAMWriteData; diff --git a/src/generic/mem/rom1p1r.sv b/src/generic/mem/rom1p1r.sv index ef9c6da37..497356788 100644 --- a/src/generic/mem/rom1p1r.sv +++ b/src/generic/mem/rom1p1r.sv @@ -25,8 +25,6 @@ // This model actually works correctly with vivado. -`include "wally-config.vh" - module rom1p1r #(parameter ADDR_WIDTH = 8, parameter DATA_WIDTH = 32, parameter PRELOAD_ENABLED = 0) diff --git a/src/generic/mux.sv b/src/generic/mux.sv index 223d41afc..9c1dfe335 100644 --- a/src/generic/mux.sv +++ b/src/generic/mux.sv @@ -24,7 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" /* verilator lint_off DECLFILENAME */ module mux2 #(parameter WIDTH = 8) ( diff --git a/src/generic/neg.sv b/src/generic/neg.sv index 787817af8..e971fc232 100644 --- a/src/generic/neg.sv +++ b/src/generic/neg.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module neg #(parameter WIDTH = 8) ( input logic [WIDTH-1:0] a, output logic [WIDTH-1:0] y); diff --git a/src/generic/onehotdecoder.sv b/src/generic/onehotdecoder.sv index 5e8f01c26..b672a08e5 100644 --- a/src/generic/onehotdecoder.sv +++ b/src/generic/onehotdecoder.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module onehotdecoder #(parameter WIDTH = 2) ( input logic [WIDTH-1:0] bin, output logic [2**WIDTH-1:0] decoded diff --git a/src/generic/or_rows.sv b/src/generic/or_rows.sv index a98c79a3d..476b62586 100644 --- a/src/generic/or_rows.sv +++ b/src/generic/or_rows.sv @@ -24,8 +24,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - // perform an OR of all the rows in an array, producing one output for each column // equivalent to assign y = a.or module or_rows #(parameter ROWS = 8, COLS=2) ( diff --git a/src/generic/priorityonehot.sv b/src/generic/priorityonehot.sv index ba5ebb90f..1cddb2bfc 100644 --- a/src/generic/priorityonehot.sv +++ b/src/generic/priorityonehot.sv @@ -33,8 +33,6 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -`include "wally-config.vh" - module priorityonehot #(parameter N = 8) ( input logic [N-1:0] a, output logic [N-1:0] y diff --git a/src/generic/prioritythermometer.sv b/src/generic/prioritythermometer.sv index 059792b7d..f779d4748 100644 --- a/src/generic/prioritythermometer.sv +++ b/src/generic/prioritythermometer.sv @@ -29,8 +29,6 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -`include "wally-config.vh" - module prioritythermometer #(parameter N = 8) ( input logic [N-1:0] a, output logic [N-1:0] y diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 43df83b60..1906c85e5 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -27,9 +27,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module alu #(parameter WIDTH=32) ( +module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) ( input logic [WIDTH-1:0] A, B, // Operands input logic W64, // W64-type instruction input logic SubArith, // Subtraction or arithmetic shift @@ -38,6 +36,7 @@ module alu #(parameter WIDTH=32) ( input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // For BMU decoding input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage + input logic BMUActiveE, // Bit manipulation instruction being executed output logic [WIDTH-1:0] ALUResult, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands @@ -56,7 +55,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts (configurable for rotation) - shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); + shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign @@ -76,7 +75,7 @@ module alu #(parameter WIDTH=32) ( 3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv - 3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported) + 3'b101: FullResult = (P.ZBS_SUPPORTED | P.ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported) 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset 3'b111: FullResult = A & CondMaskInvB; // and, bclr endcase @@ -87,8 +86,8 @@ module alu #(parameter WIDTH=32) ( else assign PreALUResult = FullResult; // Final Result B instruction select mux - if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu - bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, + if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu + bitmanipalu #(P, WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActiveE, .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, .CondMaskB, .CondShiftA, .ALUResult); end else begin @@ -96,4 +95,4 @@ module alu #(parameter WIDTH=32) ( assign CondMaskB = B; assign CondShiftA = A; end -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 228b23132..706ebdb21 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -27,9 +27,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module bitmanipalu #(parameter WIDTH=32) ( +module bitmanipalu import cvw::*; #(parameter cvw_t P, + parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands input logic W64, // W64-type instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction @@ -38,6 +37,7 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic LT, // less than flag input logic LTU, // less than unsigned flag input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage + input logic BMUActiveE, // Bit manipulation instruction being executed input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions @@ -51,18 +51,23 @@ module bitmanipalu #(parameter WIDTH=32) ( logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction logic [1:0] PreShiftAmt; // Amount to Pre-Shift A logic [WIDTH-1:0] CondZextA; // A Conditional Extend Intermediary Signal + logic [WIDTH-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity + + // gate data inputs to BMU to only operate when BMU is active + assign ABMU = A & {WIDTH{BMUActiveE}}; + assign BBMU = B & {WIDTH{BMUActiveE}}; // Extract control signals from bitmanip ALUControl. assign {Mask, PreShift} = BALUControl[1:0]; // Mask Generation Mux - if (`ZBS_SUPPORTED) begin: zbsdec - decoder #($clog2(WIDTH)) maskgen(B[$clog2(WIDTH)-1:0], MaskB); + if (P.ZBS_SUPPORTED) begin: zbsdec + decoder #($clog2(WIDTH)) maskgen(BBMU[$clog2(WIDTH)-1:0], MaskB); mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); end else assign CondMaskB = B; // 0-3 bit Pre-Shift Mux - if (`ZBA_SUPPORTED) begin: zbapreshift + if (P.ZBA_SUPPORTED) begin: zbapreshift if (WIDTH == 64) begin mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA); end else assign CondZextA = A; @@ -74,18 +79,18 @@ module bitmanipalu #(parameter WIDTH=32) ( end // Bit reverse needed for some ZBB, ZBC instructions - if (`ZBC_SUPPORTED | `ZBB_SUPPORTED) begin: bitreverse - bitreverse #(WIDTH) brA(.A, .RevA); + if (P.ZBC_SUPPORTED | P.ZBB_SUPPORTED) begin: bitreverse + bitreverse #(WIDTH) brA(.A(ABMU), .RevA); end // ZBC Unit - if (`ZBC_SUPPORTED) begin: zbc - zbc #(WIDTH) ZBC(.A, .RevA, .B, .Funct3, .ZBCResult); + if (P.ZBC_SUPPORTED) begin: zbc + zbc #(WIDTH) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult); end else assign ZBCResult = 0; // ZBB Unit - if (`ZBB_SUPPORTED) begin: zbb - zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); + if (P.ZBB_SUPPORTED) begin: zbb + zbb #(WIDTH) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); end else assign ZBBResult = 0; // Result Select Mux diff --git a/src/ieu/bmu/bitreverse.sv b/src/ieu/bmu/bitreverse.sv index e2afb0c95..fc2530aab 100644 --- a/src/ieu/bmu/bitreverse.sv +++ b/src/ieu/bmu/bitreverse.sv @@ -27,7 +27,6 @@ // either express or implied. See the License for the specific language governing permissions // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" module bitreverse #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index ad46ab728..59a8e4a16 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -46,7 +46,8 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding output logic [2:0] ZBBSelectE, // ZBB mux select signal output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute - output logic [2:0] BALUControlE // ALU Control signals for B instructions in Execute Stage + output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage + output logic BMUActiveE // Bit manipulation instruction being executed ); logic [6:0] OpD; // Opcode in Decode stage @@ -174,5 +175,5 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); // BMU Execute stage pipieline control register - flopenrc #(9) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE}); + flopenrc #(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD, ~IllegalBitmanipInstrD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE, BMUActiveE}); endmodule diff --git a/src/ieu/bmu/byteop.sv b/src/ieu/bmu/byteop.sv index e6099533b..2879ba042 100644 --- a/src/ieu/bmu/byteop.sv +++ b/src/ieu/bmu/byteop.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module byteop #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, // Operands input logic ByteSelect, // LSB of Immediate @@ -43,4 +41,4 @@ module byteop #(parameter WIDTH=32) ( end mux2 #(WIDTH) bytemux(Rev8Result, OrcBResult, ByteSelect, ByteResult); -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/bmu/clmul.sv b/src/ieu/bmu/clmul.sv index cf3e1c6b1..675387577 100644 --- a/src/ieu/bmu/clmul.sv +++ b/src/ieu/bmu/clmul.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module clmul #(parameter WIDTH=32) ( input logic [WIDTH-1:0] X, Y, // Operands output logic [WIDTH-1:0] ClmulResult); // ZBS result diff --git a/src/ieu/bmu/cnt.sv b/src/ieu/bmu/cnt.sv index a1f82eb7e..d015c1195 100644 --- a/src/ieu/bmu/cnt.sv +++ b/src/ieu/bmu/cnt.sv @@ -28,8 +28,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module cnt #(parameter WIDTH = 32) ( input logic [WIDTH-1:0] A, RevA, // Operands input logic [1:0] B, // Last 2 bits of immediate @@ -62,4 +60,4 @@ module cnt #(parameter WIDTH = 32) ( assign cpopResult[WIDTH-1:$clog2(WIDTH)+1] = '0; mux2 #(WIDTH) cntresultmux(czResult, cpopResult, B[1], CntResult); -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/bmu/ext.sv b/src/ieu/bmu/ext.sv index 438addaa8..1feca6e1e 100644 --- a/src/ieu/bmu/ext.sv +++ b/src/ieu/bmu/ext.sv @@ -28,8 +28,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module ext #(parameter WIDTH = 32) ( input logic [WIDTH-1:0] A, // Operands input logic [1:0] ExtSelect, // B[2], B[0] of immediate @@ -42,4 +40,4 @@ module ext #(parameter WIDTH = 32) ( assign sextbResult = {{(WIDTH-8){A[7]}},A[7:0]}; mux3 #(WIDTH) extmux(sextbResult, sexthResult, zexthResult, ExtSelect, ExtResult); -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index 3d7bcedd9..9ae3df42d 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -28,8 +28,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module zbb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, RevA, B, // Operands input logic W64, // Indicates word operation @@ -55,4 +53,4 @@ module zbb #(parameter WIDTH=32) ( // ZBB Result select mux mux4 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinMaxResult, ZBBSelect[1:0], ZBBResult); -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/bmu/zbc.sv b/src/ieu/bmu/zbc.sv index b173a5f63..4dc3ad1bd 100644 --- a/src/ieu/bmu/zbc.sv +++ b/src/ieu/bmu/zbc.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module zbc #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, RevA, B, // Operands input logic [2:0] Funct3, // Indicates operation to perform @@ -48,4 +46,4 @@ module zbc #(parameter WIDTH=32) ( bitreverse #(WIDTH) brClmulResult(ClmulResult, RevClmulResult); mux2 #(WIDTH) zbcresultmux(ClmulResult, RevClmulResult, Funct3[1], ZBCResult); -endmodule \ No newline at end of file +endmodule diff --git a/src/ieu/comparator.sv b/src/ieu/comparator.sv index 5f504dced..0803d8b2f 100644 --- a/src/ieu/comparator.sv +++ b/src/ieu/comparator.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - // This comparator is best module comparator #(parameter WIDTH=64) ( input logic [WIDTH-1:0] a, b, // Operands diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 8839b9cad..838560ed1 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -58,6 +58,8 @@ module controller import cvw::*; #(parameter cvw_t P) ( output logic [1:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction output logic [2:0] ZBBSelectE, // ZBB mux select signal in Execute stage output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage + output logic BMUActiveE, // Bit manipulation instruction being executed + output logic MDUActiveE, // Mul/Div instruction being executed // Memory stage control signals input logic StallM, FlushM, // Stall, flush Memory stage @@ -253,7 +255,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( bmuctrl #(P) bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, - .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE); + .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE, .BMUActiveE); if (P.ZBA_SUPPORTED) begin // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; @@ -282,6 +284,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( assign BSelectD = 2'b00; assign ZBBSelectE = 3'b000; assign BALUControlE = 3'b0; + assign BMUActiveE = 1'b0; end // Fences @@ -317,6 +320,7 @@ module controller import cvw::*; #(parameter cvw_t P) ( // Other execute stage controller signals assign MemReadE = MemRWE[1]; assign SCE = (ResultSrcE == 3'b100); + assign MDUActiveE = (ResultSrcE == 3'b011); assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers assign IntDivE = MDUE & Funct3E[2]; // Integer division operation @@ -335,5 +339,6 @@ module controller import cvw::*; #(parameter cvw_t P) ( // the synchronous DTIM cannot read immediately after write // a cache cannot read or write immediately after a write - assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & P.DCACHE_SUPPORTED)) | (|AtomicD)); + // atomic operations are also detected as MemRWD[1] + assign StoreStallD = MemRWE[0] & ((MemRWD[1] | (MemRWD[0] & P.DCACHE_SUPPORTED))); endmodule diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index cb013ee9d..799a25988 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -28,55 +28,56 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module datapath import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, + input logic clk, reset, // Decode stage signals - input logic [2:0] ImmSrcD, // Selects type of immediate extension - input logic [31:0] InstrD, // Instruction in Decode stage + input logic [2:0] ImmSrcD, // Selects type of immediate extension + input logic [31:0] InstrD, // Instruction in Decode stage // Execute stage signals input logic [P.XLEN-1:0] PCE, // PC in Execute stage input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage) - input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage - input logic StallE, FlushE, // Stall, flush Execute stage - input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages - input logic W64E, // W64-type instruction - input logic SubArithE, // Subtraction or arithmetic shift - input logic ALUSrcAE, ALUSrcBE, // ALU operands - input logic ALUResultSrcE, // Selects result to pass on to Memory stage - input logic [2:0] ALUSelectE, // ALU mux select signal - input logic JumpE, // Is a jump (j) instruction - input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) - input logic [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction - input logic [2:0] ZBBSelectE, // ZBB mux select signal - input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage - output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) + input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage + input logic StallE, FlushE, // Stall, flush Execute stage + input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages + input logic W64E, // W64-type instruction + input logic SubArithE, // Subtraction or arithmetic shift + input logic ALUSrcAE, ALUSrcBE, // ALU operands + input logic ALUResultSrcE, // Selects result to pass on to Memory stage + input logic [2:0] ALUSelectE, // ALU mux select signal + input logic JumpE, // Is a jump (j) instruction + input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) + input logic [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction + input logic [2:0] ZBBSelectE, // ZBB mux select signal + input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage + input logic BMUActiveE, // Bit manipulation instruction being executed + output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) output logic [P.XLEN-1:0] IEUAdrE, // Address computed by ALU output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B // Memory stage signals - input logic StallM, FlushM, // Stall, flush Memory stage - input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int + input logic StallM, FlushM, // Stall, flush Memory stage + input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int input logic [P.XLEN-1:0] FIntResM, // FPU integer result output logic [P.XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes output logic [P.XLEN-1:0] WriteDataM, // Write data in Memory stage // Writeback stage signals - input logic StallW, FlushW, // Stall, flush Writeback stage - input logic RegWriteW, IntDivW, // Write register file, integer divide instruction - input logic SquashSCW, // Squash a store conditional when a conflict arose - input logic [2:0] ResultSrcW, // Select source of result to write back to register file + input logic StallW, FlushW, // Stall, flush Writeback stage + input logic RegWriteW, IntDivW, // Write register file, integer divide instruction + input logic SquashSCW, // Squash a store conditional when a conflict arose + input logic [2:0] ResultSrcW, // Select source of result to write back to register file input logic [P.XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result input logic [P.XLEN-1:0] ReadDataW, // Read data from LSU input logic [P.XLEN-1:0] CSRReadValW, // CSR read result input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result // Hazard Unit signals - output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage - output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage + output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage + output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage ); // Fetch stage signals // Decode stage signals logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2) logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage - logic [4:0] RdD; // Destination register in Decode stage + logic [4:0] RdD; // Destination register in Decode stage // Execute stage signals logic [P.XLEN-1:0] R1E, R2E; // Source operands read from register file logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage @@ -103,16 +104,16 @@ module datapath import cvw::*; #(parameter cvw_t P) ( flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); - flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E); - flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); - flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); + flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E); + flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); + flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); - alu #(P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE); + alu #(P, P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, ALUResultE, IEUAdrE); mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); @@ -144,5 +145,5 @@ module datapath import cvw::*; #(parameter cvw_t P) ( // handle Store Conditional result if atomic extension supported if (P.A_SUPPORTED) assign SCResultW = {{(P.XLEN-1){1'b0}}, SquashSCW}; - else assign SCResultW = 0; + else assign SCResultW = 0; endmodule diff --git a/src/ieu/extend.sv b/src/ieu/extend.sv index 70a429b16..e0551e9dc 100644 --- a/src/ieu/extend.sv +++ b/src/ieu/extend.sv @@ -30,7 +30,7 @@ module extend #(parameter XLEN, A_SUPPORTED) ( input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits) input logic [2:0] ImmSrcD, // Select what kind of extension to perform - output logic [XLEN-1:0 ] ImmExtD); // Extended immediate + output logic [XLEN-1:0] ImmExtD); // Extended immediate localparam [XLEN-1:0] undefined = {(XLEN){1'bx}}; // could change to 0 after debug @@ -45,10 +45,10 @@ module extend #(parameter XLEN, A_SUPPORTED) ( // J-type (jal) 3'b011: ImmExtD = {{(XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0}; // U-type (lui, auipc) - 3'b100: ImmExtD = {{(XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0}; + 3'b100: ImmExtD = {{(XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0}; // Store Conditional: zero offset 3'b101: if (A_SUPPORTED) ImmExtD = 0; - else ImmExtD = undefined; + else ImmExtD = undefined; default: ImmExtD = undefined; // undefined endcase endmodule diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index daebc98f6..c4e60aca9 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -26,7 +26,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// - module ieu import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Decode stage signals @@ -34,36 +33,37 @@ module ieu import cvw::*; #(parameter cvw_t P) ( input logic IllegalIEUFPUInstrD, // Illegal instruction output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers // Execute stage signals - input logic [P.XLEN-1:0] PCE, // PC - input logic [P.XLEN-1:0] PCLinkE, // PC + 4 + input logic [P.XLEN-1:0] PCE, // PC + input logic [P.XLEN-1:0] PCLinkE, // PC + 4 output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE) input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int - output logic [P.XLEN-1:0] IEUAdrE, // Memory address + output logic [P.XLEN-1:0] IEUAdrE, // Memory address output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction output logic [2:0] Funct3E, // Funct3 instruction field - output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B + output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B output logic [4:0] RdE, // Destination register + output logic MDUActiveE, // Mul/Div instruction being executed // Memory stage signals input logic SquashSCW, // Squash store conditional, from LSU output logic [1:0] MemRWM, // Read/write control goes to LSU output logic [1:0] AtomicM, // Atomic control goes to LSU - output logic [P.XLEN-1:0] WriteDataM, // Write data to LSU + output logic [P.XLEN-1:0] WriteDataM, // Write data to LSU output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU - output logic [P.XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU + output logic [P.XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU output logic [4:0] RdM, // Destination register - input logic [P.XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) + input logic [P.XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ - output logic InstrValidD, InstrValidE, InstrValidM,// Instruction is valid + output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid output logic BranchD, BranchE, output logic JumpD, JumpE, // Writeback stage signals - input logic [P.XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) - input logic [P.XLEN-1:0] CSRReadValW, // CSR read value, - input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result - input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result + input logic [P.XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) + input logic [P.XLEN-1:0] CSRReadValW, // CSR read value, + input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result + input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result input logic FCvtIntW, // FPU converts float to int output logic [4:0] RdW, // Destination register - input logic [P.XLEN-1:0] ReadDataW, // LSU's read data + input logic [P.XLEN-1:0] ReadDataW, // LSU's read data // Hazard unit signals input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic FlushD, FlushE, FlushM, FlushW, // Flush signals @@ -94,20 +94,22 @@ module ieu import cvw::*; #(parameter cvw_t P) ( logic MemReadE, CSRReadE; // Load, CSRRead instruction logic BranchSignedE; // Branch does signed comparison on operands logic MDUE; // Multiply/divide instruction + logic BMUActiveE; // Bit manipulation instruction being executed controller #(P) c( .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, - .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM, - .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, + .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, + .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE, + .StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); datapath #(P) dp( .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, - .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, + .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); @@ -118,4 +120,3 @@ module ieu import cvw::*; #(parameter cvw_t P) ( .FCvtIntE, .SCE, .ForwardAE, .ForwardBE, .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD); endmodule - diff --git a/src/ieu/regfile.sv b/src/ieu/regfile.sv index 5eff24022..2b76bca17 100644 --- a/src/ieu/regfile.sv +++ b/src/ieu/regfile.sv @@ -31,10 +31,10 @@ module regfile #(parameter XLEN, E_SUPPORTED) ( input logic clk, reset, input logic we3, // Write enable input logic [4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3) - input logic [XLEN-1:0] wd3, // Write data for port 3 - output logic [XLEN-1:0] rd1, rd2); // Read data for ports 1, 2 + input logic [XLEN-1:0] wd3, // Write data for port 3 + output logic [XLEN-1:0] rd1, rd2); // Read data for ports 1, 2 - localparam NUMREGS = E_SUPPORTED ? 16 : 32; // only 16 registers in E mode + localparam NUMREGS = E_SUPPORTED ? 16 : 32; // only 16 registers in E mode logic [XLEN-1:0] rf[NUMREGS-1:1]; integer i; @@ -50,7 +50,7 @@ module regfile #(parameter XLEN, E_SUPPORTED) ( always_ff @(negedge clk) if (reset) for(i=1; i> Offset; - assign Y = ZShift[`XLEN-1:0]; + assign Y = ZShift[P.XLEN-1:0]; endmodule - - diff --git a/src/ifu/CodeAligner.py b/src/ifu/CodeAligner.py deleted file mode 100644 index 579fd6237..000000000 --- a/src/ifu/CodeAligner.py +++ /dev/null @@ -1,112 +0,0 @@ -import os - -# Kevin Wan kewan@hmc.edu 10/27/2021 -def read_input(filename): #1 - """Takes in a string filename and outputs the parsed verilog code by line into a list - such that each element of the list is one line of verilog code as a string.""" - lineOfCode = [] - input_file = open(filename, 'r') - for line in input_file: - lineOfCode.append(line) - return lineOfCode -################################################################################### -def ID_start(GiantString):#2 - """takes in the list of sv file lines, outputs the location that variable names should start""" - VarLoc = 0 - VarLineNum = None - for lines in GiantString: - if ' logic ' in lines and (lines.find("//") == -1 or lines.find("//") > lines.find(' logic ')): # // logic does not proceed. logic proceeds. logic // proceeds. - if "[" in lines and "]" in lines:# need to account for these space - NowLoc = lines.find(']') + 3# column number in sv code when 1st char of the var name should appear. - if NowLoc>VarLoc: - VarLoc = NowLoc - VarLineNum = GiantString.index(lines) # Update this number if new record is made. - else: - NowLoc = lines.find('logic') + 7 # same as before. - if NowLoc>VarLoc: - VarLoc = NowLoc - VarLineNum = GiantString.index(lines) - #print("Furthest variable appears on line", VarLineNum + 1,VarLoc) # Disable this line after debugging. - return VarLoc -################################################################################## -def modified_logNew(GS,SOV): #3 - Ind = SOV - 1 # SOV is for human readability, Ind is the character's index in computer, since computers count from 0's we need to correct it. - Out = [] - for l in GS: - lines = l.replace('\t',' ') - - if ' logic ' in lines and (lines.find("//") == -1 or lines.find("//") > lines.find(' logic ')): # // logic does not proceed. logic proceeds. logic // proceeds. - if "[" in lines and "]" in lines: # the line is an extended declaration. - EditLoc = lines.find("]") # Re-finds the string index number of ]. - VarLoc = FindCharRel(lines[EditLoc+1::]) + EditLoc + 1 # Checks where variable declaration currently is at. - #print(VarLoc,lines[VarLoc])# VERIFIED - NewLine = Mod_Space_at(lines,VarLoc,VarLoc-Ind) - Out.append(NewLine)# Verified0957 10272021 - else: - EditLoc1 = lines.find('c') # Hopefully sees the c in 'logic' - - VarLoc1 = FindCharRel(lines[EditLoc1+1::]) + EditLoc1 + 1 - NewLine1 = Mod_Space_at(lines,VarLoc1,VarLoc1-Ind) - - Out.append(NewLine1)# Verified 1005 10272021 - else: - Out.append(lines) - return Out -################################################################################ -def write_to_output(filename,GiantString,OW=True,Lines_editted=None): #4 - """Filename is preferrably passed from the early function calls""" - """GiantString has all the corrected features in the code, each line is a good verilog code line""" - newname = filename - if not OW or OW =='f': #which means no overwrite (create a new file) - Decomposed=filename.split('.') - newname = Decomposed[0] + "_AL." + Decomposed[1] # AL for aligned. - - OutFile = open(newname,'w') # This step should create a new file. - OutFile.writelines(GiantString) - OutFile.close() - print("Success! " + newname + " Now contains an aligned file!") - return newname -################################################################################# - -def FindCharRel(Ln): - #returns the computer location of a character's first occurence - for num in range(len(Ln)): - if Ln[num] != " ": - return num - - -def Mod_Space_at(Ln,loc,diff): - #loc is the varLoc from mln, diff is varLoc - Ind - if diff > 0: # to delete - NewString = Ln[:(loc-diff)] + Ln[loc:] - - if diff < 0: # to add - NewString = Ln[:loc] + (-diff)*" " + Ln[loc:] - if diff == 0: - NewString = Ln - - return NewString - -'''def main_filehandler(overwrite=False): - for filename in os.listdir(): - if ".sv" in filename: - GiantString = read_input(filename) - SOV = ID_start(GiantString) - ModifiedGS = modified_logNew(GiantString,SOV) - Newname = write_to_output(filename,ModifiedGS,overwrite)''' -def root_filehandler(path,overwrite=False): - for f in os.listdir(path): - if os.path.isdir(f): - root_filehandler(path+"/"+f) - else: - if ".sv" in f: - GiantString = read_input(f) - SOV = ID_start(GiantString) - ModifiedGS = modified_logNew(GiantString,SOV) - Newname = write_to_output(f,ModifiedGS,overwrite) - - -def driver(overwrite=False): - root_filehandler(os.getcwd()) - -driver(True) \ No newline at end of file diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index 7493c5ccc..13439cd43 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -97,45 +97,45 @@ module bpred import cvw::*; #(parameter cvw_t P) ( // Part 1 branch direction prediction if (P.BPRED_TYPE == BP_TWOBIT) begin:Predictor - twoBitPredictor #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, + twoBitPredictor #(P, P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (P.BPRED_TYPE == BP_GSHARE) begin:Predictor - gshare #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + gshare #(P, P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE, .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .PCSrcE); end else if (P.BPRED_TYPE == BP_GLOBAL) begin:Predictor - gshare #(P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + gshare #(P, P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, .BPDirPredF, .BPDirPredWrongE, .BPBranchF, .BranchD, .BranchE, .BranchM, .BranchW, .PCSrcE); end else if (P.BPRED_TYPE == BP_GSHARE_BASIC) begin:Predictor - gsharebasic #(P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + gsharebasic #(P, P.XLEN, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (P.BPRED_TYPE == BP_GLOBAL_BASIC) begin:Predictor - gsharebasic #(P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + gsharebasic #(P, P.XLEN, P.BPRED_SIZE, 0) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (P.BPRED_TYPE == BP_LOCAL_BASIC) begin:Predictor - localbpbasic #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, + localbpbasic #(P, P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .BPDirPredF, .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (P.BPRED_TYPE == BP_LOCAL_AHEAD) begin:Predictor - localaheadbp #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, + localaheadbp #(P, P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCM, .BPDirPredD(BPDirPredF), .BPDirPredWrongE, .BranchE, .BranchM, .PCSrcE); end else if (P.BPRED_TYPE == BP_LOCAL_REPAIR) begin:Predictor - localrepairbp #(P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, + localrepairbp #(P, P.XLEN, P.BPRED_NUM_LHR, P.BPRED_SIZE) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCE, .PCM, .BPDirPredD(BPDirPredF), .BPDirPredWrongE, .BranchD, .BranchE, .BranchM, .PCSrcE); diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index 5279f867a..e93c1decb 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -92,7 +92,7 @@ module btb import cvw::*; #(parameter cvw_t P, // An optimization may be using a PC relative address. - ram2p1r1wbe #(2**Depth, P.XLEN+4) memory( + ram2p1r1wbe #(P, 2**Depth, P.XLEN+4) memory( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); diff --git a/src/ifu/bpred/gshare.sv b/src/ifu/bpred/gshare.sv index dcd94e2a2..460acbcbf 100644 --- a/src/ifu/bpred/gshare.sv +++ b/src/ifu/bpred/gshare.sv @@ -28,7 +28,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////// -module gshare #(parameter XLEN, +module gshare import cvw::*; #(parameter cvw_t P, + parameter XLEN, parameter k = 10, parameter integer TYPE = 1) ( input logic clk, @@ -83,7 +84,7 @@ module gshare #(parameter XLEN, assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(TableBPDirPredF), diff --git a/src/ifu/bpred/gsharebasic.sv b/src/ifu/bpred/gsharebasic.sv index 165915ce2..2914c3e3f 100644 --- a/src/ifu/bpred/gsharebasic.sv +++ b/src/ifu/bpred/gsharebasic.sv @@ -27,7 +27,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module gsharebasic #(parameter XLEN, +module gsharebasic import cvw::*; #(parameter cvw_t P, + parameter XLEN, parameter k = 10, parameter TYPE = 1) ( input logic clk, @@ -57,7 +58,7 @@ module gsharebasic #(parameter XLEN, assign IndexM = GHRM; end - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(BPDirPredF), diff --git a/src/ifu/bpred/localaheadbp.sv b/src/ifu/bpred/localaheadbp.sv index 6fdf7c3f5..266219416 100644 --- a/src/ifu/bpred/localaheadbp.sv +++ b/src/ifu/bpred/localaheadbp.sv @@ -25,7 +25,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module localaheadbp #(parameter XLEN, +module localaheadbp import cvw::*; #(parameter cvw_t P, + parameter XLEN, parameter m = 6, // 2^m = number of local history branches parameter k = 10) ( // number of past branches stored input logic clk, @@ -58,7 +59,7 @@ module localaheadbp #(parameter XLEN, //assign IndexNextF = LHR; assign IndexM = LHRW; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallD), .ce2(~StallW & ~FlushW), .ra1(LHRF), .rd1(BPDirPredD), @@ -91,7 +92,7 @@ module localaheadbp #(parameter XLEN, assign IndexLHRM = {PCW[m+1] ^ PCW[1], PCW[m:2]}; assign IndexLHRNextF = {PCNextF[m+1] ^ PCNextF[1], PCNextF[m:2]}; - ram2p1r1wbe #(2**m, k) BHT(.clk(clk), + ram2p1r1wbe #(P, 2**m, k) BHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexLHRNextF), .rd1(LHRF), diff --git a/src/ifu/bpred/localbpbasic.sv b/src/ifu/bpred/localbpbasic.sv index 827b756e6..8037b743d 100644 --- a/src/ifu/bpred/localbpbasic.sv +++ b/src/ifu/bpred/localbpbasic.sv @@ -26,7 +26,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module localbpbasic #(parameter XLEN, +module localbpbasic import cvw::*; #(parameter cvw_t P, + parameter XLEN, parameter m = 6, // 2^m = number of local history branches parameter k = 10) ( // number of past branches stored input logic clk, @@ -55,7 +56,7 @@ module localbpbasic #(parameter XLEN, assign IndexNextF = LHR; assign IndexM = LHRM; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(BPDirPredF), diff --git a/src/ifu/bpred/localrepairbp.sv b/src/ifu/bpred/localrepairbp.sv index f7be7e71e..3af6d7b9f 100644 --- a/src/ifu/bpred/localrepairbp.sv +++ b/src/ifu/bpred/localrepairbp.sv @@ -25,7 +25,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module localrepairbp #(parameter XLEN, +module localrepairbp import cvw::*; #(parameter cvw_t P, + parameter XLEN, parameter m = 6, // 2^m = number of local history branches parameter k = 10) ( // number of past branches stored input logic clk, @@ -57,7 +58,7 @@ module localrepairbp #(parameter XLEN, logic SpeculativeFlushedF; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallD), .ce2(~StallW & ~FlushW), .ra1(LHRF), .rd1(BPDirPredD), @@ -88,7 +89,7 @@ module localrepairbp #(parameter XLEN, assign IndexLHRM = {PCW[m+1] ^ PCW[1], PCW[m:2]}; assign IndexLHRNextF = {PCNextF[m+1] ^ PCNextF[1], PCNextF[m:2]}; - ram2p1r1wbe #(2**m, k) BHT(.clk(clk), + ram2p1r1wbe #(P, 2**m, k) BHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexLHRNextF), .rd1(LHRCommittedF), @@ -100,7 +101,7 @@ module localrepairbp #(parameter XLEN, assign IndexLHRD = {PCE[m+1] ^ PCE[1], PCE[m:2]}; assign LHRNextE = BranchD ? {BPDirPredD[1], LHRE[k-1:1]} : LHRE; // *** replace with a small CAM - ram2p1r1wbe #(2**m, k) SHB(.clk(clk), + ram2p1r1wbe #(P, 2**m, k) SHB(.clk(clk), .ce1(~StallF), .ce2(~StallE & ~FlushE), .ra1(IndexLHRNextF), .rd1(LHRSpeculativeF), diff --git a/src/ifu/bpred/twoBitPredictor.sv b/src/ifu/bpred/twoBitPredictor.sv index 7cb3f4173..52e24d901 100644 --- a/src/ifu/bpred/twoBitPredictor.sv +++ b/src/ifu/bpred/twoBitPredictor.sv @@ -26,7 +26,7 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module twoBitPredictor #(parameter XLEN, +module twoBitPredictor import cvw::*; #(parameter cvw_t P, parameter XLEN, parameter k = 10) ( input logic clk, input logic reset, @@ -53,7 +53,7 @@ module twoBitPredictor #(parameter XLEN, assign IndexM = {PCM[k+1] ^ PCM[1], PCM[k:2]}; - ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), + ram2p1r1wbe #(P, 2**k, 2) PHT(.clk(clk), .ce1(~StallF), .ce2(~StallW & ~FlushW), .ra1(IndexNextF), .rd1(BPDirPredF), diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 582dbecbe..1605ed039 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -29,7 +29,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" module decompress #(parameter XLEN)( input logic [31:0] InstrRawD, // 32-bit instruction or raw compressed 16-bit instruction in bottom half @@ -91,18 +90,18 @@ module decompress #(parameter XLEN)( end 5'b00001: InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld 5'b00010: InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw - 5'b00011: if (`XLEN==32) + 5'b00011: if (XLEN==32) InstrD = {immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw else InstrD = {immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld; 5'b00101: InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd 5'b00110: InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw - 5'b00111: if (`XLEN==32) + 5'b00111: if (XLEN==32) InstrD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw else InstrD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd 5'b01000: InstrD = {immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi - 5'b01001: if (`XLEN==32) + 5'b01001: if (XLEN==32) InstrD = {immCJ, 5'b00001, 7'b1101111}; // c.jal else InstrD = {immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw @@ -126,7 +125,7 @@ module decompress #(parameter XLEN)( InstrD = {7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or else // if (instr16[6:5] == 2'b11) InstrD = {7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and - else if (`XLEN > 32) //if (instr16[12:10] == 3'b111) full truth table no need to check [12:10] + else if (XLEN > 32) //if (instr16[12:10] == 3'b111) full truth table no need to check [12:10] if (instr16[6:5] == 2'b00) InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw else if (instr16[6:5] == 2'b01) @@ -151,7 +150,7 @@ module decompress #(parameter XLEN)( 5'b10000: InstrD = {6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli 5'b10001: InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp 5'b10010: InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp - 5'b10011: if (`XLEN == 32) + 5'b10011: if (XLEN == 32) InstrD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp else InstrD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp @@ -170,7 +169,7 @@ module decompress #(parameter XLEN)( InstrD = {7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add 5'b10101: InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp 5'b10110: InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp - 5'b10111: if (`XLEN==32) + 5'b10111: if (XLEN==32) InstrD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp else InstrD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp @@ -181,4 +180,3 @@ module decompress #(parameter XLEN)( endcase end endmodule - diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index f33c150d0..de0200058 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -26,116 +26,115 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module ifu import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic StallF, StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, - output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation + input logic clk, reset, + input logic StallF, StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, + output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation // Command from CPU - input logic InvalidateICacheM, // Clears all instruction cache valid bits - input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE) - input logic InstrValidD, InstrValidE, InstrValidM, - input logic BranchD, BranchE, - input logic JumpD, JumpE, + input logic InvalidateICacheM, // Clears all instruction cache valid bits + input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE) + input logic InstrValidD, InstrValidE, InstrValidM, + input logic BranchD, BranchE, + input logic JumpD, JumpE, // Bus interface output logic [P.PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU input logic [P.XLEN-1:0] HRDATA, // Bus read data from IFU to EBU - input logic IFUHREADY, // Bus ready from IFU to EBU - output logic IFUHWRITE, // Bus write operation from IFU to EBU - output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU - output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU - output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU + input logic IFUHREADY, // Bus ready from IFU to EBU + output logic IFUHWRITE, // Bus write operation from IFU to EBU + output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU + output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU + output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW // Execute output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) - input logic PCSrcE, // Executation stage branch is taken + input logic PCSrcE, // Executation stage branch is taken input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address output logic [P.XLEN-1:0] PCE, // Execution stage instruction address - output logic BPWrongE, // Prediction is wrong - output logic BPWrongM, // Prediction is wrong + output logic BPWrongE, // Prediction is wrong + output logic BPWrongM, // Prediction is wrong // Mem - output logic CommittedF, // I$ or bus memory operation started, delay interrupts + output logic CommittedF, // I$ or bus memory operation started, delay interrupts input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. output logic [P.XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence - output logic [31:0] InstrD, // The decoded instruction in Decode stage - output logic [31:0] InstrM, // The decoded instruction in Memory stage - output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL + output logic [31:0] InstrD, // The decoded instruction in Decode stage + output logic [31:0] InstrM, // The decoded instruction in Memory stage + output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL output logic [P.XLEN-1:0] PCM, // Memory stage instruction address // branch predictor - output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br - output logic BPDirPredWrongM, // Prediction direction is wrong - output logic BTAWrongM, // Prediction target wrong - output logic RASPredPCWrongM, // RAS prediction is wrong - output logic IClassWrongM, // Class prediction is wrong - output logic ICacheStallF, // I$ busy with multicycle operation + output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br + output logic BPDirPredWrongM, // Prediction direction is wrong + output logic BTAWrongM, // Prediction target wrong + output logic RASPredPCWrongM, // RAS prediction is wrong + output logic IClassWrongM, // Class prediction is wrong + output logic ICacheStallF, // I$ busy with multicycle operation // Faults - input logic IllegalBaseInstrD, // Illegal non-compressed instruction - input logic IllegalFPUInstrD, // Illegal FP instruction - output logic InstrPageFaultF, // Instruction page fault - output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP - output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) + input logic IllegalBaseInstrD, // Illegal non-compressed instruction + input logic IllegalFPUInstrD, // Illegal FP instruction + output logic InstrPageFaultF, // Instruction page fault + output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP + output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) // mmu management - input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage + input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB - input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB - input logic ITLBWriteF, // Writes PTE and PageType to ITLB + input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB + input logic ITLBWriteF, // Writes PTE and PageType to ITLB input logic [P.XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration - input logic STATUS_MXR, // Status CSR: make executable page readable - input logic STATUS_SUM, // Status CSR: Supervisor access to user memory - input logic STATUS_MPRV, // Status CSR: modify machine privilege - input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level - input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries - output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk - output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits - input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit - input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP address from privileged unit - output logic InstrAccessFaultF, // Instruction access fault - output logic ICacheAccess, // Report I$ read to performance counters - output logic ICacheMiss // Report I$ miss to performance counters + input logic STATUS_MXR, // Status CSR: make executable page readable + input logic STATUS_SUM, // Status CSR: Supervisor access to user memory + input logic STATUS_MPRV, // Status CSR: modify machine privilege + input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level + input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries + output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk + output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit + input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],// PMP address from privileged unit + output logic InstrAccessFaultF, // Instruction access fault + output logic ICacheAccess, // Report I$ read to performance counters + output logic ICacheMiss // Report I$ miss to performance counters ); - localparam [31:0] nop = 32'h00000013; // instruction for NOP + localparam [31:0] nop = 32'h00000013; // instruction for NOP - logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 - logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) - logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) - logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill - logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) - logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F - logic [P.XLEN-1:0] PCD; // Decode stage instruction address - logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence - logic [P.XLEN-1:0] PCF; // Fetch stage instruction address - logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation - logic [P.XLEN+1:0] PCFExt; // + logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 + logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) + logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) + logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill + logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) + logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F + logic [P.XLEN-1:0] PCD; // Decode stage instruction address + logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence + logic [P.XLEN-1:0] PCF; // Fetch stage instruction address + logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation + logic [P.XLEN+1:0] PCFExt; - logic [31:0] IROMInstrF; // Instruction from the IROM - logic [31:0] ICacheInstrF; // Instruction from the I$ - logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus - logic CompressedF; // The fetched instruction is compressed - logic CompressedD; // The decoded instruction is compressed - logic CompressedE; // The execution instruction is compressed - logic CompressedM; // The execution instruction is compressed - logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill - logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage - logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good + logic [31:0] IROMInstrF; // Instruction from the IROM + logic [31:0] ICacheInstrF; // Instruction from the I$ + logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus + logic CompressedF; // The fetched instruction is compressed + logic CompressedD; // The decoded instruction is compressed + logic CompressedE; // The execution instruction is compressed + logic CompressedM; // The execution instruction is compressed + logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill + logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage + logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good - logic [1:0] IFURWF; // IFU alreays read IFURWF = 10 - logic [31:0] InstrE; // Instruction in the Execution stage - logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush + logic [1:0] IFURWF; // IFU alreays read IFURWF = 10 + logic [31:0] InstrE; // Instruction in the Execution stage + logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush - - logic CacheableF; // PMA indicates instruction address is cacheable - logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF - logic BusStall; // Bus interface busy with multicycle operation - logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation - logic GatedStallD; // StallD gated by selected next spill + logic CacheableF; // PMA indicates instruction address is cacheable + logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF + logic BusStall; // Bus interface busy with multicycle operation + logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation + logic GatedStallD; // StallD gated by selected next spill // branch predictor signal - logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF - logic BusCommittedF; // Bus memory operation in flight, delay interrupts - logic CacheCommittedF; // I$ memory operation started, delay interrupts - logic SelIROM; // PMA indicates instruction address is in the IROM - logic [15:0] InstrRawE, InstrRawM; + logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF + logic BusCommittedF; // Bus memory operation in flight, delay interrupts + logic CacheCommittedF; // I$ memory operation started, delay interrupts + logic SelIROM; // PMA indicates instruction address is in the IROM + logic [15:0] InstrRawE, InstrRawM; assign PCFExt = {2'b00, PCSpillF}; @@ -199,6 +198,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( //////////////////////////////////////////////////////////////////////////////////////////////// // Memory //////////////////////////////////////////////////////////////////////////////////////////////// + // CommittedM tells the CPU's privileged unit the current instruction // in the memory stage is a memory operaton and that memory operation is either completed // or is partially executed. Partially completed memory operations need to prevent an interrupts. @@ -206,7 +206,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( // delay the interrupt until the LSU is in a clean state. assign CommittedF = CacheCommittedF | BusCommittedF; - logic IgnoreRequest; + logic IgnoreRequest; assign IgnoreRequest = ITLBMissF | FlushD; // The IROM uses untranslated addresses, so it is not compatible with virtual memory. @@ -223,16 +223,16 @@ module ifu import cvw::*; #(parameter cvw_t P) ( localparam WORDSPERLINE = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/P.XLEN : 1; localparam LOGBWPL = P.ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1; if(P.ICACHE_SUPPORTED) begin : icache - localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN; - localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) - logic [LINELEN-1:0] FetchBuffer; + localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN; + localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) + logic [LINELEN-1:0] FetchBuffer; logic [P.PA_BITS-1:0] ICacheBusAdr; - logic ICacheBusAck; - logic [1:0] CacheBusRW, BusRW, CacheRWF; + logic ICacheBusAck; + logic [1:0] CacheBusRW, BusRW, CacheRWF; assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; - cache #(.PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS), + cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS), .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), @@ -255,7 +255,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( .Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr), .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), - .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), + .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), .FetchBuffer, .PAdr(PCPF), .BusRW, .Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF)); @@ -321,7 +321,6 @@ module ifu import cvw::*; #(parameter cvw_t P) ( else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4 - //////////////////////////////////////////////////////////////////////////////////////////////// // Branch and Jump Predictor //////////////////////////////////////////////////////////////////////////////////////////////// @@ -341,10 +340,10 @@ module ifu import cvw::*; #(parameter cvw_t P) ( assign NextValidPCE = PCE; end - //////////////////////////////////////////////////////////////////////////////////////////////// // Decode stage pipeline register and compressed instruction decoding. //////////////////////////////////////////////////////////////////////////////////////////////// + // Decode stage pipeline register and logic flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); @@ -374,10 +373,10 @@ module ifu import cvw::*; #(parameter cvw_t P) ( // Instruction and PC/PCLink pipeline registers // Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0. - mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD); - mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); - flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); - flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); + mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD); + mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); + flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); + flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); //flopenr #(P.XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); diff --git a/src/ifu/irom.sv b/src/ifu/irom.sv index 321dd9fa8..1339c26fa 100644 --- a/src/ifu/irom.sv +++ b/src/ifu/irom.sv @@ -25,10 +25,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module irom import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic ce, // Chip Enable. 0: Holds IROMInstrF constant + input logic clk, + input logic ce, // Chip Enable. 0: Holds IROMInstrF constant input logic [P.XLEN-1:0] Adr, // PCNextFSpill - output logic [31:0] IROMInstrF // Instruction read data + output logic [31:0] IROMInstrF // Instruction read data ); localparam XLENBYTES = {{P.PA_BITS-32{1'b0}}, P.XLEN/8}; // XLEN/8, adjusted for width @@ -36,14 +36,13 @@ module irom import cvw::*; #(parameter cvw_t P) ( localparam OFFSET = $clog2(XLENBYTES); logic [P.XLEN-1:0] IROMInstrFFull; - logic [31:0] RawIROMInstrF; - - logic [1:0] AdrD; + logic [31:0] RawIROMInstrF; + logic [1:0] AdrD; flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD); rom1p1r #(ADDR_WDITH, P.XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull)); if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull; - else begin + else begin // IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two // haves. Adr is the Next PCF not PCF so we delay 1 cycle. assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0]; @@ -52,4 +51,3 @@ module irom import cvw::*; #(parameter cvw_t P) ( // The spill logic will handle merging the two together. assign IROMInstrF = AdrD[0] ? {16'b0, RawIROMInstrF[31:16]} : RawIROMInstrF; endmodule - diff --git a/src/ifu/spill.sv b/src/ifu/spill.sv index 27eaa4107..bb018406a 100644 --- a/src/ifu/spill.sv +++ b/src/ifu/spill.sv @@ -29,36 +29,34 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module spill import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic reset, - input logic StallD, FlushD, + input logic clk, + input logic reset, + input logic StallD, FlushD, input logic [P.XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage input logic [P.XLEN-1:2] PCPlus4F, // PCF + 4 input logic [P.XLEN-1:0] PCNextF, // The next PCF - input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed - input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched - input logic ITLBMissF, // ITLB miss, ignore memory request - input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) + input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed + input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched + input logic ITLBMissF, // ITLB miss, ignore memory request + input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill - output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline - output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction - output logic CompressedF); // The fetched instruction is compressed + output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline + output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction + output logic CompressedF); // The fetched instruction is compressed // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1] - typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; - localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1; + typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; + localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1; - statetype CurrState, NextState; + statetype CurrState, NextState; logic [P.XLEN-1:0] PCPlus2F; - logic TakeSpillF; - logic SpillF; - logic SelSpillF; - logic SpillSaveF; - logic [15:0] InstrFirstHalfF; + logic TakeSpillF; + logic SpillF; + logic SelSpillF; + logic SpillSaveF; + logic [15:0] InstrFirstHalfF; //////////////////////////////////////////////////////////////////////////////////////////////////// // PC logic @@ -71,7 +69,6 @@ module spill import cvw::*; #(parameter cvw_t P) ( // select between PCF and PCF+2 mux2 #(P.XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCSpillF)); - //////////////////////////////////////////////////////////////////////////////////////////////////// // Detect spill //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/lsu/amoalu.sv b/src/lsu/amoalu.sv index 524a4cf75..c8b7ccee3 100644 --- a/src/lsu/amoalu.sv +++ b/src/lsu/amoalu.sv @@ -30,8 +30,8 @@ module amoalu import cvw::*; #(parameter cvw_t P) ( input logic [P.XLEN-1:0] ReadDataM, // LSU's ReadData input logic [P.XLEN-1:0] IHWriteDataM, // LSU's WriteData - input logic [6:0] LSUFunct7M, // ALU Operation - input logic [2:0] LSUFunct3M, // Memoy access width + input logic [6:0] LSUFunct7M, // ALU Operation + input logic [2:0] LSUFunct3M, // Memoy access width output logic [P.XLEN-1:0] AMOResultM // ALU output ); @@ -72,4 +72,3 @@ module amoalu import cvw::*; #(parameter cvw_t P) ( end end endmodule - diff --git a/src/lsu/atomic.sv b/src/lsu/atomic.sv index 5c2035699..117a42c2b 100644 --- a/src/lsu/atomic.sv +++ b/src/lsu/atomic.sv @@ -28,24 +28,24 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module atomic import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic reset, - input logic StallW, + input logic clk, + input logic reset, + input logic StallW, input logic [P.XLEN-1:0] ReadDataM, // LSU ReadData XLEN because FPU does not issue atomic memory operation from FPU registers input logic [P.XLEN-1:0] IHWriteDataM, // LSU WriteData XLEN because FPU does not issue atomic memory operation from FPU registers input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address - input logic [6:0] LSUFunct7M, // AMO alu operation gated by HPTW - input logic [2:0] LSUFunct3M, // IEU or HPTW memory operation size - input logic [1:0] LSUAtomicM, // 10: AMO operation, select AMOResultM as the writedata output, 01: LR/SC operation - input logic [1:0] PreLSURWM, // IEU or HPTW Read/Write signal - input logic IgnoreRequest, // On FlushM or TLB miss ignore memory operation + input logic [6:0] LSUFunct7M, // AMO alu operation gated by HPTW + input logic [2:0] LSUFunct3M, // IEU or HPTW memory operation size + input logic [1:0] LSUAtomicM, // 10: AMO operation, select AMOResultM as the writedata output, 01: LR/SC operation + input logic [1:0] PreLSURWM, // IEU or HPTW Read/Write signal + input logic IgnoreRequest, // On FlushM or TLB miss ignore memory operation output logic [P.XLEN-1:0] IMAWriteDataM, // IEU, HPTW, or AMO write data - output logic SquashSCW, // Store conditional failed disable write to GPR - output logic [1:0] LSURWM // IEU or HPTW Read/Write signal gated by LR/SC + output logic SquashSCW, // Store conditional failed disable write to GPR + output logic [1:0] LSURWM // IEU or HPTW Read/Write signal gated by LR/SC ); logic [P.XLEN-1:0] AMOResultM; - logic MemReadM; + logic MemReadM; amoalu #(P) amoalu(.ReadDataM, .IHWriteDataM, .LSUFunct7M, .LSUFunct3M, .AMOResultM); diff --git a/src/lsu/dtim.sv b/src/lsu/dtim.sv index 36b3af1a3..c8668e767 100644 --- a/src/lsu/dtim.sv +++ b/src/lsu/dtim.sv @@ -28,17 +28,17 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module dtim import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic FlushW, - input logic ce, // Chip Enable. 0: Holds ReadDataWordM - input logic [1:0] MemRWM, // Read/Write control + input logic clk, + input logic FlushW, + input logic ce, // Chip Enable. 0: Holds ReadDataWordM + input logic [1:0] MemRWM, // Read/Write control input logic [P.PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address input logic [P.LLEN-1:0] WriteDataM, // Write data from IEU input logic [P.LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write output logic [P.LLEN-1:0] ReadDataWordM // Read data before subword selection ); - logic we; + logic we; localparam LLENBYTES = P.LLEN/8; // verilator lint_off WIDTH @@ -49,7 +49,6 @@ module dtim import cvw::*; #(parameter cvw_t P) ( assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap. - ram1p1rwbe #(.DEPTH(DEPTH), .WIDTH(P.LLEN)) + ram1p1rwbe #(.P(P), .DEPTH(DEPTH), .WIDTH(P.LLEN)) ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM)); endmodule - diff --git a/src/lsu/lrsc.sv b/src/lsu/lrsc.sv index a1fbe6fdb..cc6c94ba8 100644 --- a/src/lsu/lrsc.sv +++ b/src/lsu/lrsc.sv @@ -29,23 +29,23 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module lrsc import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic reset, - input logic StallW, - input logic MemReadM, // Memory read - input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write - output logic [1:0] LSURWM, // Memory operation after potential squash of SC - input logic [1:0] LSUAtomicM, // Atomic memory operaiton + input logic clk, + input logic reset, + input logic StallW, + input logic MemReadM, // Memory read + input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write + output logic [1:0] LSURWM, // Memory operation after potential squash of SC + input logic [1:0] LSUAtomicM, // Atomic memory operaiton input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address - output logic SquashSCW // Squash the store conditional by not allowing rf write + output logic SquashSCW // Squash the store conditional by not allowing rf write ); // possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest. // Handle atomic load reserved / store conditional logic [P.PA_BITS-1:2] ReservationPAdrW; - logic ReservationValidM, ReservationValidW; - logic lrM, scM, WriteAdrMatchM; - logic SquashSCM; + logic ReservationValidM, ReservationValidW; + logic lrM, scM, WriteAdrMatchM; + logic SquashSCM; assign lrM = MemReadM & LSUAtomicM[0]; assign scM = PreLSURWM[0] & LSUAtomicM[0]; diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 595f1eec4..9c0d00543 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -30,63 +30,63 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////// module lsu import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic StallM, FlushM, StallW, FlushW, - output logic LSUStallM, // LSU stalls pipeline during a multicycle operation + input logic clk, reset, + input logic StallM, FlushM, StallW, FlushW, + output logic LSUStallM, // LSU stalls pipeline during a multicycle operation // connected to cpu (controls) - input logic [1:0] MemRWM, // Read/Write control - input logic [2:0] Funct3M, // Size of memory operation - input logic [6:0] Funct7M, // Atomic memory operation function - input logic [1:0] AtomicM, // Atomic memory operation - input logic FlushDCacheM, // Flush D cache to next level of memory - output logic CommittedM, // Delay interrupts while memory operation in flight - output logic SquashSCW, // Store conditional failed disable write to GPR - output logic DCacheMiss, // D cache miss for performance counters - output logic DCacheAccess, // D cache memory access for performance counters + input logic [1:0] MemRWM, // Read/Write control + input logic [2:0] Funct3M, // Size of memory operation + input logic [6:0] Funct7M, // Atomic memory operation function + input logic [1:0] AtomicM, // Atomic memory operation + input logic FlushDCacheM, // Flush D cache to next level of memory + output logic CommittedM, // Delay interrupts while memory operation in flight + output logic SquashSCW, // Store conditional failed disable write to GPR + output logic DCacheMiss, // D cache miss for performance counters + output logic DCacheAccess, // D cache memory access for performance counters // address and write data - input logic [P.XLEN-1:0] IEUAdrE, // Execution stage memory address - output logic [P.XLEN-1:0] IEUAdrM, // Memory stage memory address - input logic [P.XLEN-1:0] WriteDataM, // Write data from IEU - output logic [P.LLEN-1:0] ReadDataW, // Read data to IEU or FPU + input logic [P.XLEN-1:0] IEUAdrE, // Execution stage memory address + output logic [P.XLEN-1:0] IEUAdrM, // Memory stage memory address + input logic [P.XLEN-1:0] WriteDataM, // Write data from IEU + output logic [P.LLEN-1:0] ReadDataW, // Read data to IEU or FPU // cpu privilege - input logic [1:0] PrivilegeModeW, // Current privilege mode - input logic BigEndianM, // Swap byte order to big endian - input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries - output logic DCacheStallM, // D$ busy with multicycle operation + input logic [1:0] PrivilegeModeW, // Current privilege mode + input logic BigEndianM, // Swap byte order to big endian + input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries + output logic DCacheStallM, // D$ busy with multicycle operation // fpu - input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU - input logic FpLoadStoreM, // Selects FPU as store for write data + input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU + input logic FpLoadStoreM, // Selects FPU as store for write data // faults - output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions - output logic LoadMisalignedFaultM, // Load address misaligned fault - output logic LoadAccessFaultM, // Load access fault (PMA) - output logic HPTWInstrAccessFaultF, // HPTW generated access fault during instruction fetch + output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions + output logic LoadMisalignedFaultM, // Load address misaligned fault + output logic LoadAccessFaultM, // Load access fault (PMA) + output logic HPTWInstrAccessFaultF, // HPTW generated access fault during instruction fetch // cpu hazard unit (trap) - output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault - output logic StoreAmoAccessFaultM, // Store or AMO access fault + output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault + output logic StoreAmoAccessFaultM, // Store or AMO access fault // connect to ahb - output logic [P.PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU - input logic [P.XLEN-1:0] HRDATA, // Bus read data from LSU to EBU - output logic [P.XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU - input logic LSUHREADY, // Bus ready from LSU to EBU - output logic LSUHWRITE, // Bus write operation from LSU to EBU - output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU - output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU - output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU - output logic [P.XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU + output logic [P.PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU + input logic [P.XLEN-1:0] HRDATA, // Bus read data from LSU to EBU + output logic [P.XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU + input logic LSUHREADY, // Bus ready from LSU to EBU + output logic LSUHWRITE, // Bus write operation from LSU to EBU + output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU + output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU + output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU + output logic [P.XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU // page table walker - input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR - input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege - input logic [1:0] STATUS_MPP, // Machine previous privilege mode - input logic [P.XLEN-1:0] PCSpillF, // Fetch PC - input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk - input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits - output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB - output logic [1:0] PageType, // Type of page table entry to write to ITLB - output logic ITLBWriteF, // Write PTE to ITLB - output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE - input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit - input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP address from privileged unit + input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege + input logic [1:0] STATUS_MPP, // Machine previous privilege mode + input logic [P.XLEN-1:0] PCSpillF, // Fetch PC + input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk + input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits + output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB + output logic [1:0] PageType, // Type of page table entry to write to ITLB + output logic ITLBWriteF, // Write PTE to ITLB + output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit + input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP address from privileged unit ); logic [P.XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer @@ -94,20 +94,20 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic [P.PA_BITS-1:0] PAdrM; // Physical memory address logic [P.XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address - logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal - logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC - logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size - logic [6:0] LSUFunct7M; // AMO function gated by HPTW - logic [1:0] LSUAtomicM; // AMO signal gated by HPTW + logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal + logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC + logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size + logic [6:0] LSUFunct7M; // AMO function gated by HPTW + logic [1:0] LSUAtomicM; // AMO signal gated by HPTW - logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1 + logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1 - logic BusStall; // Bus interface busy with multicycle operation - logic HPTWStall; // HPTW busy with multicycle operation + logic BusStall; // Bus interface busy with multicycle operation + logic HPTWStall; // HPTW busy with multicycle operation - logic CacheableM; // PMA indicates memory address is cacheable - logic BusCommittedM; // Bus memory operation in flight, delay interrupts - logic DCacheCommittedM; // D$ memory operation started, delay interrupts + logic CacheableM; // PMA indicates memory address is cacheable + logic BusCommittedM; // Bus memory operation in flight, delay interrupts + logic DCacheCommittedM; // D$ memory operation started, delay interrupts logic [P.LLEN-1:0] DTIMReadDataWordM; // DTIM read data logic [P.LLEN-1:0] DCacheReadDataWordM; // D$ read data @@ -123,16 +123,15 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic [P.LLEN-1:0] LSUWriteDataM; // Final write data logic [(P.LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write - logic DTLBMissM; // DTLB miss causes HPTW walk - logic DTLBWriteM; // Writes PTE and PageType to DTLB - logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits - logic LSULoadAccessFaultM; // Load acces fault - logic LSUStoreAmoAccessFaultM; // Store access fault - logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle - logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation - logic SelDTIM; // Select DTIM rather than bus or D$ + logic DTLBMissM; // DTLB miss causes HPTW walk + logic DTLBWriteM; // Writes PTE and PageType to DTLB + logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits + logic LSULoadAccessFaultM; // Load acces fault + logic LSUStoreAmoAccessFaultM; // Store access fault + logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle + logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation + logic SelDTIM; // Select DTIM rather than bus or D$ - ///////////////////////////////////////////////////////////////////////////////////////////// // Pipeline for IEUAdr E to M // Zero-extend address to 34 bits for XLEN=32 @@ -222,7 +221,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( if (P.DTIM_SUPPORTED) begin : dtim logic [P.PA_BITS-1:0] DTIMAdr; - logic [1:0] DTIMMemRWM; + logic [1:0] DTIMMemRWM; // The DTIM uses untranslated addresses, so it is not compatible with virtual memory. mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr); @@ -237,23 +236,23 @@ module lsu import cvw::*; #(parameter cvw_t P) ( if (P.BUS_SUPPORTED) begin : bus if(P.DCACHE_SUPPORTED) begin : dcache localparam LLENWORDSPERLINE = P.DCACHE_LINELENINBITS/P.LLEN; // Number of LLEN words in cacheline - localparam LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^ + localparam LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^ localparam BEATSPERLINE = P.DCACHE_LINELENINBITS/P.AHBW; // Number of AHBW words (beats) in cacheline - localparam AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^ - localparam LINELEN = P.DCACHE_LINELENINBITS; // Number of bits in cacheline + localparam AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^ + localparam LINELEN = P.DCACHE_LINELENINBITS; // Number of bits in cacheline localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) - logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline - logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. - logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache - logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback - logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount - logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface - logic [1:0] BusRW; // Uncached bus memory access - logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush - logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11) - logic [1:0] CacheAtomicM; // Cache AMO - logic FlushDCache; // Suppress d cache flush if there is an ITLB miss. + logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline + logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. + logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache + logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback + logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount + logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface + logic [1:0] BusRW; // Uncached bus memory access + logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush + logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11) + logic [1:0] CacheAtomicM; // Cache AMO + logic FlushDCache; // Suppress d cache flush if there is an ITLB miss. assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; @@ -261,7 +260,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0; assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW); - cache #(.PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), + cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(P.LLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache( .clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM), .FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM), @@ -320,6 +319,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( ///////////////////////////////////////////////////////////////////////////////////////////// // Atomic operations ///////////////////////////////////////////////////////////////////////////////////////////// + if (P.A_SUPPORTED) begin:atomic atomic #(P) atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[P.XLEN-1:0]), .IHWriteDataM, .PAdrM, .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, @@ -335,6 +335,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( ///////////////////////////////////////////////////////////////////////////////////////////// // Subword Accesses ///////////////////////////////////////////////////////////////////////////////////////////// + subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); subwordwrite #(P.LLEN) subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM); @@ -361,5 +362,4 @@ module lsu import cvw::*; #(parameter cvw_t P) ( assign LSUWriteDataM = LittleEndianWriteDataM; assign LittleEndianReadDataWordM = ReadDataWordMuxM; end - endmodule diff --git a/src/lsu/subwordread.sv b/src/lsu/subwordread.sv index 4c529ec07..e5666eb84 100644 --- a/src/lsu/subwordread.sv +++ b/src/lsu/subwordread.sv @@ -29,12 +29,12 @@ module subwordread #(parameter LLEN) ( - input logic [LLEN-1:0] ReadDataWordMuxM, + input logic [LLEN-1:0] ReadDataWordMuxM, input logic [2:0] PAdrM, input logic [2:0] Funct3M, input logic FpLoadStoreM, input logic BigEndianM, - output logic [LLEN-1:0] ReadDataM + output logic [LLEN-1:0] ReadDataM ); logic [7:0] ByteM; @@ -89,7 +89,7 @@ module subwordread #(parameter LLEN) //3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128 3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu 3'b110: ReadDataM = {{LLEN-32{1'b0}}, WordM[31:0]}; // lwu - default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen + default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen endcase end else begin:swrmux // 32-bit diff --git a/src/lsu/subwordwrite.sv b/src/lsu/subwordwrite.sv index f53f121e7..ad21b3c25 100644 --- a/src/lsu/subwordwrite.sv +++ b/src/lsu/subwordwrite.sv @@ -28,8 +28,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module subwordwrite #(parameter LLEN) ( - input logic [2:0] LSUFunct3M, - input logic [LLEN-1:0] IMAFWriteDataM, + input logic [2:0] LSUFunct3M, + input logic [LLEN-1:0] IMAFWriteDataM, output logic [LLEN-1:0] LittleEndianWriteDataM ); @@ -46,18 +46,18 @@ module subwordwrite #(parameter LLEN) ( end else if (LLEN == 64) begin:sww always_comb case(LSUFunct3M[1:0]) - 2'b00: LittleEndianWriteDataM = {8{IMAFWriteDataM[7:0]}}; // sb - 2'b01: LittleEndianWriteDataM = {4{IMAFWriteDataM[15:0]}}; // sh - 2'b10: LittleEndianWriteDataM = {2{IMAFWriteDataM[31:0]}}; // sw - 2'b11: LittleEndianWriteDataM = IMAFWriteDataM; // sd + 2'b00: LittleEndianWriteDataM = {8{IMAFWriteDataM[7:0]}}; // sb + 2'b01: LittleEndianWriteDataM = {4{IMAFWriteDataM[15:0]}}; // sh + 2'b10: LittleEndianWriteDataM = {2{IMAFWriteDataM[31:0]}}; // sw + 2'b11: LittleEndianWriteDataM = IMAFWriteDataM; // sd endcase end else begin:sww // 32-bit always_comb case(LSUFunct3M[1:0]) - 2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb - 2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh - 2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw - default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen + 2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb + 2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh + 2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw + default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen endcase end endmodule diff --git a/src/lsu/swbytemask.sv b/src/lsu/swbytemask.sv index 51076fc7d..ad20a4414 100644 --- a/src/lsu/swbytemask.sv +++ b/src/lsu/swbytemask.sv @@ -28,9 +28,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module swbytemask #(parameter WORDLEN)( - input logic [2:0] Size, - input logic [$clog2(WORDLEN/8)-1:0] Adr, - output logic [WORDLEN/8-1:0] ByteMask + input logic [2:0] Size, + input logic [$clog2(WORDLEN/8)-1:0] Adr, + output logic [WORDLEN/8-1:0] ByteMask ); assign ByteMask = ((2**(2**Size))-1) << Adr; diff --git a/src/mdu/div.sv b/src/mdu/div.sv index a05e88f6d..c550c06fc 100644 --- a/src/mdu/div.sv +++ b/src/mdu/div.sv @@ -27,38 +27,38 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module div import cvw::*; #(parameter cvw_t P) ( - input logic clk, - input logic reset, - input logic StallM, - input logic FlushE, - input logic IntDivE, // integer division/remainder instruction of any type - input logic DivSignedE, // signed division - input logic W64E, // W-type instructions (divw, divuw, remw, remuw) - input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE,// Forwarding mux outputs for Source A and B - output logic DivBusyE, // Divide is busy - stall pipeline - output logic [P.XLEN-1:0] QuotM, RemM // Quotient and remainder outputs + input logic clk, + input logic reset, + input logic StallM, + input logic FlushE, + input logic IntDivE, // integer division/remainder instruction of any type + input logic DivSignedE, // signed division + input logic W64E, // W-type instructions (divw, divuw, remw, remuw) + input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Forwarding mux outputs for Source A and B + output logic DivBusyE, // Divide is busy - stall pipeline + output logic [P.XLEN-1:0] QuotM, RemM // Quotient and remainder outputs ); localparam STEPBITS = $clog2(P.XLEN/P.IDIV_BITSPERCYCLE); // Number of steps - typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; // division FSM state + typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; // division FSM state statetype state; logic [P.XLEN-1:0] W[P.IDIV_BITSPERCYCLE:0]; // Residual for each of k steps logic [P.XLEN-1:0] XQ[P.IDIV_BITSPERCYCLE:0]; // dividend/quotient for each of k steps - logic [P.XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers - logic [P.XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits - logic [P.XLEN-1:0] DnE; // DnE = ~DinE - logic [P.XLEN-1:0] DAbsBE; // absolute value of D - logic [P.XLEN-1:0] DAbsB; // registered absolute value of D, constant during division - logic [P.XLEN-1:0] XnE; // DXnE = ~XinE - logic [P.XLEN-1:0] XInitE; // |X|, or original X for divide by 0 - logic [P.XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction - logic [STEPBITS:0] step; // division step - logic Div0E, Div0M; // divide by 0 - logic DivStartE; // start integer division - logic SignXE, SignDE; // sign of dividend and divisor - logic NegQE, NegWM, NegQM; // negate quotient or residual during postprocessing + logic [P.XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers + logic [P.XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits + logic [P.XLEN-1:0] DnE; // DnE = ~DinE + logic [P.XLEN-1:0] DAbsBE; // absolute value of D + logic [P.XLEN-1:0] DAbsB; // registered absolute value of D, constant during division + logic [P.XLEN-1:0] XnE; // DXnE = ~XinE + logic [P.XLEN-1:0] XInitE; // |X|, or original X for divide by 0 + logic [P.XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction + logic [STEPBITS:0] step; // division step + logic Div0E, Div0M; // divide by 0 + logic DivStartE; // start integer division + logic SignXE, SignDE; // sign of dividend and divisor + logic NegQE, NegWM, NegQM; // negate quotient or residual during postprocessing ////////////////////////////// // Execute Stage: prepare for division calculation with control logic, W logic and absolute values, initialize W and XQ @@ -105,7 +105,7 @@ module div import cvw::*; #(parameter cvw_t P) ( // one copy of divstep for each bit produced per cycle genvar i; for (i=0; i PMPAdr[i] + logic EnforcePMP; // should PMP be checked in this privilege level + logic [P.PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges + logic [P.PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. + logic [P.PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set + logic [P.PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0 pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0]( diff --git a/src/mmu/tlb/vm64check.sv b/src/mmu/tlb/vm64check.sv index 10ca759a0..a089031c2 100644 --- a/src/mmu/tlb/vm64check.sv +++ b/src/mmu/tlb/vm64check.sv @@ -26,8 +26,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - module vm64check import cvw::*; #(parameter cvw_t P) ( input logic [P.SVMODE_BITS-1:0] SATP_MODE, input logic [P.XLEN-1:0] VAdr, diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 7bf2bf7d5..fba8a89c5 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -29,66 +29,66 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csr import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic FlushM, FlushW, - input logic StallE, StallM, StallW, - input logic [31:0] InstrM, // current instruction - input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL - input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic - input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU - input logic CSRReadM, CSRWriteM, // read or write CSR - input logic TrapM, // trap is occurring - input logic mretM, sretM, wfiM, // return or WFI instruction - input logic IntPendingM, // at least one interrupt is pending and could occur if enabled - input logic InterruptM, // interrupt is occurring - input logic ExceptionM, // interrupt is occurring - input logic MTimerInt, // timer interrupt - input logic MExtInt, SExtInt, // external interrupt (from PLIC) - input logic MSwInt, // software interrupt - input logic [63:0] MTIME_CLINT, // TIME value from CLINT - input logic InstrValidM, // current instruction is valid - input logic FRegWriteM, // writes to floating point registers change STATUS.FS - input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR - input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode - input logic [1:0] PrivilegeModeW, // current privilege mode - input logic [3:0] CauseM, // Trap cause - input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode + input logic clk, reset, + input logic FlushM, FlushW, + input logic StallE, StallM, StallW, + input logic [31:0] InstrM, // current instruction + input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL + input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic + input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU + input logic CSRReadM, CSRWriteM, // read or write CSR + input logic TrapM, // trap is occurring + input logic mretM, sretM, wfiM, // return or WFI instruction + input logic IntPendingM, // at least one interrupt is pending and could occur if enabled + input logic InterruptM, // interrupt is occurring + input logic ExceptionM, // interrupt is occurring + input logic MTimerInt, // timer interrupt + input logic MExtInt, SExtInt, // external interrupt (from PLIC) + input logic MSwInt, // software interrupt + input logic [63:0] MTIME_CLINT, // TIME value from CLINT + input logic InstrValidM, // current instruction is valid + input logic FRegWriteM, // writes to floating point registers change STATUS.FS + input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR + input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode + input logic [1:0] PrivilegeModeW, // current privilege mode + input logic [3:0] CauseM, // Trap cause + input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode // inputs for performance counters - input logic LoadStallD, - input logic StoreStallD, - input logic ICacheStallF, - input logic DCacheStallM, - input logic BPDirPredWrongM, - input logic BTAWrongM, - input logic RASPredPCWrongM, - input logic IClassWrongM, - input logic BPWrongM, // branch predictor is wrong - input logic [3:0] InstrClassM, - input logic DCacheMiss, - input logic DCacheAccess, - input logic ICacheMiss, - input logic ICacheAccess, - input logic sfencevmaM, - input logic InvalidateICacheM, - input logic DivBusyE, // integer divide busy - input logic FDivBusyE, // floating point divide busy + input logic LoadStallD, + input logic StoreStallD, + input logic ICacheStallF, + input logic DCacheStallM, + input logic BPDirPredWrongM, + input logic BTAWrongM, + input logic RASPredPCWrongM, + input logic IClassWrongM, + input logic BPWrongM, // branch predictor is wrong + input logic [3:0] InstrClassM, + input logic DCacheMiss, + input logic DCacheAccess, + input logic ICacheMiss, + input logic ICacheAccess, + input logic sfencevmaM, + input logic InvalidateICacheM, + input logic DivBusyE, // integer divide busy + input logic FDivBusyE, // floating point divide busy // outputs from CSRs - output logic [1:0] STATUS_MPP, - output logic STATUS_SPP, STATUS_TSR, STATUS_TVM, - output logic [15:0] MEDELEG_REGW, - output logic [P.XLEN-1:0] SATP_REGW, - output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, - output logic STATUS_MIE, STATUS_SIE, - output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, - output logic [1:0] STATUS_FS, - output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], + output logic [1:0] STATUS_MPP, + output logic STATUS_SPP, STATUS_TSR, STATUS_TVM, + output logic [15:0] MEDELEG_REGW, + output logic [P.XLEN-1:0] SATP_REGW, + output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, + output logic STATUS_MIE, STATUS_SIE, + output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, + output logic [1:0] STATUS_FS, + output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], - output logic [2:0] FRM_REGW, + output logic [2:0] FRM_REGW, // - output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR - output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns - output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level - output logic BigEndianM // memory access is big-endian based on privilege mode and STATUS register endian fields + output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR + output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns + output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level + output logic BigEndianM // memory access is big-endian based on privilege mode and STATUS register endian fields ); localparam MIP = 12'h344; @@ -180,13 +180,13 @@ module csr import cvw::*; #(parameter cvw_t P) ( else CSRReadVal2M = CSRReadValM; // Compute AND/OR modification - CSRRWM = CSRSrcM; - CSRRSM = CSRReadVal2M | CSRSrcM; - CSRRCM = CSRReadVal2M & ~CSRSrcM; + CSRRWM = CSRSrcM; + CSRRSM = CSRReadVal2M | CSRSrcM; + CSRRCM = CSRReadVal2M & ~CSRSrcM; case (InstrM[13:12]) - 2'b01: CSRWriteValM = CSRRWM; - 2'b10: CSRWriteValM = CSRRSM; - 2'b11: CSRWriteValM = CSRRCM; + 2'b01: CSRWriteValM = CSRRWM; + 2'b10: CSRWriteValM = CSRRSM; + 2'b11: CSRWriteValM = CSRRCM; default: CSRWriteValM = CSRReadValM; endcase end diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index f6f228dd8..0ee13d865 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -1,5 +1,3 @@ - - /////////////////////////////////////////// // csrc.sv // @@ -31,57 +29,57 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csrc import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic StallE, StallM, - input logic FlushM, - input logic InstrValidNotFlushedM, LoadStallD, StoreStallD, - input logic CSRMWriteM, CSRWriteM, - input logic BPDirPredWrongM, - input logic BTAWrongM, - input logic RASPredPCWrongM, - input logic IClassWrongM, - input logic BPWrongM, // branch predictor is wrong - input logic [3:0] InstrClassM, - input logic DCacheMiss, - input logic DCacheAccess, - input logic ICacheMiss, - input logic ICacheAccess, - input logic ICacheStallF, - input logic DCacheStallM, - input logic sfencevmaM, - input logic InterruptM, - input logic ExceptionM, - input logic InvalidateICacheM, - input logic DivBusyE, // integer divide busy - input logic FDivBusyE, // floating point divide busy - input logic [11:0] CSRAdrM, - input logic [1:0] PrivilegeModeW, + input logic clk, reset, + input logic StallE, StallM, + input logic FlushM, + input logic InstrValidNotFlushedM, LoadStallD, StoreStallD, + input logic CSRMWriteM, CSRWriteM, + input logic BPDirPredWrongM, + input logic BTAWrongM, + input logic RASPredPCWrongM, + input logic IClassWrongM, + input logic BPWrongM, // branch predictor is wrong + input logic [3:0] InstrClassM, + input logic DCacheMiss, + input logic DCacheAccess, + input logic ICacheMiss, + input logic ICacheAccess, + input logic ICacheStallF, + input logic DCacheStallM, + input logic sfencevmaM, + input logic InterruptM, + input logic ExceptionM, + input logic InvalidateICacheM, + input logic DivBusyE, // integer divide busy + input logic FDivBusyE, // floating point divide busy + input logic [11:0] CSRAdrM, + input logic [1:0] PrivilegeModeW, input logic [P.XLEN-1:0] CSRWriteValM, - input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, - input logic [63:0] MTIME_CLINT, + input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, + input logic [63:0] MTIME_CLINT, output logic [P.XLEN-1:0] CSRCReadValM, - output logic IllegalCSRCAccessM + output logic IllegalCSRCAccessM ); - localparam MHPMCOUNTERBASE = 12'hB00; - localparam MTIME = 12'hB01; // this is a memory-mapped register; no such CSR exists, and access should faul; + localparam MHPMCOUNTERBASE = 12'hB00; + localparam MTIME = 12'hB01; // this is a memory-mapped register; no such CSR exists, and access should faul; localparam MHPMCOUNTERHBASE = 12'hB80; - localparam MTIMEH = 12'hB81; // this is a memory-mapped register; no such CSR exists, and access should fault - localparam MHPMEVENTBASE = 12'h320; - localparam HPMCOUNTERBASE = 12'hC00; - localparam HPMCOUNTERHBASE = 12'hC80; - localparam TIME = 12'hC01; - localparam TIMEH = 12'hC81; + localparam MTIMEH = 12'hB81; // this is a memory-mapped register; no such CSR exists, and access should fault + localparam MHPMEVENTBASE = 12'h320; + localparam HPMCOUNTERBASE = 12'hC00; + localparam HPMCOUNTERHBASE = 12'hC80; + localparam TIME = 12'hC01; + localparam TIMEH = 12'hC81; logic [4:0] CounterNumM; - 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] HPMCOUNTER_REGW[P.COUNTERS-1:0]; + logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0]; logic LoadStallE, LoadStallM; logic StoreStallE, StoreStallM; - logic [P.COUNTERS-1:0] WriteHPMCOUNTERM; - logic [P.COUNTERS-1:0] CounterEvent; + logic [P.COUNTERS-1:0] WriteHPMCOUNTERM; + logic [P.COUNTERS-1:0] CounterEvent; logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0]; - logic [P.XLEN-1:0] NextHPMCOUNTERM[P.COUNTERS-1:0]; + logic [P.XLEN-1:0] NextHPMCOUNTERM[P.COUNTERS-1:0]; genvar i; // Interface signals @@ -89,34 +87,34 @@ module csrc import cvw::*; #(parameter cvw_t P) ( flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM})); // Determine when to increment each counter - assign CounterEvent[0] = 1'b1; // MCYCLE always increments - assign CounterEvent[1] = 1'b0; // Counter 1 doesn't exist - assign CounterEvent[2] = InstrValidNotFlushedM; // MINSTRET instructions retired - if (P.ZIHPM_SUPPORTED) begin: cevent // User-defined counters - assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction - assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions - assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions - assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong - assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction - assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target - assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address - assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong - assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. - assign CounterEvent[12] = StoreStallM; // Store Stall - assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access - assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss - assign CounterEvent[15] = DCacheStallM; // d cache miss cycles - assign CounterEvent[16] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access - assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss - assign CounterEvent[18] = ICacheStallF; // i cache miss cycles - assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes - assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i - assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma - assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low - assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low + assign CounterEvent[0] = 1'b1; // MCYCLE always increments + assign CounterEvent[1] = 1'b0; // Counter 1 doesn't exist + assign CounterEvent[2] = InstrValidNotFlushedM; // MINSTRET instructions retired + if (P.ZIHPM_SUPPORTED) begin: cevent // User-defined counters + assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction + assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions + assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions + assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong + assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction + assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target + assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address + assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong + assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. + assign CounterEvent[12] = StoreStallM; // Store Stall + assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access + assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss + assign CounterEvent[15] = DCacheStallM; // d cache miss cycles + assign CounterEvent[16] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access + assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss + assign CounterEvent[18] = ICacheStallF; // i cache miss cycles + assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes + assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i + assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma + assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low + assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low // coverage off // DivBusyE will never be assert high since this configuration uses the FPU to do integer division - assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle + assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle // coverage on assign CounterEvent[P.COUNTERS-1:25] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions end else begin: cevent @@ -158,7 +156,7 @@ module csrc import cvw::*; #(parameter cvw_t P) ( /* verilator lint_on WIDTH */ else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+P.COUNTERS & CSRAdrM != MTIME) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; - else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+P.COUNTERS) + else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+P.COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; else begin CSRCReadValM = 0; @@ -189,4 +187,4 @@ module csrc import cvw::*; #(parameter cvw_t P) ( end endmodule -// mounteren should only exist if u-mode exists +// mounteren should only exist if u-mode exists \ No newline at end of file diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index c7e6ca51a..ca89617d9 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -82,7 +82,6 @@ module csri import cvw::*; #(parameter cvw_t P) ( else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222 & MIDELEG_REGW) | (MIE_REGW & 12'h888); // only S fields - assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0, MTimerInt, 1'b0, STIP, 1'b0, MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0}; diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index 40dc73996..61226f790 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -62,44 +62,44 @@ module csrm import cvw::*; #(parameter cvw_t P) ( logic WriteMENVCFGM; // Machine CSRs - localparam MVENDORID = 12'hF11; - localparam MARCHID = 12'hF12; - localparam MIMPID = 12'hF13; - localparam MHARTID = 12'hF14; - localparam MCONFIGPTR = 12'hF15; - localparam MSTATUS = 12'h300; - localparam MISA_ADR = 12'h301; - localparam MEDELEG = 12'h302; - localparam MIDELEG = 12'h303; - localparam MIE = 12'h304; - localparam MTVEC = 12'h305; - localparam MCOUNTEREN = 12'h306; - localparam MENVCFG = 12'h30A; - localparam MSTATUSH = 12'h310; - localparam MENVCFGH = 12'h31A; + localparam MVENDORID = 12'hF11; + localparam MARCHID = 12'hF12; + localparam MIMPID = 12'hF13; + localparam MHARTID = 12'hF14; + localparam MCONFIGPTR = 12'hF15; + localparam MSTATUS = 12'h300; + localparam MISA_ADR = 12'h301; + localparam MEDELEG = 12'h302; + localparam MIDELEG = 12'h303; + localparam MIE = 12'h304; + localparam MTVEC = 12'h305; + localparam MCOUNTEREN = 12'h306; + localparam MENVCFG = 12'h30A; + localparam MSTATUSH = 12'h310; + localparam MENVCFGH = 12'h31A; localparam MCOUNTINHIBIT = 12'h320; - localparam MSCRATCH = 12'h340; - localparam MEPC = 12'h341; - localparam MCAUSE = 12'h342; - localparam MTVAL = 12'h343; - localparam MIP = 12'h344; - localparam MTINST = 12'h34A; - localparam PMPCFG0 = 12'h3A0; + localparam MSCRATCH = 12'h340; + localparam MEPC = 12'h341; + localparam MCAUSE = 12'h342; + localparam MTVAL = 12'h343; + localparam MIP = 12'h344; + localparam MTINST = 12'h34A; + localparam PMPCFG0 = 12'h3A0; // .. up to 15 more at consecutive addresses - localparam PMPADDR0 = 12'h3B0; + localparam PMPADDR0 = 12'h3B0; // ... up to 63 more at consecutive addresses - localparam TSELECT = 12'h7A0; - localparam TDATA1 = 12'h7A1; - localparam TDATA2 = 12'h7A2; - localparam TDATA3 = 12'h7A3; - localparam DCSR = 12'h7B0; - localparam DPC = 12'h7B1; - localparam DSCRATCH0 = 12'h7B2; - localparam DSCRATCH1 = 12'h7B3; + localparam TSELECT = 12'h7A0; + localparam TDATA1 = 12'h7A1; + localparam TDATA2 = 12'h7A2; + localparam TDATA3 = 12'h7A3; + localparam DCSR = 12'h7B0; + localparam DPC = 12'h7B1; + localparam DSCRATCH0 = 12'h7B2; + localparam DSCRATCH1 = 12'h7B3; // Constants localparam ZERO = {(P.XLEN){1'b0}}; - localparam MEDELEG_MASK = 16'hB3FF; - localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable + localparam MEDELEG_MASK = 16'hB3FF; + localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop genvar i; @@ -137,17 +137,17 @@ module csrm import cvw::*; #(parameter cvw_t P) ( assign MHARTID_REGW = 0; // Write machine Mode CSRs - assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS); - assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & (P.XLEN==32); - assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC); - assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG); - assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG); - assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH); - assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC)); - assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)); - assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); - assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); - assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG); + assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS); + assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & (P.XLEN==32); + assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC); + assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG); + assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG); + assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH); + assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC)); + assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)); + assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); + assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); + assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG); assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID); @@ -197,10 +197,10 @@ module csrm import cvw::*; #(parameter cvw_t P) ( assign MENVCFG_STCE = MENVCFG_REGW[63]; // Uncomment these other fields when they are defined // assign MENVCFG_PBMTE = MENVCFG_REGW[62]; - // assign MENVCFG_CBZE = MENVCFG_REGW[7]; + // assign MENVCFG_CBZE = MENVCFG_REGW[7]; // assign MENVCFG_CBCFE = MENVCFG_REGW[6]; - // assign MENVCFG_CBIE = MENVCFG_REGW[5:4]; - // assign MENVCFG_FIOM = MENVCFG_REGW[0]; + // assign MENVCFG_CBIE = MENVCFG_REGW[5:4]; + // assign MENVCFG_FIOM = MENVCFG_REGW[0]; // Read machine mode CSRs // verilator lint_off WIDTH @@ -222,28 +222,28 @@ module csrm import cvw::*; #(parameter cvw_t P) ( end end else case (CSRAdrM) - MISA_ADR: CSRMReadValM = MISA_REGW; - MVENDORID: CSRMReadValM = 0; - MARCHID: CSRMReadValM = 0; - MIMPID: CSRMReadValM = {{P.XLEN-12{1'b0}}, 12'h100}; // pipelined implementation - MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0 - MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0 - MSTATUS: CSRMReadValM = MSTATUS_REGW; - MSTATUSH: CSRMReadValM = MSTATUSH_REGW; - MTVEC: CSRMReadValM = MTVEC_REGW; - MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW}; - MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW}; - MIP: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIP_REGW}; - MIE: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIE_REGW}; - MSCRATCH: CSRMReadValM = MSCRATCH_REGW; - MEPC: CSRMReadValM = MEPC_REGW; - MCAUSE: CSRMReadValM = MCAUSE_REGW; - MTVAL: CSRMReadValM = MTVAL_REGW; - MTINST: CSRMReadValM = 0; // implemented as trivial zero - MCOUNTEREN:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW}; - MENVCFG: CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0]; - MENVCFGH: CSRMReadValM = MENVCFGH_REGW; - MCOUNTINHIBIT:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; + MISA_ADR: CSRMReadValM = MISA_REGW; + MVENDORID: CSRMReadValM = 0; + MARCHID: CSRMReadValM = 0; + MIMPID: CSRMReadValM = {{P.XLEN-12{1'b0}}, 12'h100}; // pipelined implementation + MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0 + MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0 + MSTATUS: CSRMReadValM = MSTATUS_REGW; + MSTATUSH: CSRMReadValM = MSTATUSH_REGW; + MTVEC: CSRMReadValM = MTVEC_REGW; + MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW}; + MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW}; + MIP: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIP_REGW}; + MIE: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIE_REGW}; + MSCRATCH: CSRMReadValM = MSCRATCH_REGW; + MEPC: CSRMReadValM = MEPC_REGW; + MCAUSE: CSRMReadValM = MCAUSE_REGW; + MTVAL: CSRMReadValM = MTVAL_REGW; + MTINST: CSRMReadValM = 0; // implemented as trivial zero + MCOUNTEREN: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW}; + MENVCFG: CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0]; + MENVCFGH: CSRMReadValM = MENVCFGH_REGW; + MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; default: begin CSRMReadValM = 0; @@ -252,4 +252,4 @@ module csrm import cvw::*; #(parameter cvw_t P) ( endcase end // verilator lint_on WIDTH -endmodule +endmodule \ No newline at end of file diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index e28ec79da..97c8b3f22 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -51,21 +51,21 @@ module csrs import cvw::*; #(parameter cvw_t P) ( ); // Supervisor CSRs - localparam SSTATUS = 12'h100; - localparam SIE = 12'h104; - localparam STVEC = 12'h105; + localparam SSTATUS = 12'h100; + localparam SIE = 12'h104; + localparam STVEC = 12'h105; localparam SCOUNTEREN = 12'h106; - localparam SENVCFG = 12'h10A; - localparam SSCRATCH = 12'h140; - localparam SEPC = 12'h141; - localparam SCAUSE = 12'h142; - localparam STVAL = 12'h143; - localparam SIP= 12'h144; - localparam STIMECMP = 12'h14D; - localparam STIMECMPH = 12'h15D; - localparam SATP = 12'h180; + localparam SENVCFG = 12'h10A; + localparam SSCRATCH = 12'h140; + localparam SEPC = 12'h141; + localparam SCAUSE = 12'h142; + localparam STVAL = 12'h143; + localparam SIP = 12'h144; + localparam STIMECMP = 12'h14D; + localparam STIMECMPH = 12'h15D; + localparam SATP = 12'h180; // Constants - localparam ZERO = {(P.XLEN){1'b0}}; + localparam ZERO = {(P.XLEN){1'b0}}; localparam SEDELEG_MASK = ~(ZERO | {{P.XLEN-3{1'b0}}, 3'b111} << 9); logic WriteSTVECM; @@ -81,17 +81,17 @@ module csrs import cvw::*; #(parameter cvw_t P) ( logic [63:0] STIMECMP_REGW; // write enables - assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS); - assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC); - assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH); - assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)); - assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)); - assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); - assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); + assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS); + assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC); + assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH); + assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)); + assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)); + assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); + assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); - assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG); - assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)); - assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)) & (P.XLEN == 32); + assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG); + assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)); + assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)) & (P.XLEN == 32); // CSRs flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); @@ -116,7 +116,7 @@ module csrs import cvw::*; #(parameter cvw_t P) ( // Supervisor timer interrupt logic // Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs if (P.SSTC_SUPPORTED) - assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison + assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison else assign STimerInt = 0; @@ -133,10 +133,10 @@ module csrs import cvw::*; #(parameter cvw_t P) ( // Extract bit fields // Uncomment these other fields when they are defined // assign SENVCFG_PBMTE = SENVCFG_REGW[62]; - // assign SENVCFG_CBZE = SENVCFG_REGW[7]; + // assign SENVCFG_CBZE = SENVCFG_REGW[7]; // assign SENVCFG_CBCFE = SENVCFG_REGW[6]; - // assign SENVCFG_CBIE = SENVCFG_REGW[5:4]; - // assign SENVCFG_FIOM = SENVCFG_REGW[0]; + // assign SENVCFG_CBIE = SENVCFG_REGW[5:4]; + // assign SENVCFG_FIOM = SENVCFG_REGW[0]; // CSR Reads always_comb begin:csrr @@ -175,4 +175,4 @@ module csrs import cvw::*; #(parameter cvw_t P) ( end endcase end -endmodule +endmodule \ No newline at end of file diff --git a/src/privileged/csrsr.sv b/src/privileged/csrsr.sv index a4b89297f..55db35f63 100644 --- a/src/privileged/csrsr.sv +++ b/src/privileged/csrsr.sv @@ -28,22 +28,22 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csrsr import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, StallW, - input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM, - input logic TrapM, FRegWriteM, - input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, - input logic mretM, sretM, - input logic WriteFRMM, WriteFFLAGSM, + input logic clk, reset, StallW, + input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM, + input logic TrapM, FRegWriteM, + input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, + input logic mretM, sretM, + input logic WriteFRMM, WriteFFLAGSM, input logic [P.XLEN-1:0] CSRWriteValM, - input logic SelHPTW, + input logic SelHPTW, output logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW, - output logic [1:0] STATUS_MPP, - output logic STATUS_SPP, STATUS_TSR, STATUS_TW, - output logic STATUS_MIE, STATUS_SIE, - output logic STATUS_MXR, STATUS_SUM, - output logic STATUS_MPRV, STATUS_TVM, - output logic [1:0] STATUS_FS, - output logic BigEndianM + output logic [1:0] STATUS_MPP, + output logic STATUS_SPP, STATUS_TSR, STATUS_TW, + output logic STATUS_MIE, STATUS_SIE, + output logic STATUS_MXR, STATUS_SUM, + output logic STATUS_MPRV, STATUS_TVM, + output logic [1:0] STATUS_FS, + output logic BigEndianM ); logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT; @@ -56,27 +56,27 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( // Lower privilege status registers are a subset of the full status register // *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable if (P.XLEN==64) begin: csrsr64 // RV64 - assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0, - STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, - STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, - STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, - STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; - assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0, + assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0, + STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, + STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, + STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, + STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; + assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, - STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, - STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, + STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, + STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. end else begin: csrsr32 // RV32 - assign MSTATUS_REGW = {STATUS_SD, 8'b0, - STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, - STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, - STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; + assign MSTATUS_REGW = {STATUS_SD, 8'b0, + STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, + STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, + STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; assign MSTATUSH_REGW = {26'b0, STATUS_MBE, STATUS_SBE, 4'b0}; - assign SSTATUS_REGW = {STATUS_SD, 11'b0, + assign SSTATUS_REGW = {STATUS_SD, 11'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, - STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, - STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, + STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, + STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; end @@ -90,21 +90,21 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( end // harwired STATUS bits - assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported - assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported - assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported - assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported -/* assign STATUS_UBE = 0; // little-endian - assign STATUS_SBE = 0; // little-endian - assign STATUS_MBE = 0; // little-endian */ + assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported + assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported +/* assign STATUS_UBE = 0; // little-endian + assign STATUS_SBE = 0; // little-endian + assign STATUS_MBE = 0; // little-endian */ // SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not - assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported - assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported - assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported + assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported + assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported + assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported - assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP - assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic - assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty + assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP + assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic + assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty always_comb if (CSRWriteValM[12:11] == P.U_MODE & P.U_SUPPORTED) STATUS_MPP_NEXT = P.U_MODE; @@ -122,14 +122,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( if (SelHPTW) EndiannessPrivMode = P.S_MODE; //coverage off -item c 1 -feccondrow 1 // status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode - else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP; + else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP; //coverage on else EndiannessPrivMode = PrivilegeModeW; case (EndiannessPrivMode) P.M_MODE: BigEndianM = STATUS_MBE; P.S_MODE: BigEndianM = STATUS_SBE; - default: BigEndianM = STATUS_UBE; + default: BigEndianM = STATUS_UBE; endcase end end else begin: endianmux @@ -140,22 +140,22 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( // complex register with reset, write enable, and the ability to update other bits in certain cases always_ff @(posedge clk) //, posedge reset) if (reset) begin - STATUS_TSR_INT <= #1 0; - STATUS_TW_INT <= #1 0; - STATUS_TVM_INT <= #1 0; - STATUS_MXR_INT <= #1 0; - STATUS_SUM_INT <= #1 0; + STATUS_TSR_INT <= #1 0; + STATUS_TW_INT <= #1 0; + STATUS_TVM_INT <= #1 0; + STATUS_MXR_INT <= #1 0; + STATUS_SUM_INT <= #1 0; STATUS_MPRV_INT <= #1 0; // Per Priv 3.3 - STATUS_FS_INT <= #1 P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED - STATUS_MPP <= #1 0; - STATUS_SPP <= #1 0; - STATUS_MPIE <= #1 0; - STATUS_SPIE <= #1 0; - STATUS_MIE <= #1 0; - STATUS_SIE <= #1 0; - STATUS_MBE <= #1 0; - STATUS_SBE <= #1 0; - STATUS_UBE <= #1 0; + STATUS_FS_INT <= #1 P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED + STATUS_MPP <= #1 0; + STATUS_SPP <= #1 0; + STATUS_MPIE <= #1 0; + STATUS_SPIE <= #1 0; + STATUS_MIE <= #1 0; + STATUS_SIE <= #1 0; + STATUS_MBE <= #1 0; + STATUS_SBE <= #1 0; + STATUS_UBE <= #1 0; end else if (~StallW) begin if (TrapM) begin // Update interrupt enables per Privileged Spec p. 21 @@ -164,54 +164,54 @@ module csrsr import cvw::*; #(parameter cvw_t P) ( // Modes: 11 = Machine, 01 = Supervisor, 00 = User if (NextPrivilegeModeM == P.M_MODE) begin STATUS_MPIE <= #1 STATUS_MIE; - STATUS_MIE <= #1 0; - STATUS_MPP <= #1 PrivilegeModeW; + STATUS_MIE <= #1 0; + STATUS_MPP <= #1 PrivilegeModeW; end else begin // supervisor mode STATUS_SPIE <= #1 STATUS_SIE; - STATUS_SIE <= #1 0; - STATUS_SPP <= #1 PrivilegeModeW[0]; + STATUS_SIE <= #1 0; + STATUS_SPP <= #1 PrivilegeModeW[0]; end end else if (mretM) begin // Privileged 3.1.6.1 - STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable - STATUS_MPIE <= #1 1; // - STATUS_MPP <= #1 P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level - STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec. + STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable + STATUS_MPIE <= #1 1; // + STATUS_MPP <= #1 P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level + STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec. end else if (sretM) begin - STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable - STATUS_SPIE <= #1 P.S_SUPPORTED; - STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs + STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable + STATUS_SPIE <= #1 P.S_SUPPORTED; + STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs STATUS_MPRV_INT <= #1 0; // always clear MPRV end else if (WriteMSTATUSM) begin - STATUS_TSR_INT <= #1 CSRWriteValM[22]; - STATUS_TW_INT <= #1 CSRWriteValM[21]; - STATUS_TVM_INT <= #1 CSRWriteValM[20]; - STATUS_MXR_INT <= #1 CSRWriteValM[19]; - STATUS_SUM_INT <= #1 CSRWriteValM[18]; + STATUS_TSR_INT <= #1 CSRWriteValM[22]; + STATUS_TW_INT <= #1 CSRWriteValM[21]; + STATUS_TVM_INT <= #1 CSRWriteValM[20]; + STATUS_MXR_INT <= #1 CSRWriteValM[19]; + STATUS_SUM_INT <= #1 CSRWriteValM[18]; STATUS_MPRV_INT <= #1 CSRWriteValM[17]; - STATUS_FS_INT <= #1 CSRWriteValM[14:13]; - STATUS_MPP <= #1 STATUS_MPP_NEXT; - STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; - STATUS_MPIE <= #1 CSRWriteValM[7]; - STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; - STATUS_MIE <= #1 CSRWriteValM[3]; - STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; - STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; - STATUS_MBE <= #1 nextMBE; - STATUS_SBE <= #1 nextSBE; + STATUS_FS_INT <= #1 CSRWriteValM[14:13]; + STATUS_MPP <= #1 STATUS_MPP_NEXT; + STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; + STATUS_MPIE <= #1 CSRWriteValM[7]; + STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; + STATUS_MIE <= #1 CSRWriteValM[3]; + STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; + STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; + STATUS_MBE <= #1 nextMBE; + STATUS_SBE <= #1 nextSBE; // coverage off // MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc end else if (WriteMSTATUSHM) begin - STATUS_MBE <= #1 CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED; - STATUS_SBE <= #1 CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED; + STATUS_MBE <= #1 CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED; + STATUS_SBE <= #1 CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED; // coverage on end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits - STATUS_MXR_INT <= #1 CSRWriteValM[19]; - STATUS_SUM_INT <= #1 CSRWriteValM[18]; - STATUS_FS_INT <= #1 CSRWriteValM[14:13]; - STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; - STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; - STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; - STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; + STATUS_MXR_INT <= #1 CSRWriteValM[19]; + STATUS_SUM_INT <= #1 CSRWriteValM[18]; + STATUS_FS_INT <= #1 CSRWriteValM[14:13]; + STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; + STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; + STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; + STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11; end endmodule diff --git a/src/privileged/csru.sv b/src/privileged/csru.sv index d394594ae..3a0f8c909 100644 --- a/src/privileged/csru.sv +++ b/src/privileged/csru.sv @@ -27,40 +27,40 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module csru import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic InstrValidNotFlushedM, - input logic CSRUWriteM, - input logic [11:0] CSRAdrM, + input logic clk, reset, + input logic InstrValidNotFlushedM, + input logic CSRUWriteM, + input logic [11:0] CSRAdrM, input logic [P.XLEN-1:0] CSRWriteValM, - input logic [1:0] STATUS_FS, + input logic [1:0] STATUS_FS, output logic [P.XLEN-1:0] CSRUReadValM, - input logic [4:0] SetFflagsM, - output logic [2:0] FRM_REGW, - output logic WriteFRMM, WriteFFLAGSM, - output logic IllegalCSRUAccessM + input logic [4:0] SetFflagsM, + output logic [2:0] FRM_REGW, + output logic WriteFRMM, WriteFFLAGSM, + output logic IllegalCSRUAccessM ); localparam FFLAGS = 12'h001; - localparam FRM = 12'h002; - localparam FCSR = 12'h003; + localparam FRM = 12'h002; + localparam FCSR = 12'h003; - logic [4:0] FFLAGS_REGW; - logic [2:0] NextFRMM; - logic [4:0] NextFFLAGSM; - logic SetOrWriteFFLAGSM; + logic [4:0] FFLAGS_REGW; + logic [2:0] NextFRMM; + logic [4:0] NextFFLAGSM; + logic SetOrWriteFFLAGSM; // Write enables - assign WriteFRMM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR); + assign WriteFRMM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR); assign WriteFFLAGSM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FFLAGS | CSRAdrM == FCSR); // Write Values - assign NextFRMM = (CSRAdrM == FCSR) ? CSRWriteValM[7:5] : CSRWriteValM[2:0]; - assign NextFFLAGSM = WriteFFLAGSM ? CSRWriteValM[4:0] : FFLAGS_REGW | SetFflagsM; + assign NextFRMM = (CSRAdrM == FCSR) ? CSRWriteValM[7:5] : CSRWriteValM[2:0]; + assign NextFFLAGSM = WriteFFLAGSM ? CSRWriteValM[4:0] : FFLAGS_REGW | SetFflagsM; assign SetOrWriteFFLAGSM = WriteFFLAGSM | (|SetFflagsM & InstrValidNotFlushedM); // CSRs flopenr #(3) FRMreg(clk, reset, WriteFRMM, NextFRMM, FRM_REGW); - flopenr #(5) FFLAGSreg(clk, reset, SetOrWriteFFLAGSM, NextFFLAGSM, FFLAGS_REGW); + flopenr #(5) FFLAGSreg(clk, reset, SetOrWriteFFLAGSM, NextFFLAGSM, FFLAGS_REGW); // CSR Reads always_comb begin diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 659a00f24..95ba2b0bd 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -28,91 +28,90 @@ /////////////////////////////////////////// module privileged import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic StallD, StallE, StallM, StallW, - input logic FlushD, FlushE, FlushM, FlushW, + input logic clk, reset, + input logic StallD, StallE, StallM, StallW, + input logic FlushD, FlushE, FlushM, FlushW, // CSR Reads and Writes, and values needed for traps - input logic CSRReadM, CSRWriteM, // Read or write CSRs + input logic CSRReadM, CSRWriteM, // Read or write CSRs input logic [P.XLEN-1:0] SrcAM, // GPR register to write - input logic [31:0] InstrM, // Instruction - input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL + input logic [31:0] InstrM, // Instruction + input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [P.XLEN-1:0] IEUAdrM, // address from IEU input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic // control signals - input logic InstrValidM, // Current instruction is valid (not flushed) - input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt - input logic PrivilegedM, // privileged instruction + input logic InstrValidM, // Current instruction is valid (not flushed) + input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt + input logic PrivilegedM, // privileged instruction // processor events for performance counter logging - input logic FRegWriteM, // instruction will write floating-point registers - input logic LoadStallD, // load instruction is stalling - input logic StoreStallD, // store instruction is stalling - input logic ICacheStallF, // I cache stalled - input logic DCacheStallM, // D cache stalled - input logic BPDirPredWrongM, // branch predictor guessed wrong direction - input logic BTAWrongM, // branch predictor guessed wrong target - input logic RASPredPCWrongM, // return adddress stack guessed wrong target - input logic IClassWrongM, // branch predictor guessed wrong instruction class - input logic BPWrongM, // branch predictor is wrong - input logic [3:0] InstrClassM, // actual instruction class - input logic DCacheMiss, // data cache miss - input logic DCacheAccess, // data cache accessed (hit or miss) - input logic ICacheMiss, // instruction cache miss - input logic ICacheAccess, // instruction cache access - input logic DivBusyE, // integer divide busy - input logic FDivBusyE, // floating point divide busy + input logic FRegWriteM, // instruction will write floating-point registers + input logic LoadStallD, // load instruction is stalling + input logic StoreStallD, // store instruction is stalling + input logic ICacheStallF, // I cache stalled + input logic DCacheStallM, // D cache stalled + input logic BPDirPredWrongM, // branch predictor guessed wrong direction + input logic BTAWrongM, // branch predictor guessed wrong target + input logic RASPredPCWrongM, // return adddress stack guessed wrong target + input logic IClassWrongM, // branch predictor guessed wrong instruction class + input logic BPWrongM, // branch predictor is wrong + input logic [3:0] InstrClassM, // actual instruction class + input logic DCacheMiss, // data cache miss + input logic DCacheAccess, // data cache accessed (hit or miss) + input logic ICacheMiss, // instruction cache miss + input logic ICacheAccess, // instruction cache access + input logic DivBusyE, // integer divide busy + input logic FDivBusyE, // floating point divide busy // fault sources - input logic InstrAccessFaultF, // instruction access fault - input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault - input logic HPTWInstrAccessFaultF, // hardware page table access fault while fetching instruction PTE - input logic InstrPageFaultF, // page faults - input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults - input logic InstrMisalignedFaultM, // misaligned instruction fault - input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault - input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU - input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources - input logic [63:0] MTIME_CLINT, // timer value from CLINT - input logic [4:0] SetFflagsM, // set FCSR flags from FPU - input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses + input logic InstrAccessFaultF, // instruction access fault + input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault + input logic HPTWInstrAccessFaultF, // hardware page table access fault while fetching instruction PTE + input logic InstrPageFaultF, // page faults + input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults + input logic InstrMisalignedFaultM, // misaligned instruction fault + input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault + input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU + input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources + input logic [63:0] MTIME_CLINT, // timer value from CLINT + input logic [4:0] SetFflagsM, // set FCSR flags from FPU + input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses // CSR outputs output logic [P.XLEN-1:0] CSRReadValW, // Value read from CSR - output logic [1:0] PrivilegeModeW, // current privilege mode + output logic [1:0] PrivilegeModeW, // current privilege mode output logic [P.XLEN-1:0] SATP_REGW, // supervisor address translation register - output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits - output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits - output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration entries to MMU - output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU - output logic [2:0] FRM_REGW, // FPU rounding mode + output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits + output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits + output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration entries to MMU + output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU + output logic [2:0] FRM_REGW, // FPU rounding mode // PC logic output in privileged unit output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic // control outputs - output logic RetM, TrapM, // return instruction, or trap - output logic sfencevmaM, // sfence.vma instruction - input logic InvalidateICacheM, // fence instruction - output logic BigEndianM, // Use big endian in current privilege mode + output logic RetM, TrapM, // return instruction, or trap + output logic sfencevmaM, // sfence.vma instruction + input logic InvalidateICacheM, // fence instruction + output logic BigEndianM, // Use big endian in current privilege mode // Fault outputs - output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire - output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout + output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire + output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout ); - logic [3:0] CauseM; // trap cause - logic [15:0] MEDELEG_REGW; // exception delegation CSR - logic [11:0] MIDELEG_REGW; // interrupt delegation CSR - logic sretM, mretM; // supervisor / machine return instruction - logic IllegalCSRAccessM; // Illegal access to CSR - logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage - logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage - logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages - logic IllegalInstrFaultM; // Illegal instruction fault - logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit - logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables - logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits - logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return - logic DelegateM; // trap should be delegated - logic InterruptM; // interrupt occuring - logic ExceptionM; // Memory stage instruction caused a fault - logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE + logic [3:0] CauseM; // trap cause + logic [15:0] MEDELEG_REGW; // exception delegation CSR + logic [11:0] MIDELEG_REGW; // interrupt delegation CSR + logic sretM, mretM; // supervisor / machine return instruction + logic IllegalCSRAccessM; // Illegal access to CSR + logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage + logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage + logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages + logic IllegalInstrFaultM; // Illegal instruction fault + logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit + logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables + logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits + logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return + logic DelegateM; // trap should be delegated + logic InterruptM; // interrupt occuring + logic ExceptionM; // Memory stage instruction caused a fault + logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE - // track the current privilege level privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); @@ -156,8 +155,3 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .InstrValidM, .CommittedM, .CommittedF, .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule - - - - - diff --git a/src/privileged/privmode.sv b/src/privileged/privmode.sv index aa111732d..5ac4cae78 100644 --- a/src/privileged/privmode.sv +++ b/src/privileged/privmode.sv @@ -43,10 +43,10 @@ module privmode import cvw::*; #(parameter cvw_t P) ( always_comb begin if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8) if (P.S_SUPPORTED & DelegateM) NextPrivilegeModeM = P.S_MODE; - else NextPrivilegeModeM = P.M_MODE; - end else if (mretM) NextPrivilegeModeM = STATUS_MPP; - else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP}; - else NextPrivilegeModeM = PrivilegeModeW; + else NextPrivilegeModeM = P.M_MODE; + end else if (mretM) NextPrivilegeModeM = STATUS_MPP; + else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP}; + else NextPrivilegeModeM = PrivilegeModeW; end flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, P.M_MODE, PrivilegeModeW); diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index 0d8002d18..2720570de 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -63,13 +63,13 @@ module trap import cvw::*; #(parameter cvw_t P) ( assign MIntGlobalEnM = (PrivilegeModeW != P.M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == P.U_MODE) | ((PrivilegeModeW == P.S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 - assign PendingIntsM = MIP_REGW & MIE_REGW; - assign IntPendingM = |PendingIntsM; - assign Committed = CommittedM | CommittedF; - assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); - assign ValidIntsM = {12{~Committed}} & EnabledIntsM; - assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. - assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & + assign PendingIntsM = MIP_REGW & MIE_REGW; + assign IntPendingM = |PendingIntsM; + assign Committed = CommittedM | CommittedF; + assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); + assign ValidIntsM = {12{~Committed}} & EnabledIntsM; + assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. + assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); /////////////////////////////////////////// @@ -88,7 +88,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( LoadAccessFaultM | StoreAmoAccessFaultM; // coverage on assign TrapM = ExceptionM | InterruptM; - assign RetM = mretM | sretM; + assign RetM = mretM | sretM; /////////////////////////////////////////// // Cause priority defined in table 3.7 of 20190608 privileged spec diff --git a/src/uncore/ahbapbbridge.sv b/src/uncore/ahbapbbridge.sv index 5aed30300..381297f00 100644 --- a/src/uncore/ahbapbbridge.sv +++ b/src/uncore/ahbapbbridge.sv @@ -27,27 +27,27 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P, parameter PERIPHS = 2) ( - input logic HCLK, HRESETn, - input logic [PERIPHS-1:0] HSEL, + input logic HCLK, HRESETn, + input logic [PERIPHS-1:0] HSEL, input logic [P.PA_BITS-1:0] HADDR, input logic [P.XLEN-1:0] HWDATA, input logic [P.XLEN/8-1:0] HWSTRB, - input logic HWRITE, - input logic [1:0] HTRANS, - input logic HREADY, + input logic HWRITE, + input logic [1:0] HTRANS, + input logic HREADY, // input logic [3:0] HPROT, // not used output logic [P.XLEN-1:0] HRDATA, - output logic HRESP, HREADYOUT, - output logic PCLK, PRESETn, - output logic [PERIPHS-1:0] PSEL, - output logic PWRITE, - output logic PENABLE, - output logic [31:0] PADDR, + output logic HRESP, HREADYOUT, + output logic PCLK, PRESETn, + output logic [PERIPHS-1:0] PSEL, + output logic PWRITE, + output logic PENABLE, + output logic [31:0] PADDR, output logic [P.XLEN-1:0] PWDATA, // output logic [2:0] PPROT, // not used output logic [P.XLEN/8-1:0] PSTRB, // output logic PWAKEUP // not used - input logic [PERIPHS-1:0] PREADY, + input logic [PERIPHS-1:0] PREADY, input var [PERIPHS-1:0][P.XLEN-1:0] PRDATA ); @@ -56,15 +56,15 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P, logic PREADYOUT; // convert AHB to APB signals - assign PCLK = HCLK; + assign PCLK = HCLK; assign PRESETn = HRESETn; // identify start of a transaction - assign initTrans = HTRANS[1] & HREADY; // start a transaction when the bus is ready and an active transaction is requested + assign initTrans = HTRANS[1] & HREADY; // start a transaction when the bus is ready and an active transaction is requested assign initTransSel = initTrans & |HSEL; // capture data and address if any of the peripherals are selected // delay AHB Address phase signals to align with AHB Data phase because APB expects them at the same time - flopen #(32) addrreg(HCLK, HREADY, HADDR[31:0], PADDR); + flopen #(32) addrreg(HCLK, HREADY, HADDR[31:0], PADDR); flopenr #(1) writereg(HCLK, ~HRESETn, HREADY, HWRITE, PWRITE); flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, HREADY, HSEL & {PERIPHS{initTrans}}, PSEL); // PPROT[2:0] = {Data/InstrB, Secure, Privileged}; @@ -73,7 +73,7 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P, // AHB Data phase signal doesn't need delay. Note that they are guaranteed to remain stable until READY is asserted assign PWDATA = HWDATA; - assign PSTRB = HWSTRB; + assign PSTRB = HWSTRB; // enable logic: goes high a cycle after initTrans, then back low on cycle after desired PREADY is asserted // cycle1: AHB puts HADDR, HWRITE, HSEL on bus. initTrans is 1, and these are captured @@ -103,4 +103,3 @@ assign HREADYOUT = PREADYOUT & ~initTransSelD; // don't raise HREADYOUT before a // resp logic assign HRESP = 0; // bridge never indicates errors endmodule - diff --git a/src/uncore/clint_apb.sv b/src/uncore/clint_apb.sv index fdbe8f640..6e35ffdaf 100644 --- a/src/uncore/clint_apb.sv +++ b/src/uncore/clint_apb.sv @@ -31,11 +31,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( input logic PCLK, PRESETn, input logic PSEL, input logic [15:0] PADDR, - input logic [P.XLEN-1:0] PWDATA, - input logic [P.XLEN/8-1:0] PSTRB, + input logic [P.XLEN-1:0] PWDATA, + input logic [P.XLEN/8-1:0] PSTRB, input logic PWRITE, input logic PENABLE, - output logic [P.XLEN-1:0] PRDATA, + output logic [P.XLEN-1:0] PRDATA, output logic PREADY, output logic [63:0] MTIME, output logic MTimerInt, MSwInt @@ -48,11 +48,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( integer i, j; assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase - assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond + assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond // word aligned reads if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000}; - else assign #2 entry = {PADDR[15:2], 2'b00}; + else assign #2 entry = {PADDR[15:2], 2'b00}; // DH 2/20/21: Eventually allow MTIME to run off a separate clock // This will require synchronizing MTIME to the system clock @@ -150,36 +150,36 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( endmodule module timeregsync import cvw::*; #(parameter cvw_t P) ( - input logic clk, resetn, - input logic we0, we1, + input logic clk, resetn, + input logic we0, we1, input logic [P.XLEN-1:0] wd, - output logic [63:0] q); + output logic [63:0] q); if (P.XLEN==64) always_ff @(posedge clk or negedge resetn) - if (~resetn) q <= 0; + if (~resetn) q <= 0; else if (we0) q <= wd; else q <= q + 1; else always_ff @(posedge clk or negedge resetn) - if (~resetn) q <= 0; + if (~resetn) q <= 0; else if (we0) q[31:0] <= wd; else if (we1) q[63:32] <= wd; else q <= q + 1; endmodule module timereg import cvw::*; #(parameter cvw_t P) ( - input logic PCLK, PRESETn, TIMECLK, - input logic we0, we1, + input logic PCLK, PRESETn, TIMECLK, + input logic we0, we1, input logic [P.XLEN-1:0] PWDATA, - output logic [63:0] MTIME, - output logic done); + output logic [63:0] MTIME, + output logic done); // if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME if (1) begin:timereg // use PCLK for MTIME timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME)); - assign done = 1; // immediately completes - end else begin // use asynchronous TIMECLK + assign done = 1; // immediately completes + end else begin // use asynchronous TIMECLK // TIME counter runs on TIMECLK but bus interface runs on PCLK // Need to synchronize reads and writes // This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits diff --git a/src/uncore/gpio_apb.sv b/src/uncore/gpio_apb.sv index 1b6ef8e48..baab83088 100644 --- a/src/uncore/gpio_apb.sv +++ b/src/uncore/gpio_apb.sv @@ -29,78 +29,78 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module gpio_apb import cvw::*; #(parameter cvw_t P) ( - input logic PCLK, PRESETn, - input logic PSEL, - input logic [7:0] PADDR, - input logic [P.XLEN-1:0] PWDATA, + input logic PCLK, PRESETn, + input logic PSEL, + input logic [7:0] PADDR, + input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN/8-1:0] PSTRB, - input logic PWRITE, - input logic PENABLE, - output logic [P.XLEN-1:0] PRDATA, - output logic PREADY, - input logic [31:0] iof0, iof1, - input logic [31:0] GPIOIN, - output logic [31:0] GPIOOUT, GPIOEN, - output logic GPIOIntr + input logic PWRITE, + input logic PENABLE, + output logic [P.XLEN-1:0] PRDATA, + output logic PREADY, + input logic [31:0] iof0, iof1, + input logic [31:0] GPIOIN, + output logic [31:0] GPIOOUT, GPIOEN, + output logic GPIOIntr ); - logic [31:0] input0d, input1d, input2d, input3d; - logic [31:0] input_val, input_en, output_en, output_val; - logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip; - logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out; - logic [7:0] entry; - logic [31:0] Din, Dout; - logic memwrite; + logic [31:0] input0d, input1d, input2d, input3d; + logic [31:0] input_val, input_en, output_en, output_val; + logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip; + logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out; + logic [7:0] entry; + logic [31:0] Din, Dout; + logic memwrite; // APB I/O - assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses + assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase - assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond + assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond // account for subword read/write circuitry // -- Note GPIO registers are 32 bits no matter what; access them with LW SW. // (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported") if (P.XLEN == 64) begin - assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0]; + assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0]; assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout}; end else begin // 32-bit - assign Din = PWDATA[31:0]; + assign Din = PWDATA[31:0]; assign PRDATA = Dout; end // register access always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin // asynch reset - input_en <= 0; + input_en <= 0; output_en <= 0; // *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required] output_val <= #1 0; - rise_ie <= #1 0; - rise_ip <= #1 0; - fall_ie <= #1 0; - fall_ip <= #1 0; - high_ie <= #1 0; - high_ip <= #1 0; - low_ie <= #1 0; - low_ip <= #1 0; - iof_en <= #1 0; - iof_sel <= #1 0; - out_xor <= #1 0; + rise_ie <= #1 0; + rise_ip <= #1 0; + fall_ie <= #1 0; + fall_ip <= #1 0; + high_ie <= #1 0; + high_ip <= #1 0; + low_ie <= #1 0; + low_ip <= #1 0; + iof_en <= #1 0; + iof_sel <= #1 0; + out_xor <= #1 0; end else begin // writes // According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit. /* verilator lint_off CASEINCOMPLETE */ if (memwrite) case(entry) - 8'h04: input_en <= #1 Din; - 8'h08: output_en <= #1 Din; + 8'h04: input_en <= #1 Din; + 8'h08: output_en <= #1 Din; 8'h0C: output_val <= #1 Din; - 8'h18: rise_ie <= #1 Din; - 8'h20: fall_ie <= #1 Din; - 8'h28: high_ie <= #1 Din; - 8'h30: low_ie <= #1 Din; - 8'h38: iof_en <= #1 Din; - 8'h3C: iof_sel <= #1 Din; - 8'h40: out_xor <= #1 Din; + 8'h18: rise_ie <= #1 Din; + 8'h20: fall_ie <= #1 Din; + 8'h28: high_ie <= #1 Din; + 8'h30: low_ie <= #1 Din; + 8'h38: iof_en <= #1 Din; + 8'h3C: iof_sel <= #1 Din; + 8'h40: out_xor <= #1 Din; endcase /* verilator lint_on CASEINCOMPLETE */ @@ -115,21 +115,21 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) ( else low_ip <= low_ip | ~input3d; case(entry) // flop to sample inputs - 8'h00: Dout <= #1 input_val; - 8'h04: Dout <= #1 input_en; - 8'h08: Dout <= #1 output_en; - 8'h0C: Dout <= #1 output_val; - 8'h18: Dout <= #1 rise_ie; - 8'h1C: Dout <= #1 rise_ip; - 8'h20: Dout <= #1 fall_ie; - 8'h24: Dout <= #1 fall_ip; - 8'h28: Dout <= #1 high_ie; - 8'h2C: Dout <= #1 high_ip; - 8'h30: Dout <= #1 low_ie; - 8'h34: Dout <= #1 low_ip; - 8'h38: Dout <= #1 iof_en; - 8'h3C: Dout <= #1 iof_sel; - 8'h40: Dout <= #1 out_xor; + 8'h00: Dout <= #1 input_val; + 8'h04: Dout <= #1 input_en; + 8'h08: Dout <= #1 output_en; + 8'h0C: Dout <= #1 output_val; + 8'h18: Dout <= #1 rise_ie; + 8'h1C: Dout <= #1 rise_ip; + 8'h20: Dout <= #1 fall_ie; + 8'h24: Dout <= #1 fall_ip; + 8'h28: Dout <= #1 high_ie; + 8'h2C: Dout <= #1 high_ip; + 8'h30: Dout <= #1 low_ie; + 8'h34: Dout <= #1 low_ip; + 8'h38: Dout <= #1 iof_en; + 8'h3C: Dout <= #1 iof_sel; + 8'h40: Dout <= #1 out_xor; default: Dout <= #1 0; endcase end @@ -137,18 +137,17 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) ( // chip i/o // connect OUT to IN for loopback testing if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en; - else assign input0d = GPIOIN & input_en; + else assign input0d = GPIOIN & input_en; // synchroninzer for inputs flop #(32) sync1(PCLK,input0d,input1d); flop #(32) sync2(PCLK,input1d,input2d); flop #(32) sync3(PCLK,input2d,input3d); assign input_val = input3d; - assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0 - assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val - assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity - assign GPIOEN = output_en; + assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0 + assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val + assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity + assign GPIOEN = output_en; - assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)}; + assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)}; endmodule - diff --git a/src/uncore/plic_apb.sv b/src/uncore/plic_apb.sv index aaa1c47f4..11c06153d 100644 --- a/src/uncore/plic_apb.sv +++ b/src/uncore/plic_apb.sv @@ -41,22 +41,22 @@ // hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts module plic_apb import cvw::*; #(parameter cvw_t P) ( - input logic PCLK, PRESETn, - input logic PSEL, - input logic [27:0] PADDR, + input logic PCLK, PRESETn, + input logic PSEL, + input logic [27:0] PADDR, input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN/8-1:0] PSTRB, - input logic PWRITE, - input logic PENABLE, + input logic PWRITE, + input logic PENABLE, output logic [P.XLEN-1:0] PRDATA, - output logic PREADY, - input logic UARTIntr,GPIOIntr, - output logic MExtInt, SExtInt + output logic PREADY, + input logic UARTIntr,GPIOIntr, + output logic MExtInt, SExtInt ); - logic memwrite, memread; - logic [23:0] entry; - logic [31:0] Din, Dout; + logic memwrite, memread; + logic [23:0] entry; + logic [31:0] Din, Dout; // context-independent signals logic [`N:1] requests; @@ -78,9 +78,9 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( // ======= assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase - assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this - assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond - assign entry = {PADDR[23:2],2'b0}; + assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this + assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond + assign entry = {PADDR[23:2],2'b0}; // account for subword read/write circuitry // -- Note PLIC registers are 32 bits no matter what; access them with LW SW. @@ -97,6 +97,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( // ================== // Register Interface // ================== + always @(posedge PCLK) begin // resetting if (~PRESETn) begin @@ -110,19 +111,19 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( casez(entry) 24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0]; `ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources - 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; - 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; + 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; + 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; `endif `ifndef PLIC_NUM_SRC_LT_32 - 24'h002000: intEn[0][31:1] <= #1 Din[31:1]; - 24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; - 24'h002080: intEn[1][31:1] <= #1 Din[31:1]; - 24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; + 24'h002000: intEn[0][31:1] <= #1 Din[31:1]; + 24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; + 24'h002080: intEn[1][31:1] <= #1 Din[31:1]; + 24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; `endif - 24'h200000: intThreshold[0] <= #1 Din[2:0]; - 24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion - 24'h201000: intThreshold[1] <= #1 Din[2:0]; - 24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h200000: intThreshold[0] <= #1 Din[2:0]; + 24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h201000: intThreshold[1] <= #1 Din[2:0]; + 24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion endcase // Read synchronously because a read can have side effect of changing intInProgress if (memread) begin @@ -245,4 +246,3 @@ module plic_apb import cvw::*; #(parameter cvw_t P) ( assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]); assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]); endmodule - diff --git a/src/uncore/ram_ahb.sv b/src/uncore/ram_ahb.sv index b7ec13457..78de50aa1 100644 --- a/src/uncore/ram_ahb.sv +++ b/src/uncore/ram_ahb.sv @@ -30,33 +30,33 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, parameter BASE=0, RANGE = 65535) ( - input logic HCLK, HRESETn, - input logic HSELRam, + input logic HCLK, HRESETn, + input logic HSELRam, input logic [P.PA_BITS-1:0] HADDR, - input logic HWRITE, - input logic HREADY, - input logic [1:0] HTRANS, + input logic HWRITE, + input logic HREADY, + input logic [1:0] HTRANS, input logic [P.XLEN-1:0] HWDATA, input logic [P.XLEN/8-1:0] HWSTRB, output logic [P.XLEN-1:0] HREADRam, - output logic HRESPRam, HREADYRam + output logic HRESPRam, HREADYRam ); - localparam ADDR_WIDTH = $clog2(RANGE/8); - localparam OFFSET = $clog2(P.XLEN/8); + localparam ADDR_WIDTH = $clog2(RANGE/8); + localparam OFFSET = $clog2(P.XLEN/8); logic [P.XLEN/8-1:0] ByteMask; logic [P.PA_BITS-1:0] HADDRD, RamAddr; - logic initTrans; - logic memwrite, memwriteD, memread; - logic nextHREADYRam; - logic DelayReady; + logic initTrans; + logic memwrite, memwriteD, memread; + logic nextHREADYRam; + logic DelayReady; // a new AHB transactions starts when HTRANS requests a transaction, // the peripheral is selected, and the previous transaction is completing assign initTrans = HREADY & HSELRam & HTRANS[1] ; - assign memwrite = initTrans & HWRITE; - assign memread = initTrans & ~HWRITE; + assign memwrite = initTrans & HWRITE; + assign memread = initTrans & ~HWRITE; flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD); flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD); @@ -71,10 +71,9 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, mux2 #(P.PA_BITS) adrmux(HADDR, HADDRD, memwriteD | ~HREADY, RamAddr); // single-ported RAM - ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1), + ram1p1rwbe #(.P(P), .DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1), .addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam)); - // use this to add arbitrary latency to ram. Helps test AHB controller correctness if(`RAM_LATENCY > 0) begin logic [7:0] NextCycle, Cycle; @@ -89,15 +88,15 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, always_ff @(posedge HCLK) if (~HRESETn) CurrState <= #1 READY; - else CurrState <= #1 NextState; + else CurrState <= #1 NextState; always_comb begin case(CurrState) READY: if(initTrans & ~CycleFlag) NextState = DELAY; - else NextState = READY; - DELAY: if(CycleFlag) NextState = READY; - else NextState = DELAY; - default: NextState = READY; + else NextState = READY; + DELAY: if(CycleFlag) NextState = READY; + else NextState = DELAY; + default: NextState = READY; endcase end @@ -110,4 +109,3 @@ module ram_ahb import cvw::*; #(parameter cvw_t P, end endmodule - diff --git a/src/uncore/rom_ahb.sv b/src/uncore/rom_ahb.sv index abb75277f..0c09191be 100644 --- a/src/uncore/rom_ahb.sv +++ b/src/uncore/rom_ahb.sv @@ -28,24 +28,23 @@ module rom_ahb import cvw::*; #(parameter cvw_t P, parameter BASE=0, RANGE = 65535) ( - input logic HCLK, HRESETn, - input logic HSELRom, - input logic [P.PA_BITS-1:0] HADDR, - input logic HREADY, - input logic [1:0] HTRANS, - output logic [P.XLEN-1:0] HREADRom, - output logic HRESPRom, HREADYRom + input logic HCLK, HRESETn, + input logic HSELRom, + input logic [P.PA_BITS-1:0] HADDR, + input logic HREADY, + input logic [1:0] HTRANS, + output logic [P.XLEN-1:0] HREADRom, + output logic HRESPRom, HREADYRom ); localparam ADDR_WIDTH = $clog2(RANGE/8); - localparam OFFSET = $clog2(P.XLEN/8); + localparam OFFSET = $clog2(P.XLEN/8); // Never stalls assign HREADYRom = 1'b1; - assign HRESPRom = 0; // OK + assign HRESPRom = 0; // OK // single-ported ROM rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA) memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom)); endmodule - diff --git a/src/uncore/uartPC16550D.sv b/src/uncore/uartPC16550D.sv index fc01f4024..ad1e0f259 100644 --- a/src/uncore/uartPC16550D.sv +++ b/src/uncore/uartPC16550D.sv @@ -7,11 +7,11 @@ // Purpose: Universial Asynchronous Receiver/ Transmitter with FIFOs // Emulates interface of Texas Instruments PC16550D // https://media.digikey.com/pdf/Data%20Sheets/Texas%20Instruments%20PDFs/PC16550D.pdf -// Compatible with UART in Imperas Virtio model *** +// Compatible with UART in Imperas Virtio model // // Compatible with most of PC16550D with the following known exceptions: // Generates 2 rather than 1.5 stop bits when 5-bit word length is slected and LCR[2] = 1 -// Timeout not yet implemented*** +// Timeout not yet implemented // // Documentation: RISC-V System on Chip Design Chapter 15 // @@ -35,7 +35,7 @@ /* verilator lint_off UNOPTFLAT */ -module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( +module uartPC16550D #(parameter UART_PRESCALE) ( // Processor Interface input logic PCLK, PRESETn, // UART clock and active low reset input logic [2:0] A, // address input (8 registers) @@ -45,7 +45,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines // Clocks output logic BAUDOUTb, // active low baud clock - input logic RCLK, // usually BAUDOUTb tied to RCLK externally + input logic RCLK, // usually BAUDOUTb tied to RCLK externally // E1A Driver input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs @@ -71,9 +71,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( logic DLAB; // Divisor Latch Access Bit (LCR bit 7) // Baud and rx/tx timing - logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period - logic [16+UART_PRESCALE-1:0] baudcount; - logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 + logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period + logic [16+UART_PRESCALE-1:0] baudcount; + logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 logic [3:0] rxbitsreceived, txbitssent; statetype rxstate, txstate; @@ -122,6 +122,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( /////////////////////////////////////////// // Input synchronization: 2-stage synchronizer /////////////////////////////////////////// + always_ff @(posedge PCLK) begin {SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb}; {SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} : @@ -132,11 +133,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( /////////////////////////////////////////// // Register interface (Table 1, note some are read only and some write only) /////////////////////////////////////////// + always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin // Table 3 Reset Configuration IER <= #1 4'b0; FCR <= #1 8'b0; - if (QEMU) LCR <= #1 8'b0; else LCR <= #1 8'b11; // fpga only **** BUG + LCR <= #1 8'b11; // **** fpga used to require reset to 3, double check this is no longer needed. MCR <= #1 5'b0; LSR <= #1 8'b01100000; MSR <= #1 4'b0; @@ -162,13 +164,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( if (~MEMWb & (A == 3'b101)) LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3 else begin - LSR[0] <= #1 rxdataready; // Data ready - LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error - LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error - LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error - LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator - LSR[5] <= #1 THRE; // THRE - LSR[6] <= #1 ~txsrfull & THRE; // TEMT + LSR[0] <= #1 rxdataready; // Data ready + LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error + LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error + LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error + LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator + LSR[5] <= #1 THRE; // THRE + LSR[6] <= #1 ~txsrfull & THRE; // TEMT if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error end @@ -204,10 +206,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( // consider switching to same fixed-frequency reference clock used for TIME register // prescale by factor of 2^UART_PRESCALE to allow for high-frequency reference clock // Unlike PC16550D, this unit is hardwired with same rx and tx baud clock - // *** add table of scale factors to get 16x uart clk + // For example, with PCLK = 320 MHz, UART_PRESCALE = 5, DLM = 0, DLL = 65, + // 320 MHz system clock is divided by 65 x 2^5. The UART clock 16x oversamples + // the data, so the baud rate is 320x10^6 / (65 x 2^5 x 16) = 9615 Hz, which is + // close enough to 9600 baud to stay synchronized over the duration of one character. /////////////////////////////////////////// - // Ross Thompson: Found a bug. If the baud rate dividers DLM, and DLL are reloaded - // the baudcount is not reset to {DLM, DLL, UART_PRESCALE} always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin baudcount <= #1 1; @@ -233,17 +236,18 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( /////////////////////////////////////////// // receive timing and control /////////////////////////////////////////// + always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin - rxoversampledcnt <= #1 0; - rxstate <= #1 UART_IDLE; - rxbitsreceived <= #1 0; - rxtimeoutcnt <= #1 0; + rxoversampledcnt <= #1 0; + rxstate <= #1 UART_IDLE; + rxbitsreceived <= #1 0; + rxtimeoutcnt <= #1 0; end else begin if (rxstate == UART_IDLE & ~SINsync) begin // got start bit - rxstate <= #1 UART_ACTIVE; + rxstate <= #1 UART_ACTIVE; rxoversampledcnt <= #1 0; - rxbitsreceived <= #1 0; + rxbitsreceived <= #1 0; if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter @@ -255,18 +259,17 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( end // timeout counting if (~MEMRb & A == 3'b000 & ~DLAB) rxtimeoutcnt <= #1 0; // reset timeout on read - else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= #1 rxtimeoutcnt+1; // *** not right + else if (fifoenabled & ~rxfifoempty & rxbaudpulse & ~rxfifotimeout) rxtimeoutcnt <= #1 rxtimeoutcnt+1; // may not be right end - // ***explain why - if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE - else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE + assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit /////////////////////////////////////////// // receive shift register, buffer register, FIFO /////////////////////////////////////////// + always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit @@ -282,11 +285,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit // ERROR CONDITIONS - assign rxparity = ^rxdata; - assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted) + assign rxparity = ^rxdata; + assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted) assign rxoverrunerr = fifoenabled ? (rxfifoentries == 15) : rxdataready; // overrun if FIFO or receive buffer register full assign rxframingerr = ~rxstopbit; // framing error if no stop bit - assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time + assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time // receive FIFO and register always_ff @(posedge PCLK) @@ -298,7 +301,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( end else if (rxstate == UART_DONE) begin RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register if (rxoverrunerr) $warning("UART RX Overrun Err\n"); - if (rxparityerr) $warning("UART RX Parity Err\n"); + if (rxparityerr) $warning("UART RX Parity Err\n"); if (rxframingerr) $warning("UART RX Framing Err\n"); if (fifoenabled) begin rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; @@ -326,7 +329,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( (rxfifohead + 16 - rxfifotail); // verilator lint_on WIDTH assign rxfifotriggered = rxfifoentries >= rxfifotriggerlevel; - assign rxfifotimeout = rxtimeoutcnt == {rxbitsexpected, 6'b0}; // time out after 4 character periods; *** probably not right yet + assign rxfifotimeout = rxtimeoutcnt == {rxbitsexpected, 6'b0}; // time out after 4 character periods; probably not right yet //assign rxfifotimeout = 0; // disabled pending fix // detect any errors in rx fifo @@ -339,14 +342,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( else assign rxfullbitunwrapped[i] = ({1'b0,rxfifohead}==i | rxfullbitunwrapped[i-1]) & (rxfifotailunwrapped != i); end for (i=0; i<16; i++) begin:rx - assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set? + assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set? assign rxfullbit[i] = rxfullbitunwrapped[i] | rxfullbitunwrapped[i+16]; /* if (i > 0) assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i); else assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/ end - assign rxfifohaserr = |(RXerrbit & rxfullbit); + assign rxfifohaserr = |(RXerrbit & rxfullbit); // receive buffer register and ready bit always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1) @@ -361,22 +364,23 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( if (fifodmamodesel) RXRDYb = ~rxfifodmaready; else RXRDYb = rxfifoempty; end else begin - RBR = RXBR; + RBR = RXBR; RXRDYb = ~rxdataready; end /////////////////////////////////////////// // transmit timing and control /////////////////////////////////////////// + always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin txoversampledcnt <= #1 0; - txstate <= #1 UART_IDLE; - txbitssent <= #1 0; + txstate <= #1 UART_IDLE; + txbitssent <= #1 0; end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting - txstate <= #1 UART_ACTIVE; + txstate <= #1 UART_ACTIVE; txoversampledcnt <= #1 1; - txbitssent <= #1 0; + txbitssent <= #1 0; end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin txoversampledcnt <= #1 txoversampledcnt + 1; if (txnextbit) begin // transmit at end of phase @@ -388,17 +392,16 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( end assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1 - // *** explain; is this necessary? - if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE - else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE + assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE /////////////////////////////////////////// // transmit holding register, shift register, FIFO /////////////////////////////////////////// + always_comb begin // compute value for parity and tx holding register nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register case (LCR[1:0]) // compute parity from appropriate number of bits - 2'b00: txparity = ^nexttxdata[4:0] ^ ~evenparitysel; // *** check polarity + 2'b00: txparity = ^nexttxdata[4:0] ^ ~evenparitysel; 2'b01: txparity = ^nexttxdata[5:0] ^ ~evenparitysel; 2'b10: txparity = ^nexttxdata[6:0] ^ ~evenparitysel; 2'b11: txparity = ^nexttxdata[7:0] ^ ~evenparitysel; @@ -426,9 +429,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo if (fifoenabled) begin txfifo[txfifohead] <= #1 Din; - txfifohead <= #1 txfifohead + 1; + txfifohead <= #1 txfifohead + 1; end else begin - TXHR <= #1 Din; + TXHR <= #1 Din; txhrfull <= #1 1; end $write("%c",Din); // for testbench @@ -436,12 +439,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( if (txstate == UART_IDLE) begin // move data into tx shift register if available if (fifoenabled) begin if (~txfifoempty & ~txsrfull) begin - txsr <= #1 txdata; + txsr <= #1 txdata; txfifotail <= #1 txfifotail+1; - txsrfull <= #1 1; + txsrfull <= #1 1; end end else if (txhrfull) begin - txsr <= #1 txdata; + txsr <= #1 txdata; txhrfull <= #1 0; txsrfull <= #1 1; end @@ -470,12 +473,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( HeadPointerLastMove <= 1'b0; end - assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove; + assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove; // verilator lint_off WIDTH assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) : (txfifohead + 16 - txfifotail); // verilator lint_on WIDTH - //assign txfifofull = (txfifoentries == 4'b1111); assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove; // transmit buffer ready bit @@ -490,11 +492,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( // Transmitter pin assign SOUTbit = txsr[11]; // transmit most significant bit - assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break + assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break /////////////////////////////////////////// // interrupts /////////////////////////////////////////// + assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready; @@ -533,15 +536,15 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) ( // modem control logic /////////////////////////////////////////// - assign loop = MCR[4]; + assign loop = MCR[4]; assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode assign RTSb = ~MCR[1] | loop; assign OUT1b = ~MCR[2] | loop; assign OUT2b = ~MCR[3] | loop; assign DLAB = LCR[7]; - assign evenparitysel = LCR[4]; - assign fifoenabled = FCR[0]; + assign evenparitysel = LCR[4]; + assign fifoenabled = FCR[0]; assign fifodmamodesel = FCR[3]; always_comb case (FCR[7:6]) diff --git a/src/uncore/uart_apb.sv b/src/uncore/uart_apb.sv index b6a0321a9..130d7503e 100644 --- a/src/uncore/uart_apb.sv +++ b/src/uncore/uart_apb.sv @@ -29,18 +29,18 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module uart_apb import cvw::*; #(parameter cvw_t P) ( - input logic PCLK, PRESETn, - input logic PSEL, - input logic [2:0] PADDR, - input logic [P.XLEN-1:0] PWDATA, + input logic PCLK, PRESETn, + input logic PSEL, + input logic [2:0] PADDR, + input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN/8-1:0] PSTRB, - input logic PWRITE, - input logic PENABLE, - output logic [P.XLEN-1:0] PRDATA, - output logic PREADY, - input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface - output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface - output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU + input logic PWRITE, + input logic PENABLE, + output logic [P.XLEN-1:0] PRDATA, + output logic PREADY, + input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface + output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface + output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU // UART interface signals logic [2:0] entry; @@ -49,10 +49,10 @@ module uart_apb import cvw::*; #(parameter cvw_t P) ( assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memread = ~PWRITE & PENABLE & PSEL; - assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond - assign entry = PADDR[2:0]; - assign MEMRb = ~memread; - assign MEMWb = ~memwrite; + assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond + assign entry = PADDR[2:0]; + assign MEMRb = ~memread; + assign MEMWb = ~memwrite; if (P.XLEN == 64) begin:uart always_comb begin @@ -81,8 +81,7 @@ module uart_apb import cvw::*; #(parameter cvw_t P) ( end logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK - // *** make sure reads don't occur on UART unless fully selected because they could change state. This applies to all peripherals - uartPC16550D #(P.UART_PRESCALE, P.QEMU) u( + uartPC16550D #(P.UART_PRESCALE) u( // Processor Interface .PCLK, .PRESETn, .A(entry), .Din, @@ -97,4 +96,3 @@ module uart_apb import cvw::*; #(parameter cvw_t P) ( ); endmodule - diff --git a/src/uncore/uncore.sv b/src/uncore/uncore.sv index 7a44977e4..d1cd99002 100644 --- a/src/uncore/uncore.sv +++ b/src/uncore/uncore.sv @@ -29,58 +29,58 @@ module uncore import cvw::*; #(parameter cvw_t P)( // AHB Bus Interface - input logic HCLK, HRESETn, - input logic TIMECLK, + input logic HCLK, HRESETn, + input logic TIMECLK, input logic [P.PA_BITS-1:0] HADDR, input logic [P.AHBW-1:0] HWDATA, input logic [P.XLEN/8-1:0] HWSTRB, - input logic HWRITE, - input logic [2:0] HSIZE, - input logic [2:0] HBURST, - input logic [3:0] HPROT, - input logic [1:0] HTRANS, - input logic HMASTLOCK, + input logic HWRITE, + input logic [2:0] HSIZE, + input logic [2:0] HBURST, + input logic [3:0] HPROT, + input logic [1:0] HTRANS, + input logic HMASTLOCK, input logic [P.AHBW-1:0] HRDATAEXT, - input logic HREADYEXT, HRESPEXT, + input logic HREADYEXT, HRESPEXT, output logic [P.AHBW-1:0] HRDATA, - output logic HREADY, HRESP, - output logic HSELEXT, + output logic HREADY, HRESP, + output logic HSELEXT, // peripheral pins - output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT - output logic MExtInt, SExtInt, // External interrupts from PLIC - output logic [63:0] MTIME_CLINT, // MTIME, from CLINT - input logic [31:0] GPIOIN, // GPIO pin input value - output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable - input logic UARTSin, // UART serial input - output logic UARTSout, // UART serial output - output logic SDCCmdOut, // SD Card command output - output logic SDCCmdOE, // SD Card command output enable - input logic SDCCmdIn, // SD Card command input - input logic [3:0] SDCDatIn, // SD Card data input - output logic SDCCLK // SD Card clock + output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT + output logic MExtInt, SExtInt, // External interrupts from PLIC + output logic [63:0] MTIME_CLINT, // MTIME, from CLINT + input logic [31:0] GPIOIN, // GPIO pin input value + output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable + input logic UARTSin, // UART serial input + output logic UARTSout, // UART serial output + output logic SDCCmdOut, // SD Card command output + output logic SDCCmdOE, // SD Card command output enable + input logic SDCCmdIn, // SD Card command input + input logic [3:0] SDCDatIn, // SD Card data input + output logic SDCCLK // SD Card clock ); logic [P.XLEN-1:0] HREADRam, HREADSDC; - logic [10:0] HSELRegions; - logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; - logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; - logic HRESPRam, HRESPSDC; - logic HREADYRam, HRESPSDCD; + logic [10:0] HSELRegions; + logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; + logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; + logic HRESPRam, HRESPSDC; + logic HREADYRam, HRESPSDCD; logic [P.XLEN-1:0] HREADBootRom; - logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC; - logic HSELNoneD; - logic UARTIntr,GPIOIntr; - logic SDCIntM; + logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC; + logic HSELNoneD; + logic UARTIntr,GPIOIntr; + logic SDCIntM; - logic PCLK, PRESETn, PWRITE, PENABLE; - logic [3:0] PSEL, PREADY; - logic [31:0] PADDR; + logic PCLK, PRESETn, PWRITE, PENABLE; + logic [3:0] PSEL, PREADY; + logic [31:0] PADDR; logic [P.XLEN-1:0] PWDATA; logic [P.XLEN/8-1:0] PSTRB; logic [3:0][P.XLEN-1:0] PRDATA; logic [P.XLEN-1:0] HREADBRIDGE; - logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED; + logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED; // Determine which region of physical memory (if any) is being accessed // Use a trimmed down portion of the PMA checker - only the address decoders @@ -154,9 +154,9 @@ module uncore import cvw::*; #(parameter cvw_t P)( .SDCIntM ); end else begin : sdc - assign SDCCLK = 0; + assign SDCCLK = 0; assign SDCCmdOut = 0; - assign SDCCmdOE = 0; + assign SDCCmdOE = 0; end // AHB Read Multiplexer @@ -189,4 +189,3 @@ module uncore import cvw::*; #(parameter cvw_t P)( HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD}); flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED); endmodule - diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index a3becb9be..39f780a60 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -26,18 +26,18 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( +module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, // Privileged input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic [63:0] MTIME_CLINT, // Bus Interface - input logic [P.AHBW-1:0] HRDATA, + input logic [P.AHBW-1:0] HRDATA, input logic HREADY, HRESP, output logic HCLK, HRESETn, - output logic [P.PA_BITS-1:0] HADDR, - output logic [P.AHBW-1:0] HWDATA, - output logic [P.XLEN/8-1:0] HWSTRB, + output logic [P.PA_BITS-1:0] HADDR, + output logic [P.AHBW-1:0] HWDATA, + output logic [P.XLEN/8-1:0] HWSTRB, output logic HWRITE, output logic [2:0] HSIZE, output logic [2:0] HBURST, @@ -55,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic IntDivE, W64E; logic CSRReadM, CSRWriteM, PrivilegedM; logic [1:0] AtomicM; - logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; - logic [P.XLEN-1:0] SrcAM; + logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; + logic [P.XLEN-1:0] SrcAM; logic [2:0] Funct3E; logic [31:0] InstrD; logic [31:0] InstrM, InstrOrigM; - logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; - logic [P.XLEN-1:0] PCM; - logic [P.XLEN-1:0] CSRReadValW, MDUResultW; - logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; + logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; + logic [P.XLEN-1:0] PCM; + logic [P.XLEN-1:0] CSRReadValW, MDUResultW; + logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [1:0] MemRWM; logic InstrValidD, InstrValidE, InstrValidM; logic InstrMisalignedFaultM; @@ -77,37 +77,38 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic DivBusyE; logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; logic SquashSCW; + logic MDUActiveE; // Mul/Div instruction being executed // floating point unit signals logic [2:0] FRM_REGW; logic [4:0] RdE, RdM, RdW; logic FPUStallD; logic FWriteIntE; - logic [P.FLEN-1:0] FWriteDataM; - logic [P.XLEN-1:0] FIntResM; - logic [P.XLEN-1:0] FCvtIntResW; + logic [P.FLEN-1:0] FWriteDataM; + logic [P.XLEN-1:0] FIntResM; + logic [P.XLEN-1:0] FCvtIntResW; logic FCvtIntW; logic FDivBusyE; logic FRegWriteM; logic FCvtIntStallD; logic FpLoadStoreM; logic [4:0] SetFflagsM; - logic [P.XLEN-1:0] FIntDivResultW; + logic [P.XLEN-1:0] FIntDivResultW; // memory management unit signals logic ITLBWriteF; logic ITLBMissF; - logic [P.XLEN-1:0] SATP_REGW; + logic [P.XLEN-1:0] SATP_REGW; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] PrivilegeModeW; - logic [P.XLEN-1:0] PTE; + logic [P.XLEN-1:0] PTE; logic [1:0] PageType; logic sfencevmaM; logic SelHPTW; // PMA checker signals - var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0]; + var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0]; // IMem stalls @@ -116,14 +117,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( // cpu lsu interface logic [2:0] Funct3M; - logic [P.XLEN-1:0] IEUAdrE; - logic [P.XLEN-1:0] WriteDataM; - logic [P.XLEN-1:0] IEUAdrM; - logic [P.LLEN-1:0] ReadDataW; + logic [P.XLEN-1:0] IEUAdrE; + logic [P.XLEN-1:0] WriteDataM; + logic [P.XLEN-1:0] IEUAdrM; + logic [P.LLEN-1:0] ReadDataW; logic CommittedM; // AHB ifu interface - logic [P.PA_BITS-1:0] IFUHADDR; + logic [P.PA_BITS-1:0] IFUHADDR; logic [2:0] IFUHBURST; logic [1:0] IFUHTRANS; logic [2:0] IFUHSIZE; @@ -131,9 +132,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic IFUHREADY; // AHB LSU interface - logic [P.PA_BITS-1:0] LSUHADDR; - logic [P.XLEN-1:0] LSUHWDATA; - logic [P.XLEN/8-1:0] LSUHWSTRB; + logic [P.PA_BITS-1:0] LSUHADDR; + logic [P.XLEN-1:0] LSUHWDATA; + logic [P.XLEN/8-1:0] LSUHWSTRB; logic LSUHWRITE; logic LSUHREADY; @@ -190,14 +191,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .InstrD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, // Execute Stage interface .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E, - .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, + .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .MDUActiveE, // Memory stage interface - .SquashSCW, // from LSU - .MemRWM, // read/write control goes to LSU - .AtomicM, // atomic control goes to LSU + .SquashSCW, // from LSU + .MemRWM, // read/write control goes to LSU + .AtomicM, // atomic control goes to LSU .WriteDataM, // Write data to LSU - .Funct3M, // size and signedness to LSU - .SrcAM, // to privilege and fpu + .Funct3M, // size and signedness to LSU + .SrcAM, // to privilege and fpu .RdE, .RdM, .FIntResM, .FlushDCacheM, .BranchD, .BranchE, .JumpD, .JumpE, // Writeback stage @@ -219,24 +220,24 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY, // connect to csr or privilege and stay the same. - .PrivilegeModeW, .BigEndianM, // connects to csr - .PMPCFG_ARRAY_REGW, // connects to csr - .PMPADDR_ARRAY_REGW, // connects to csr + .PrivilegeModeW, .BigEndianM, // connects to csr + .PMPCFG_ARRAY_REGW, // connects to csr + .PMPADDR_ARRAY_REGW, // connects to csr // hptw keep i/o - .SATP_REGW, // from csr - .STATUS_MXR, // from csr - .STATUS_SUM, // from csr - .STATUS_MPRV, // from csr - .STATUS_MPP, // from csr - .sfencevmaM, // connects to privilege - .DCacheStallM, // connects to privilege - .LoadPageFaultM, // connects to privilege - .StoreAmoPageFaultM, // connects to privilege - .LoadMisalignedFaultM, // connects to privilege - .LoadAccessFaultM, // connects to privilege - .HPTWInstrAccessFaultF, // connects to privilege - .StoreAmoMisalignedFaultM, // connects to privilege - .StoreAmoAccessFaultM, // connects to privilege + .SATP_REGW, // from csr + .STATUS_MXR, // from csr + .STATUS_SUM, // from csr + .STATUS_MPRV, // from csr + .STATUS_MPP, // from csr + .sfencevmaM, // connects to privilege + .DCacheStallM, // connects to privilege + .LoadPageFaultM, // connects to privilege + .StoreAmoPageFaultM, // connects to privilege + .LoadMisalignedFaultM, // connects to privilege + .LoadAccessFaultM, // connects to privilege + .HPTWInstrAccessFaultF, // connects to privilege + .StoreAmoMisalignedFaultM, // connects to privilege + .StoreAmoAccessFaultM, // connects to privilege .InstrUpdateDAF, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .LSUStallM); @@ -292,63 +293,63 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); end else begin - assign CSRReadValW = 0; + assign CSRReadValW = 0; assign UnalignedPCNextF = PC2NextF; - assign RetM = 0; - assign TrapM = 0; - assign wfiM = 0; - assign IntPendingM = 0; - assign sfencevmaM = 0; - assign BigEndianM = 0; + assign RetM = 0; + assign TrapM = 0; + assign wfiM = 0; + assign IntPendingM = 0; + assign sfencevmaM = 0; + assign BigEndianM = 0; end // multiply/divide unit if (P.M_SUPPORTED | P.ZMMUL_SUPPORTED) begin:mdu mdu #(P) mdu(.clk, .reset, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .ForwardedSrcAE, .ForwardedSrcBE, - .Funct3E, .Funct3M, .IntDivE, .W64E, + .Funct3E, .Funct3M, .IntDivE, .W64E, .MDUActiveE, .MDUResultW, .DivBusyE); end else begin // no M instructions supported assign MDUResultW = 0; - assign DivBusyE = 0; + assign DivBusyE = 0; end // floating point unit if (P.F_SUPPORTED) begin:fpu fpu #(P) fpu( .clk, .reset, - .FRM_REGW, // Rounding mode from CSR - .InstrD, // instruction from IFU - .ReadDataW(ReadDataW[P.FLEN-1:0]),// Read data from memory - .ForwardedSrcAE, // Integer input being processed (from IEU) - .StallE, .StallM, .StallW, // stall signals from HZU - .FlushE, .FlushM, .FlushW, // flush signals from HZU - .RdE, .RdM, .RdW, // which FP register to write to (from IEU) - .STATUS_FS, // is floating-point enabled? - .FRegWriteM, // FP register write enable + .FRM_REGW, // Rounding mode from CSR + .InstrD, // instruction from IFU + .ReadDataW(ReadDataW[P.FLEN-1:0]), // Read data from memory + .ForwardedSrcAE, // Integer input being processed (from IEU) + .StallE, .StallM, .StallW, // stall signals from HZU + .FlushE, .FlushM, .FlushW, // flush signals from HZU + .RdE, .RdM, .RdW, // which FP register to write to (from IEU) + .STATUS_FS, // is floating-point enabled? + .FRegWriteM, // FP register write enable .FpLoadStoreM, - .ForwardedSrcBE, // Integer input for intdiv + .ForwardedSrcBE, // Integer input for intdiv .Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions - .FPUStallD, // Stall the decode stage - .FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation - .FWriteDataM, // Data to be written to memory - .FIntResM, // data to be written to integer register - .FCvtIntResW, // fp -> int conversion result to be stored in int register - .FCvtIntW, // fpu result selection - .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) - .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction - .SetFflagsM, // FPU flags (to privileged unit) + .FPUStallD, // Stall the decode stage + .FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation + .FWriteDataM, // Data to be written to memory + .FIntResM, // data to be written to integer register + .FCvtIntResW, // fp -> int conversion result to be stored in int register + .FCvtIntW, // fpu result selection + .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) + .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction + .SetFflagsM, // FPU flags (to privileged unit) .FIntDivResultW); - end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low - assign FPUStallD = 0; - assign FWriteIntE = 0; - assign FCvtIntE = 0; - assign FIntResM = 0; - assign FCvtIntW = 0; - assign FDivBusyE = 0; + end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low + assign FPUStallD = 0; + assign FWriteIntE = 0; + assign FCvtIntE = 0; + assign FIntResM = 0; + assign FCvtIntW = 0; + assign FDivBusyE = 0; assign IllegalFPUInstrD = 1; - assign SetFflagsM = 0; - assign FpLoadStoreM = 0; + assign SetFflagsM = 0; + assign FpLoadStoreM = 0; end endmodule diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index 03974fe51..014b93687 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -26,22 +26,19 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "config.vh" -//import cvw::*; // global CORE-V-Wally parameters - -module wallypipelinedsoc import cvw::*; ( +module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( input logic clk, input logic reset_ext, // external asynchronous reset pin output logic reset, // reset synchronized to clk to prevent races on release // AHB Interface - input logic [AHBW-1:0] HRDATAEXT, + input logic [P.AHBW-1:0] HRDATAEXT, input logic HREADYEXT, HRESPEXT, output logic HSELEXT, // outputs to external memory, shared with uncore memory output logic HCLK, HRESETn, - output logic [PA_BITS-1:0] HADDR, - output logic [AHBW-1:0] HWDATA, - output logic [XLEN/8-1:0] HWSTRB, + output logic [P.PA_BITS-1:0] HADDR, + output logic [P.AHBW-1:0] HWDATA, + output logic [P.XLEN/8-1:0] HWSTRB, output logic HWRITE, output logic [2:0] HSIZE, output logic [2:0] HBURST, @@ -51,9 +48,9 @@ module wallypipelinedsoc import cvw::*; ( output logic HREADY, // I/O Interface input logic TIMECLK, // optional for CLINT MTIME counter - input logic [31:0] GPIOIN, // inputs from GPIO - output logic [31:0] GPIOOUT, // output values for GPIO - output logic [31:0] GPIOEN, // output enables for GPIO + input logic [31:0] GPIOIN, // inputs from GPIO + output logic [31:0] GPIOOUT, // output values for GPIO + output logic [31:0] GPIOEN, // output enables for GPIO input logic UARTSin, // UART serial data input output logic UARTSout, // UART serial data output input logic SDCCmdIn, // SDC Command input @@ -64,14 +61,12 @@ module wallypipelinedsoc import cvw::*; ( ); // Uncore signals - logic [AHBW-1:0] HRDATA; // from AHB mux in uncore + logic [P.AHBW-1:0] HRDATA; // from AHB mux in uncore logic HRESP; // response from AHB logic MTimerInt, MSwInt;// timer and software interrupts from CLINT logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic MExtInt,SExtInt; // from PLIC - `include "parameter-defs.vh" - // synchronize reset to SOC clock domain synchronizer resetsync(.clk, .d(reset_ext), .q(reset)); @@ -83,7 +78,7 @@ module wallypipelinedsoc import cvw::*; ( ); // instantiate uncore if a bus interface exists - if (BUS_SUPPORTED) begin : uncore + if (P.BUS_SUPPORTED) begin : uncore uncore #(P) uncore(.HCLK, .HRESETn, .TIMECLK, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT, diff --git a/testbench/common/checksignature.sv b/testbench/common/checksignature.sv new file mode 100644 index 000000000..7fb589bb6 --- /dev/null +++ b/testbench/common/checksignature.sv @@ -0,0 +1,26 @@ +/////////////////////////////////////////// +// checksignature.sv +// +// Written: David Harris David_Harris@hmc.edu +// Modified: 14 June 2023 +// +// Purpose: Verifies the memory signature. +// +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/testbench/common/functionName.sv b/testbench/common/functionName.sv index c986c2e51..90157f255 100644 --- a/testbench/common/functionName.sv +++ b/testbench/common/functionName.sv @@ -1,6 +1,8 @@ /////////////////////////////////////////// // functionName.sv // +// Written: Ross Thompson ross1728@gmail.com +// // Purpose: decode name of function // // A component of the Wally configurable RISC-V project. @@ -21,21 +23,19 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module FunctionName(reset, clk, ProgramAddrMapFile, ProgramLabelMapFile); +module FunctionName import cvw::*; #(parameter cvw_t P) ( + input logic reset, + input logic clk, + input string ProgramAddrMapFile, + input string ProgramLabelMapFile + ); - input logic reset; - input logic clk; - input string ProgramAddrMapFile; - input string ProgramLabelMapFile; - - logic [`XLEN-1:0] ProgramAddrMapMemory []; + logic [P.XLEN-1:0] ProgramAddrMapMemory []; string ProgramLabelMapMemory [integer]; string FunctionName; - logic [`XLEN-1:0] PCF, PCD, PCE, PCM, FunctionAddr, PCM_temp, PCMOld; + logic [P.XLEN-1:0] PCF, PCD, PCE, PCM, FunctionAddr, PCM_temp, PCMOld; logic StallD, StallE, StallM, FlushD, FlushE, FlushM; logic InstrValidM; integer ProgramAddrIndex, ProgramAddrIndexQ; @@ -53,21 +53,20 @@ module FunctionName(reset, clk, ProgramAddrMapFile, ProgramLabelMapFile); // when the F and D stages are flushed we need to ensure the PCE is held so that the function name does not // erroneously change. // also need to hold the old value not an erroneously fetched PC. - flopenr #(`XLEN) PCDReg(clk, reset, ~StallD, FlushD ? PCE : PCF, PCD); - flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, FlushD & FlushE ? PCF : FlushE ? PCE : PCD, PCE); - flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, FlushD & FlushE & FlushM ? PCF : FlushE & FlushM ? PCE : FlushM ? PCM : PCE, PCM_temp); - flopenr #(`XLEN) PCMOldReg(clk, reset, InstrValidM, PCM_temp, PCMOld); + flopenr #(P.XLEN) PCDReg(clk, reset, ~StallD, FlushD ? PCE : PCF, PCD); + flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, FlushD & FlushE ? PCF : FlushE ? PCE : PCD, PCE); + flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, FlushD & FlushE & FlushM ? PCF : FlushE & FlushM ? PCE : FlushM ? PCM : PCE, PCM_temp); + flopenr #(P.XLEN) PCMOldReg(clk, reset, InstrValidM, PCM_temp, PCMOld); assign PCM = InstrValidM ? PCM_temp : PCMOld; - task automatic bin_search_min; - input logic [`XLEN-1:0] pc; - input logic [`XLEN-1:0] length; - ref logic [`XLEN-1:0] array []; - output logic [`XLEN-1:0] minval; - output logic [`XLEN-1:0] mid; + input logic [P.XLEN-1:0] pc; + input logic [P.XLEN-1:0] length; + ref logic [P.XLEN-1:0] array []; + output logic [P.XLEN-1:0] minval; + output logic [P.XLEN-1:0] mid; - logic [`XLEN-1:0] left, right; + logic [P.XLEN-1:0] left, right; begin if ( pc == 0 ) begin @@ -171,7 +170,6 @@ module FunctionName(reset, clk, ProgramAddrMapFile, ProgramLabelMapFile); initial ProgramAddrIndex = '0; assign FunctionName = AnyUnknown ? "Unknown!" : ProgramLabelMapMemory[ProgramAddrIndex]; - endmodule // function_radix diff --git a/testbench/common/instrNameDecTB.sv b/testbench/common/instrNameDecTB.sv index dd993e715..1529de5e6 100644 --- a/testbench/common/instrNameDecTB.sv +++ b/testbench/common/instrNameDecTB.sv @@ -54,12 +54,28 @@ module instrNameDecTB( 10'b0010011_000: if (instr[31:15] == 0 & instr[11:7] ==0) name = "NOP/FLUSH"; else name = "ADDI"; 10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI"; - else name = "ILLEGAL"; + else if (funct7[6:1] == 6'b010010) name = "BCLRI"; + else if (funct7[6:1] == 6'b011010) name = "BINVI"; + else if (funct7[6:1] == 6'b001010) name = "BSETI"; + else if (funct7 == 7'b0110000) begin + case (rs2) + 5'b00000: name = "CLZ"; + 5'b00010: name = "CPOP"; + 5'b00001: name = "CTZ"; + 5'b00100: name = "SEXT.B"; + 5'b00101: name = "SEXT.H"; + default: name = "ILLEGAL"; + endcase + end else name = "ILLEGAL"; 10'b0010011_010: name = "SLTI"; 10'b0010011_011: name = "SLTIU"; 10'b0010011_100: name = "XORI"; 10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI"; else if (funct7[6:1] == 6'b010000) name = "SRAI"; + else if (funct7[6:1] == 6'b011010 & rs2 == 5'b11000) name = "REV8"; + else if (funct7[6:1] == 6'b011000) name = "RORI"; + else if (funct7[6:1] == 6'b010010) name = "BEXTI"; + else if (funct7 == 7'b0010100 & rs2 == 5'b00111) name = "ORC.B"; else name = "ILLEGAL"; 10'b0010011_110: name = "ORI"; 10'b0010011_111: name = "ANDI"; @@ -69,22 +85,41 @@ module instrNameDecTB( 10'b0100011_010: name = "SW"; 10'b0100011_011: name = "SD"; 10'b0011011_000: name = "ADDIW"; - 10'b0011011_001: name = "SLLIW"; + 10'b0011011_001: if (funct7 == 7'b0000000 )name = "SLLIW"; + else if (funct7[6:1] == 6'b000010) name = "SLLI.UW"; + else if (funct7 == 7'b0110000) begin + case (rs2) + 5'b00000: name = "CLZW"; + 5'b00010: name = "CPOPW"; + 5'b00001: name = "CTZW"; + default: name = "ILLEGAL"; + endcase + end else name = "ILLEGAL"; 10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW"; else if (funct7 == 7'b0100000) name = "SRAIW"; + else if (funct7 == 7'b0110000) name = "RORIW"; else name = "ILLEGAL"; 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; else if (funct7 == 7'b0100000) name = "SUBW"; else if (funct7 == 7'b0000001) name = "MULW"; + else if (funct7 == 7'b0000100) name = "ADD.UW"; else name = "ILLEGAL"; 10'b0111011_001: if (funct7 == 7'b0000000) name = "SLLW"; else if (funct7 == 7'b0000001) name = "DIVW"; + else if (funct7 == 7'b0110000) name = "ROLW"; + else name = "ILLEGAL"; + 10'b0111011_010: if (funct7 == 7'b0010000) name = "SH1ADD.UW"; + else name = "ILLEGAL"; + 10'b0111011_100: if (funct7 == 7'b0010000) name = "SH2ADD.UW"; + else if (funct7 == 7'b0000100) name = "ZEXT.H"; else name = "ILLEGAL"; 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; else if (funct7 == 7'b0100000) name = "SRAW"; else if (funct7 == 7'b0000001) name = "DIVUW"; + else if (funct7 == 7'b0110000) name = "RORW"; else name = "ILLEGAL"; 10'b0111011_110: if (funct7 == 7'b0000001) name = "REMW"; + else if (funct7 == 7'b0010000) name = "SH3ADD.UW"; else name = "ILLEGAL"; 10'b0111011_111: if (funct7 == 7'b0000001) name = "REMUW"; else name = "ILLEGAL"; @@ -94,25 +129,45 @@ module instrNameDecTB( else name = "ILLEGAL"; 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; else if (funct7 == 7'b0000001) name = "MULH"; + else if (funct7 == 7'b0110000) name = "ROL"; + else if (funct7 == 7'b0000101) name = "CLMUL"; + else if (funct7 == 7'b0100100) name = "BCLR"; + else if (funct7 == 7'b0110100) name = "BINV"; + else if (funct7 == 7'b0010100) name = "BSET"; else name = "ILLEGAL"; 10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT"; else if (funct7 == 7'b0000001) name = "MULHSU"; + else if (funct7 == 7'b0010000) name = "SH1ADD"; + else if (funct7 == 7'b0000101) name = "CLMULR"; else name = "ILLEGAL"; 10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; else if (funct7 == 7'b0000001) name = "MULHU"; + else if (funct7 == 7'b0000101) name = "CLMULH"; else name = "ILLEGAL"; 10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; else if (funct7 == 7'b0000001) name = "DIV"; + else if (funct7 == 7'b0010000) name = "SH2ADD"; + else if (funct7 == 7'b0000101) name = "MIN"; + else if (funct7 == 7'b0100000) name = "ORN"; + else if (funct7 == 7'b0000100) name = "ZEXT.H"; else name = "ILLEGAL"; 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; else if (funct7 == 7'b0000001) name = "DIVU"; else if (funct7 == 7'b0100000) name = "SRA"; + else if (funct7 == 7'b0000101) name = "MINU"; + else if (funct7 == 7'b0110000) name = "ROR"; + else if (funct7 == 7'b0100100) name = "BEXT"; else name = "ILLEGAL"; 10'b0110011_110: if (funct7 == 7'b0000000) name = "OR"; else if (funct7 == 7'b0000001) name = "REM"; + else if (funct7 == 7'b0010000) name = "SH3ADD"; + else if (funct7 == 7'b0000101) name = "MAX"; + else if (funct7 == 7'b0100000) name = "XNOR"; else name = "ILLEGAL"; 10'b0110011_111: if (funct7 == 7'b0000000) name = "AND"; else if (funct7 == 7'b0000001) name = "REMU"; + else if (funct7 == 7'b0000101) name = "MAXU"; + else if (funct7 == 7'b0100000) name = "ANDN"; else name = "ILLEGAL"; 10'b0110111_???: name = "LUI"; 10'b1100011_000: name = "BEQ"; @@ -250,7 +305,10 @@ module instrNameDecTB( else if (funct7[6:2] == 5'b00100) name = "FSGNJX"; else if (funct7[6:2] == 5'b10100) name = "FEQ"; else name = "ILLEGAL"; + /* verilator lint_off CASEOVERLAP */ + // *** RT: definitely take a look at this. This overlaps with 10'b1010011_000 10'b1010011_???: if (funct7[6:2] == 5'b00000) name = "FADD"; + /* verilator lint_on CASEOVERLAP */ else if (funct7[6:2] == 5'b00001) name = "FSUB"; else if (funct7[6:2] == 5'b00010) name = "FMUL"; else if (funct7[6:2] == 5'b00011) name = "FDIV"; diff --git a/testbench/common/loggers.sv b/testbench/common/loggers.sv new file mode 100644 index 000000000..cf42fe4ec --- /dev/null +++ b/testbench/common/loggers.sv @@ -0,0 +1,234 @@ +/////////////////////////////////////////// +// loggers.sv +// +// Written: Ross Thompson ross1728@gmail.com +// Modified: 14 June 2023 +// +// Purpose: Log branch instructions, log instruction fetches, +// log I$ misses, log data memory accesses, log D$ misses, and +// log other related operations +// +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module loggers import cvw::*; #(parameter cvw_t P, + parameter TEST, + parameter PrintHPMCounters, + parameter I_CACHE_ADDR_LOGGER, + parameter D_CACHE_ADDR_LOGGER, + parameter BPRED_LOGGER) ( + input logic clk, + input logic reset, + input logic DCacheFlushStart, + input logic DCacheFlushDone, +// input logic BeginSample, +// input logic StartSample, +// input logic EndSample, + input string memfilename + ); + + // performance counter logging + logic BeginSample; + logic StartSample, EndSample; + if(PrintHPMCounters & P.ZICNTR_SUPPORTED) begin : HPMCSample + integer HPMCindex; + logic StartSampleFirst; + logic StartSampleDelayed, BeginDelayed; + logic EndSampleFirst, EndSampleDelayed; + logic [P.XLEN-1:0] InitialHPMCOUNTERH[P.COUNTERS-1:0]; + + string HPMCnames[] = '{"Mcycle", + "------", + "InstRet", + "Br Count", + "Jump Not Return", + "Return", + "BP Wrong", + "BP Dir Wrong", + "BP Target Wrong", + "RAS Wrong", + "Instr Class Wrong", + "Load Stall", + "Store Stall", + "D Cache Access", + "D Cache Miss", + "D Cache Cycles", + "I Cache Access", + "I Cache Miss", + "I Cache Cycles", + "CSR Write", + "FenceI", + "SFenceVMA", + "Interrupt", + "Exception", + "Divide Cycles" + }; + + if(TEST == "embench") begin + // embench runs warmup then runs start_trigger + // embench end with stop_trigger. + assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_trigger"; + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + + assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_trigger"; + flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); + assign EndSample = EndSampleFirst & ~ EndSampleDelayed; + + end else if(TEST == "coremark") begin + // embench runs warmup then runs start_trigger + // embench end with stop_trigger. + assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time"; + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + + assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time"; + flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); + assign EndSample = EndSampleFirst & ~ EndSampleDelayed; + + end else begin + // default start condiction is reset + // default end condiction is end of test (DCacheFlushDone) + assign StartSampleFirst = reset; + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + assign EndSample = DCacheFlushStart & ~DCacheFlushDone; + + flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed); + assign BeginSample = StartSampleFirst & ~BeginDelayed; + + end + always @(negedge clk) begin + if(StartSample) begin + for(HPMCindex = 0; HPMCindex < 32; HPMCindex += 1) begin + InitialHPMCOUNTERH[HPMCindex] <= dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[HPMCindex]; + end + end + if(EndSample) begin + for(HPMCindex = 0; HPMCindex < HPMCnames.size(); HPMCindex += 1) begin + // unlikely to have more than 10M in any counter. + $display("Cnt[%2d] = %7d %s", HPMCindex, dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[HPMCindex] - InitialHPMCOUNTERH[HPMCindex], HPMCnames[HPMCindex]); + end + end + end + end + + if (P.ICACHE_SUPPORTED && I_CACHE_ADDR_LOGGER) begin : ICacheLogger + int file; + string LogFile; + logic resetD, resetEdge; + logic Enable; + logic InvalDelayed, InvalEdge; + + assign Enable = dut.core.ifu.bus.icache.icache.cachefsm.LRUWriteEn & + dut.core.ifu.immu.immu.pmachecker.Cacheable & + ~dut.core.ifu.bus.icache.icache.cachefsm.FlushStage & + ~reset; + flop #(1) ResetDReg(clk, reset, resetD); + assign resetEdge = ~reset & resetD; + + flop #(1) InvalReg(clk, dut.core.ifu.InvalidateICacheM, InvalDelayed); + assign InvalEdge = dut.core.ifu.InvalidateICacheM & ~InvalDelayed; + + initial begin + LogFile = "ICache.log"; + file = $fopen(LogFile, "w"); + $fwrite(file, "BEGIN %s\n", memfilename); + end + string AccessTypeString, HitMissString; + assign HitMissString = dut.core.ifu.bus.icache.icache.CacheHit ? "H" : + dut.core.ifu.bus.icache.icache.vict.cacheLRU.AllValid ? "E" : "M"; + always @(posedge clk) begin + if(resetEdge) $fwrite(file, "TRAIN\n"); + if(BeginSample) $fwrite(file, "BEGIN %s\n", memfilename); + if(Enable) begin // only log i cache reads + $fwrite(file, "%h R %s\n", dut.core.ifu.PCPF, HitMissString); + end + if(InvalEdge) $fwrite(file, "0 I X\n"); + if(EndSample) $fwrite(file, "END %s\n", memfilename); + end + end + + + if (P.DCACHE_SUPPORTED && D_CACHE_ADDR_LOGGER) begin : DCacheLogger + int file; + string LogFile; + logic resetD, resetEdge; + logic Enabled; + string AccessTypeString, HitMissString; + + flop #(1) ResetDReg(clk, reset, resetD); + assign resetEdge = ~reset & resetD; + assign HitMissString = dut.core.lsu.bus.dcache.dcache.CacheHit ? "H" : + (!dut.core.lsu.bus.dcache.dcache.vict.cacheLRU.AllValid) ? "M" : + dut.core.lsu.bus.dcache.dcache.LineDirty ? "D" : "E"; + assign AccessTypeString = dut.core.lsu.bus.dcache.FlushDCache ? "F" : + dut.core.lsu.bus.dcache.CacheAtomicM[1] ? "A" : + dut.core.lsu.bus.dcache.CacheRWM == 2'b10 ? "R" : + dut.core.lsu.bus.dcache.CacheRWM == 2'b01 ? "W" : + "NULL"; + + assign Enabled = dut.core.lsu.bus.dcache.dcache.cachefsm.LRUWriteEn & + ~dut.core.lsu.bus.dcache.dcache.cachefsm.FlushStage & + dut.core.lsu.dmmu.dmmu.pmachecker.Cacheable & + (AccessTypeString != "NULL"); + + initial begin + LogFile = "DCache.log"; + file = $fopen(LogFile, "w"); + $fwrite(file, "BEGIN %s\n", memfilename); + end + always @(posedge clk) begin + if(resetEdge) $fwrite(file, "TRAIN\n"); + if(BeginSample) $fwrite(file, "BEGIN %s\n", memfilename); + if(Enabled) begin + $fwrite(file, "%h %s %s\n", dut.core.lsu.PAdrM, AccessTypeString, HitMissString); + end + if(dut.core.lsu.bus.dcache.dcache.cachefsm.FlushFlag) $fwrite(file, "0 F X\n"); + if(EndSample) $fwrite(file, "END %s\n", memfilename); + end + end + + if (P.BPRED_SUPPORTED) begin : BranchLogger + if (BPRED_LOGGER) begin + string direction; + int file; + logic PCSrcM; + string LogFile; + logic resetD, resetEdge; + flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM); + flop #(1) ResetDReg(clk, reset, resetD); + assign resetEdge = ~reset & resetD; + initial begin + LogFile = "branch.log"; // will break some of Ross's research analysis scripts + //LogFile = $psprintf("branch_%s%0d.log", P.BPRED_TYPE, P.BPRED_SIZE); + file = $fopen(LogFile, "w"); + end + always @(posedge clk) begin + if(resetEdge) $fwrite(file, "TRAIN\n"); + if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); + if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin + direction = PCSrcM ? "t" : "n"; + $fwrite(file, "%h %s\n", dut.core.PCM, direction); + end + if(EndSample) $fwrite(file, "END %s\n", memfilename); + end + end + end + +endmodule diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv index b3bc8f96f..50577c37d 100644 --- a/testbench/common/riscvassertions.sv +++ b/testbench/common/riscvassertions.sv @@ -19,45 +19,45 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module riscvassertions; +module riscvassertions import cvw::*; #(parameter cvw_t P); initial begin - assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); - assert (`S_SUPPORTED || `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); - assert (`IDIV_BITSPERCYCLE == 1 || `IDIV_BITSPERCYCLE==2 || `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); - assert (`F_SUPPORTED || ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)"); - assert (`D_SUPPORTED || ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)"); - assert (`F_SUPPORTED || ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); - assert (`DCACHE_SUPPORTED || ~`F_SUPPORTED || `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); - assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); - assert (`FLEN<=`XLEN || `DCACHE_SUPPORTED || `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); - assert (`DCACHE_WAYSIZEINBYTES <= 4096 || (!`DCACHE_SUPPORTED) || `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`DCACHE_LINELENINBITS >= 128 || (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); - assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); - assert (`ICACHE_WAYSIZEINBYTES <= 4096 || (!`ICACHE_SUPPORTED) || `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`ICACHE_LINELENINBITS >= 32 || (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); - assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); - assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS || (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES || (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS || (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES || (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES || `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); - assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES || `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); - assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF"); - assert (`ZICSR_SUPPORTED == 1 || (`PMP_ENTRIES == 0 && `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); - assert (`ZICSR_SUPPORTED == 1 || (`S_SUPPORTED == 0 && `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported"); - assert (`U_SUPPORTED || (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported"); - assert (`VIRTMEM_SUPPORTED == 0 || (`DTIM_SUPPORTED == 0 && `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); - assert (`DCACHE_SUPPORTED || `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); - assert (`ICACHE_SUPPORTED || `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); - assert ((`DCACHE_SUPPORTED == 0 && `ICACHE_SUPPORTED == 0) || `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED."); - assert (`DCACHE_LINELENINBITS <= `XLEN*16 || (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); - assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); - assert (`DCACHE_SUPPORTED || (`A_SUPPORTED == 0)) else $error("Atomic extension (A) requires cache on Wally."); - assert (`IDIV_ON_FPU == 0 || `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); - assert (`SSTC_SUPPORTED == 0 || (`S_SUPPORTED)) else $error("SSTC requires S_SUPPORTED"); - assert ((`ZMMUL_SUPPORTED == 0) || (`M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled"); + 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.UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'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.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"); end endmodule diff --git a/testbench/common/shadowmem.sv b/testbench/common/shadowmem.sv new file mode 100644 index 000000000..021d4b82f --- /dev/null +++ b/testbench/common/shadowmem.sv @@ -0,0 +1,139 @@ +/////////////////////////////////////////// +// shadowmem.sv +// +// Written: David Harris David_Harris@hmc.edu and Ross Thompson ross1728@gmail.com +// Modified: 14 June 2023 +// +// Purpose: The L1 data cache and any feature L2 or high cache will not necessary writeback all dirty +// line before the end of test. Signature based regression tests need to check the L1 data cache +// in addition to the main memory. These modules create a shadow memory with a projection of the +// D$ contents. +// +// 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. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module DCacheFlushFSM import cvw::*; #(parameter cvw_t P) + (input logic clk, + input logic reset, + input logic start, + output logic done); + + genvar adr; + + logic [P.XLEN-1:0] ShadowRAM[P.UNCORE_RAM_BASE>>(1+P.XLEN/32):(P.UNCORE_RAM_RANGE+P.UNCORE_RAM_BASE)>>1+(P.XLEN/32)]; + logic startD; + + if(P.DCACHE_SUPPORTED) begin + localparam numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES; + localparam numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS; + localparam linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN; + localparam linelen = testbench.dut.core.lsu.bus.dcache.dcache.LINELEN; + localparam sramlen = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].SRAMLEN; + localparam cachesramwords = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].NUMSRAM; + localparam numwords = sramlen/P.XLEN; + localparam lognumlines = $clog2(numlines); + localparam loglinebytelen = $clog2(linebytelen); + localparam lognumways = $clog2(numways); + localparam tagstart = lognumlines + loglinebytelen; + + genvar index, way, cacheWord; + logic [sramlen-1:0] CacheData [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; + logic [sramlen-1:0] cacheline; + logic [P.XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; + logic CacheValid [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; + logic CacheDirty [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; + logic [P.PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; + for(index = 0; index < numlines; index++) begin + for(way = 0; way < numways; way++) begin + for(cacheWord = 0; cacheWord < cachesramwords; cacheWord++) begin + copyShadow #(.P(P), .tagstart(tagstart), + .loglinebytelen(loglinebytelen), .sramlen(sramlen)) + copyShadow(.clk, + .start, + .tag(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][P.PA_BITS-1-tagstart:0]), + .valid(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].ValidBits[index]), + .dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]), + // these dirty bit selections would be needed if dirty is moved inside the tag array. + //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]), + //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][P.PA_BITS+tagstart]), + .data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].wordram.CacheDataMem.RAM[index]), + .index(index), + .cacheWord(cacheWord), + .CacheData(CacheData[way][index][cacheWord]), + .CacheAdr(CacheAdr[way][index][cacheWord]), + .CacheTag(CacheTag[way][index][cacheWord]), + .CacheValid(CacheValid[way][index][cacheWord]), + .CacheDirty(CacheDirty[way][index][cacheWord])); + end + end + end + + integer i, j, k, l; + + always @(posedge clk) begin + if (startD) begin + for(i = 0; i < numlines; i++) begin + for(j = 0; j < numways; j++) begin + for(l = 0; l < cachesramwords; l++) begin + if (CacheValid[j][i][l] & CacheDirty[j][i][l]) begin + for(k = 0; k < numwords; k++) begin + //cacheline = CacheData[j][i][0]; + // does not work with modelsim + // # ** Error: ../testbench/testbench.sv(483): Range must be bounded by constant expressions. + // see https://verificationacademy.com/forums/systemverilog/range-must-be-bounded-constant-expressions + //ShadowRAM[CacheAdr[j][i][k] >> $clog2(P.XLEN/8)] = cacheline[P.XLEN*(k+1)-1:P.XLEN*k]; + ShadowRAM[(CacheAdr[j][i][l] >> $clog2(P.XLEN/8)) + k] = CacheData[j][i][l][P.XLEN*k +: P.XLEN]; + end + end + end + end + end + end + end + end + flop #(1) doneReg1(.clk, .d(start), .q(startD)); + flop #(1) doneReg2(.clk, .d(startD), .q(done)); +endmodule + +module copyShadow import cvw::*; #(parameter cvw_t P, + parameter tagstart, loglinebytelen, sramlen) + (input logic clk, + input logic start, + input logic [P.PA_BITS-1:tagstart] tag, + input logic valid, dirty, + input logic [sramlen-1:0] data, + input logic [32-1:0] index, + input logic [32-1:0] cacheWord, + output logic [sramlen-1:0] CacheData, + output logic [P.PA_BITS-1:0] CacheAdr, + output logic [P.XLEN-1:0] CacheTag, + output logic CacheValid, + output logic CacheDirty); + + + always_ff @(posedge clk) begin + if(start) begin + CacheTag = tag; + CacheValid = valid; + CacheDirty = dirty; + CacheData = data; + CacheAdr = (tag << tagstart) + (index << loglinebytelen) + (cacheWord << $clog2(sramlen/8)); + end + end + +endmodule diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 8801f5119..a1dc318ec 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -19,7 +19,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" `define NUM_REGS 32 `define NUM_CSRS 4096 @@ -29,9 +28,10 @@ `define PRINT_ALL 0 `define PRINT_CSRS 0 -module wallyTracer(rvviTrace rvvi); - localparam NUMREGS = `E_SUPPORTED ? 16 : 32; +module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); + + localparam NUMREGS = P.E_SUPPORTED ? 16 : 32; // wally specific signals logic reset; @@ -39,8 +39,8 @@ module wallyTracer(rvviTrace rvvi); logic InstrValidD, InstrValidE; logic StallF, StallD; logic STATUS_SXL, STATUS_UXL; - logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW; - logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; + logic [P.XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW; + logic [P.XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; logic InstrValidM, InstrValidW; logic StallE, StallM, StallW; logic FlushD, FlushE, FlushM, FlushW; @@ -48,16 +48,16 @@ module wallyTracer(rvviTrace rvvi); logic IntrF, IntrD, IntrE, IntrM, IntrW; logic HaltM, HaltW; logic [1:0] PrivilegeModeW; - logic [`XLEN-1:0] rf[NUMREGS]; + logic [P.XLEN-1:0] rf[NUMREGS]; logic [NUMREGS-1:0] rf_wb; logic [4:0] rf_a3; logic rf_we3; - logic [`XLEN-1:0] frf[32]; + logic [P.XLEN-1:0] frf[32]; logic [`NUM_REGS-1:0] frf_wb; logic [4:0] frf_a4; logic frf_we4; - logic [`XLEN-1:0] CSRArray [logic[11:0]]; - logic [`XLEN-1:0] CSRArrayOld [logic[11:0]]; + logic [P.XLEN-1:0] CSRArray [logic[11:0]]; + logic [P.XLEN-1:0] CSRArrayOld [logic[11:0]]; logic [`NUM_CSRS-1:0] CSR_W; logic CSRWriteM, CSRWriteW; logic [11:0] CSRAdrM, CSRAdrW; @@ -102,8 +102,8 @@ module wallyTracer(rvviTrace rvvi); // PMPCFG space is 0-15 3a0 - 3af int i, i4, i8, csrid; - logic [`XLEN-1:0] pmp; - for (i=0; i<`PMP_ENTRIES; i+=8) begin + logic [P.XLEN-1:0] pmp; + for (i=0; i 64 bit conversions to the to-be-tested list - Tests = {Tests, f128f64cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b01, 3'b11}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if(`F_SUPPORTED) begin // if single precision is supported - // add the 128 <-> 32 bit conversions to the to-be-tested list - Tests = {Tests, f128f32cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b00, 3'b11}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if(`ZFH_SUPPORTED) begin // if half precision is supported - // add the 128 <-> 16 bit conversions to the to-be-tested list - Tests = {Tests, f128f16cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b11}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end + if (`XLEN == 64) begin // if 64-bit integers are supported add their conversions + Tests = {Tests, f128rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + end + // if the floating-point conversions are being tested + if (TEST === "cvtfp" | TEST === "all") begin + if(`D_SUPPORTED) begin // if double precision is supported + // add the 128 <-> 64 bit conversions to the to-be-tested list + Tests = {Tests, f128f64cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b01, 3'b11}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if(`F_SUPPORTED) begin // if single precision is supported + // add the 128 <-> 32 bit conversions to the to-be-tested list + Tests = {Tests, f128f32cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b00, 3'b11}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if(`ZFH_SUPPORTED) begin // if half precision is supported + // add the 128 <-> 16 bit conversions to the to-be-tested list + Tests = {Tests, f128f16cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b11}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end + if (TEST === "cmp" | TEST === "all") begin// if comparisons are being tested + // add the compare tests/op-ctrls/unit/fmt + Tests = {Tests, f128cmp}; + OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested + // add the addition tests/op-ctrls/unit/fmt + Tests = {Tests, f128add}; + OpCtrl = {OpCtrl, `ADD_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested + // add the subtraction tests/op-ctrls/unit/fmt + Tests = {Tests, f128sub}; + OpCtrl = {OpCtrl, `SUB_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + // add the multiply tests/op-ctrls/unit/fmt + Tests = {Tests, f128mul}; + OpCtrl = {OpCtrl, `MUL_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "div" | TEST === "all") begin // if division is being tested + // add the divide tests/op-ctrls/unit/fmt + Tests = {Tests, f128div}; + OpCtrl = {OpCtrl, `DIV_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tested + // add the square-root tests/op-ctrls/unit/fmt + Tests = {Tests, f128sqrt}; + OpCtrl = {OpCtrl, `SQRT_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b11}; + end + end + if (TEST === "fma" | TEST === "all") begin // if fused-mutliply-add is being tested + Tests = {Tests, f128fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + end end - if (TEST === "cmp" | TEST === "all") begin// if comparisons are being tested - // add the compare tests/op-ctrls/unit/fmt - Tests = {Tests, f128cmp}; - OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested - // add the addition tests/op-ctrls/unit/fmt - Tests = {Tests, f128add}; - OpCtrl = {OpCtrl, `ADD_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested - // add the subtraction tests/op-ctrls/unit/fmt - Tests = {Tests, f128sub}; - OpCtrl = {OpCtrl, `SUB_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested - // add the multiply tests/op-ctrls/unit/fmt - Tests = {Tests, f128mul}; - OpCtrl = {OpCtrl, `MUL_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested - // add the divide tests/op-ctrls/unit/fmt - Tests = {Tests, f128div}; - OpCtrl = {OpCtrl, `DIV_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tested - // add the square-root tests/op-ctrls/unit/fmt - Tests = {Tests, f128sqrt}; - OpCtrl = {OpCtrl, `SQRT_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - if (TEST === "fma" | TEST === "all") begin // if fused-mutliply-add is being tested - Tests = {Tests, f128fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - end - end - if (`D_SUPPORTED) begin // if double precision is supported - if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested - Tests = {Tests, f64rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b01}; - end - if (`XLEN == 64) begin // if 64-bit integers are being supported - Tests = {Tests, f64rv64cvtint}; + if (`D_SUPPORTED & (TEST_SIZE == "DP" | TEST_SIZE == "all")) begin // if double precision is supported + if (TEST === "cvtint" | TEST === "all") begin // if integer conversion is being tested + Tests = {Tests, f64rv32cvtint}; // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin Unit = {Unit, `CVTINTUNIT}; Fmt = {Fmt, 2'b01}; end - end + if (`XLEN == 64) begin // if 64-bit integers are being supported + Tests = {Tests, f64rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + end + if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested + if(`F_SUPPORTED) begin // if single precision is supported + // add the 64 <-> 32 bit conversions to the to-be-tested list + Tests = {Tests, f64f32cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b00, 3'b01}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if(`ZFH_SUPPORTED) begin // if half precision is supported + // add the 64 <-> 16 bit conversions to the to-be-tested list + Tests = {Tests, f64f16cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b01}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end + if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64cmp}; + OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64add}; + OpCtrl = {OpCtrl, `ADD_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "sub" | TEST === "all") begin // if subtration is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64sub}; + OpCtrl = {OpCtrl, `SUB_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64mul}; + OpCtrl = {OpCtrl, `MUL_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "div" | TEST === "all") begin // if division is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64div}; + OpCtrl = {OpCtrl, `DIV_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tessted + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f64sqrt}; + OpCtrl = {OpCtrl, `SQRT_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (TEST === "fma" | TEST === "all") begin // if the fused multiply add is being tested + Tests = {Tests, f64fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + end end - if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested - if(`F_SUPPORTED) begin // if single precision is supported - // add the 64 <-> 32 bit conversions to the to-be-tested list - Tests = {Tests, f64f32cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b00, 3'b01}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if(`ZFH_SUPPORTED) begin // if half precision is supported - // add the 64 <-> 16 bit conversions to the to-be-tested list - Tests = {Tests, f64f16cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b01}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - end - if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64cmp}; - OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64add}; - OpCtrl = {OpCtrl, `ADD_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "sub" | TEST === "all") begin // if subtration is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64sub}; - OpCtrl = {OpCtrl, `SUB_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64mul}; - OpCtrl = {OpCtrl, `MUL_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64div}; - OpCtrl = {OpCtrl, `DIV_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tessted - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f64sqrt}; - OpCtrl = {OpCtrl, `SQRT_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (TEST === "fma" | TEST === "all") begin // if the fused multiply add is being tested - Tests = {Tests, f64fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - end - if (`F_SUPPORTED) begin // if single precision being supported - if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested - Tests = {Tests, f32rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b00}; - end - if (`XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f32rv64cvtint}; + if (`F_SUPPORTED & (TEST_SIZE == "SP" | TEST_SIZE == "all")) begin // if single precision being supported + if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested + Tests = {Tests, f32rv32cvtint}; // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin Unit = {Unit, `CVTINTUNIT}; Fmt = {Fmt, 2'b00}; end - end + if (`XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f32rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + end + if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested + if(`ZFH_SUPPORTED) begin + // add the 32 <-> 16 bit conversions to the to-be-tested list + Tests = {Tests, f32f16cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b00}; + WriteInt = {WriteInt, 1'b0, 1'b0}; + // add the unit being tested and fmt (input format) + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end + if (TEST === "cmp" | TEST === "all") begin // if comparision is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32cmp}; + OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32add}; + OpCtrl = {OpCtrl, `ADD_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "sub" | TEST === "all") begin // if subtration is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32sub}; + OpCtrl = {OpCtrl, `SUB_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "mul" | TEST === "all") begin // if multiply is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32mul}; + OpCtrl = {OpCtrl, `MUL_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "div" | TEST === "all") begin // if division is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32div}; + OpCtrl = {OpCtrl, `DIV_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f32sqrt}; + OpCtrl = {OpCtrl, `SQRT_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested + Tests = {Tests, f32fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + end end - if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested - if(`ZFH_SUPPORTED) begin - // add the 32 <-> 16 bit conversions to the to-be-tested list - Tests = {Tests, f32f16cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b00}; - WriteInt = {WriteInt, 1'b0, 1'b0}; - // add the unit being tested and fmt (input format) - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - end - if (TEST === "cmp" | TEST === "all") begin // if comparision is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32cmp}; - OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32add}; - OpCtrl = {OpCtrl, `ADD_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "sub" | TEST === "all") begin // if subtration is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32sub}; - OpCtrl = {OpCtrl, `SUB_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "mul" | TEST === "all") begin // if multiply is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32mul}; - OpCtrl = {OpCtrl, `MUL_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32div}; - OpCtrl = {OpCtrl, `DIV_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f32sqrt}; - OpCtrl = {OpCtrl, `SQRT_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested - Tests = {Tests, f32fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - end - if (`ZFH_SUPPORTED) begin // if half precision supported - if (TEST === "cvtint"| TEST === "all") begin // if in conversions are being tested - Tests = {Tests, f16rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b10}; - end - if (`XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f16rv64cvtint}; + if (`ZFH_SUPPORTED & (TEST_SIZE == "HP" | TEST_SIZE == "all")) begin // if half precision supported + if (TEST === "cvtint" | TEST === "all") begin // if in conversions are being tested + Tests = {Tests, f16rv32cvtint}; // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin Unit = {Unit, `CVTINTUNIT}; Fmt = {Fmt, 2'b10}; end - end + if (`XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f16rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end + if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16cmp}; + OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16add}; + OpCtrl = {OpCtrl, `ADD_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16sub}; + OpCtrl = {OpCtrl, `SUB_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16mul}; + OpCtrl = {OpCtrl, `MUL_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "div" | TEST === "all") begin // if division is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16div}; + OpCtrl = {OpCtrl, `DIV_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested + // add the correct tests/op-ctrls/unit/fmt to their lists + Tests = {Tests, f16sqrt}; + OpCtrl = {OpCtrl, `SQRT_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested + Tests = {Tests, f16fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + end end - if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16cmp}; - OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b10}; - end + + // check if nothing is being tested + if (Tests.size() == 0) begin + $display("TEST %s not supported in this configuration", TEST); + $stop; end - if (TEST === "add" | TEST === "all") begin // if addition is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16add}; - OpCtrl = {OpCtrl, `ADD_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16sub}; - OpCtrl = {OpCtrl, `SUB_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16mul}; - OpCtrl = {OpCtrl, `MUL_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16div}; - OpCtrl = {OpCtrl, `DIV_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested - // add the correct tests/op-ctrls/unit/fmt to their lists - Tests = {Tests, f16sqrt}; - OpCtrl = {OpCtrl, `SQRT_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested - Tests = {Tests, f16fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - end + end - // check if nothing is being tested - if (Tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); - $stop; - end - end + /////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////// + // ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| ||||||||| + // ||| ||| ||| ||| ||| || || ||| ||| ||| ||| + // |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| ||| + // ||| || ||| ||| ||| || || ||| ||| ||| ||| + // ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| ||| - // ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| ||||||||| - // ||| ||| ||| ||| ||| || || ||| ||| ||| ||| - // |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| ||| - // ||| || ||| ||| ||| || || ||| ||| ||| ||| - // ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| ||| + /////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////// + // Read the first test + initial begin + //string testname = {`PATH, Tests[TestNum]}; + string p = `PATH; + string testname; + string tt0; + tt0 = $psprintf("%s", Tests[TestNum]); + testname = {p, tt0}; + // $display("Here you are %s", testname); + $display("\n\nRunning %s vectors ", Tests[TestNum]); + $readmemh(testname, TestVectors); + // set the test index to 0 + TestNum = 0; + end - // Read the first test - initial begin - $display("\n\nRunning %s vectors", Tests[TestNum]); - $readmemh({`PATH, Tests[TestNum]}, TestVectors); - // set the test index to 0 - TestNum = 0; - end + // set a the signals for all tests + always_comb UnitVal = Unit[TestNum]; + always_comb FmtVal = Fmt[TestNum]; + always_comb OpCtrlVal = OpCtrl[OpCtrlNum]; + always_comb WriteIntVal = WriteInt[OpCtrlNum]; + always_comb FrmVal = Frm[FrmNum]; - // set a the signals for all tests - always_comb UnitVal = Unit[TestNum]; - always_comb FmtVal = Fmt[TestNum]; - always_comb OpCtrlVal = OpCtrl[OpCtrlNum]; - always_comb WriteIntVal = WriteInt[OpCtrlNum]; - always_comb FrmVal = Frm[FrmNum]; + // modify the format signal if only 2 percisions supported + // - 1 for the larger precision + // - 0 for the smaller precision + always_comb begin + if(`FMTBITS == 1) ModFmt = FmtVal == `FMT; + else ModFmt = FmtVal; + end - // modify the format signal if only 2 percisions supported - // - 1 for the larger precision - // - 0 for the smaller precision - always_comb begin - if(`FMTBITS == 1) ModFmt = FmtVal == `FMT; - else ModFmt = FmtVal; - end + // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector + readvectors #(P) readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), + .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, + .Xs, .Ys, .Zs, .Unit(UnitVal), + .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), + .Xm, .Ym, .Zm, .DivStart, + .XNaN, .YNaN, .ZNaN, + .XSNaN, .YSNaN, .ZSNaN, + .XSubnorm, .ZSubnorm, + .XZero, .YZero, .ZZero, + .XInf, .YInf, .ZInf, .XExpMax, + .X, .Y, .Z, .XPostBox); - // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector - readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), - .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, - .Xs, .Ys, .Zs, .Unit(UnitVal), - .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), - .Xm, .Ym, .Zm, .DivStart, - .XNaN, .YNaN, .ZNaN, - .XSNaN, .YSNaN, .ZSNaN, - .XSubnorm, .ZSubnorm, - .XZero, .YZero, .ZZero, - .XInf, .YInf, .ZInf, .XExpMax, - .X, .Y, .Z, .XPostBox); + /////////////////////////////////////////////////////////////////////////////////////////////// + // ||||||| ||| ||| ||||||||| + // ||| ||| ||| ||| ||| + // ||| ||| ||| ||| ||| + // ||| ||| ||| ||| ||| + // ||||||| ||||||||| ||| - /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// - // ||||||| ||| ||| ||||||||| - // ||| ||| ||| ||| ||| - // ||| ||| ||| ||| ||| - // ||| ||| ||| ||| ||| - // ||||||| ||||||||| ||| - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // instantiate devices under test - if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma - fma #(P) fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), - .Xe(Xe), .Ye(Ye), .Ze(Ze), - .Xm(Xm), .Ym(Ym), .Zm(Zm), - .XZero, .YZero, .ZZero, .Ss, .Se, - .OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps, - .ASticky); - end - - postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]), - .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), - .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss), - .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE), - .XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE), - .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), - .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, - .FmaASticky(ASticky), .FmaSe(Se), - .FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), - .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes)); - - if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt - fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), - .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero, - .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); - end - - if (TEST === "cmp" | TEST === "all") begin: fcmp - fcmp fcmp (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye, - .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes), - .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes)); - end - if (TEST === "div" | TEST === "sqrt" | TEST === "all") begin: fdivsqrt - fdivsqrt #(P) fdivsqrt(.clk, .reset, .XsE(Xs), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), - .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), - .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), - .XNaNE(XNaN), .YNaNE(YNaN), - .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), - .StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .QeM(DivCalcExp), - .QmM(Quot), - .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), - .Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM), - .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE)); - end - - assign CmpFlg[3:0] = 0; - - // produce clock - always begin - clk = 1; #5; clk = 0; #5; - end - - // Provide reset for divsqrt to reset state to IDLE - // Previous version did not initiate a divide due to missing state - // information. This starts the FSM by putting the fdivsqrt into - // the IDLE state. - initial - begin - #0 reset = 1'b1; - #25 reset = 1'b0; - end - -/////////////////////////////////////////////////////////////////////////////////////////////// - -// ||||| ||| |||||||||| ||||| ||| -// ||||||| ||| ||| ||| ||||||| ||| -// |||| ||| ||| |||||||||| |||| ||| ||| -// |||| ||| ||| ||| ||| |||| ||| ||| -// |||| ||| ||| ||| ||| |||| ||| ||| -// |||| |||||| ||| ||| |||| |||||| - -/////////////////////////////////////////////////////////////////////////////////////////////// - - // Check if the correct answer and result is a NaN - always_comb begin - if(UnitVal === `CVTINTUNIT | UnitVal === `CMPUNIT) begin - // an integer output can't be a NaN - AnsNaN = 1'b0; - ResNaN = 1'b0; - end - else if (UnitVal === `CVTFPUNIT) begin - case (OpCtrlVal[1:0]) - 4'b11: begin // quad - AnsNaN = &Ans[`Q_LEN-2:`NF]&(|Ans[`Q_NF-1:0]); - ResNaN = &Res[`Q_LEN-2:`NF]&(|Res[`Q_NF-1:0]); - end - 4'b01: begin // double - AnsNaN = &Ans[`D_LEN-2:`D_NF]&(|Ans[`D_NF-1:0]); - ResNaN = &Res[`D_LEN-2:`D_NF]&(|Res[`D_NF-1:0]); - end - 4'b00: begin // single - AnsNaN = &Ans[`S_LEN-2:`S_NF]&(|Ans[`S_NF-1:0]); - ResNaN = &Res[`S_LEN-2:`S_NF]&(|Res[`S_NF-1:0]); - end - 4'b10: begin // half - AnsNaN = &Ans[`H_LEN-2:`H_NF]&(|Ans[`H_NF-1:0]); - ResNaN = &Res[`H_LEN-2:`H_NF]&(|Res[`H_NF-1:0]); - end - endcase - end - else begin - case (FmtVal) - 4'b11: begin // quad - AnsNaN = &Ans[`Q_LEN-2:`Q_NF]&(|Ans[`Q_NF-1:0]); - ResNaN = &Res[`Q_LEN-2:`Q_NF]&(|Res[`Q_NF-1:0]); - end - 4'b01: begin // double - AnsNaN = &Ans[`D_LEN-2:`D_NF]&(|Ans[`D_NF-1:0]); - ResNaN = &Res[`D_LEN-2:`D_NF]&(|Res[`D_NF-1:0]); - end - 4'b00: begin // single - AnsNaN = &Ans[`S_LEN-2:`S_NF]&(|Ans[`S_NF-1:0]); - ResNaN = &Res[`S_LEN-2:`S_NF]&(|Res[`S_NF-1:0]); - end - 4'b10: begin // half - AnsNaN = &Ans[`H_LEN-2:`H_NF]&(|Ans[`H_NF-1:0]); - ResNaN = &Res[`H_LEN-2:`H_NF]&(|Res[`H_NF-1:0]); - end - endcase - end - end -always_comb begin - // select the result to check - case (UnitVal) - `FMAUNIT: Res = FpRes; - `DIVUNIT: Res = FpRes; - `CMPUNIT: Res = CmpRes; - `CVTINTUNIT: if(WriteIntVal) Res = IntRes; else Res = FpRes; - `CVTFPUNIT: Res = FpRes; - endcase - - // select the flag to check - case (UnitVal) - `FMAUNIT: ResFlg = Flg; - `DIVUNIT: ResFlg = Flg; - `CMPUNIT: ResFlg = CmpFlg; - `CVTINTUNIT: ResFlg = Flg; - `CVTFPUNIT: ResFlg = Flg; - endcase -end - - logic ResMatch, FlagMatch, CheckNow; - -always @(posedge clk) - OldFDivBusyE = FDivDoneE; - -// check results on falling edge of clk -always @(negedge clk) begin - - - // check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify: - // - the sign of the NaN does not matter for the opperations being tested - // - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter - if (UnitVal !== `CVTFPUNIT & UnitVal !== `CVTINTUNIT) - case (FmtVal) - 4'b11: NaNGood = (((`IEEE754==0)&AnsNaN&(Res === {1'b0, {`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | - (XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) | - (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]})) | - (ZNaN&(Res[`Q_LEN-2:0] === {Z[`Q_LEN-2:`Q_NF],1'b1,Z[`Q_NF-2:0]}))); - 4'b01: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`D_LEN-1:0] === {1'b0, {`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | - (XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | - (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})) | - (ZNaN&(Res[`D_LEN-2:0] === {Z[`D_LEN-2:`D_NF],1'b1,Z[`D_NF-2:0]}))); - 4'b00: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`S_LEN-1:0] === {1'b0, {`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | - (XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | - (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})) | - (ZNaN&(Res[`S_LEN-2:0] === {Z[`S_LEN-2:`S_NF],1'b1,Z[`S_NF-2:0]}))); - 4'b10: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`H_LEN-1:0] === {1'b0, {`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | - (XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | - (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})) | - (ZNaN&(Res[`H_LEN-2:0] === {Z[`H_LEN-2:`H_NF],1'b1,Z[`H_NF-2:0]}))); - endcase - else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format - case (OpCtrlVal[1:0]) - 2'b11: NaNGood = (((`IEEE754==0)&AnsNaN&(Res === {1'b0, {`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | - (AnsNaN&(Res[`Q_LEN-2:0] === Ans[`Q_LEN-2:0])) | - (XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) | - (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]}))); - 2'b01: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`D_LEN-1:0] === {1'b0, {`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | - (AnsNaN&(Res[`D_LEN-2:0] === Ans[`D_LEN-2:0])) | - (XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | - (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]}))); - 2'b00: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`S_LEN-1:0] === {1'b0, {`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | - (AnsNaN&(Res[`S_LEN-2:0] === Ans[`S_LEN-2:0])) | - (XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | - (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]}))); - 2'b10: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`H_LEN-1:0] === {1'b0, {`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | - (AnsNaN&(Res[`H_LEN-2:0] === Ans[`H_LEN-2:0])) | - (XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | - (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]}))); - endcase - else NaNGood = 1'b0; // integers can't be NaNs - - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // ||||||| ||| ||| ||||||| ||||||| ||| ||| - // ||| ||| ||| ||| ||| ||| ||| - // ||| |||||||||| ||||||| ||| |||||| - // ||| ||| ||| ||| ||| ||| ||| - // ||||||| ||| ||| ||||||| ||||||| ||| ||| - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // check if result is correct - // - wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage) - // if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&~((FDivBusyE===1'b1)|DivStart)&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin - assign ResMatch = (Res === Ans | NaNGood | NaNGood === 1'bx); - assign FlagMatch = (ResFlg === AnsFlg | AnsFlg === 5'bx); - assign divsqrtop = OpCtrlVal == `SQRT_OPCTRL | OpCtrlVal == `DIV_OPCTRL; - assign DivDone = OldFDivBusyE & ~FDivBusyE; - - //assign divsqrtop = OpCtrl[TestNum] == `SQRT_OPCTRL | OpCtrl[TestNum] == `DIV_OPCTRL; - assign CheckNow = (DivDone | ~divsqrtop) & (UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT); - if(~(ResMatch & FlagMatch) & CheckNow) begin -// if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&(DivDone | (TEST != "sqrt" & TEST != "div"))&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin - errors += 1; - $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); - $display("Error in %s", Tests[TestNum]); - $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); - $stop; - end - - // TestFloat sets the result to all 1's when there is an invalid result, however in - // http://www.jhauser.us/arithmetic/TestFloat-3/doc/TestFloat-general.html it says - // for an unsigned integer result 0 is also okay - - // Testfloat outputs 800... for both the largest integer values for both positive and negitive numbers but - // the riscv spec specifies 2^31-1 for positive values out of range and NaNs ie 7fff... - else if ((UnitVal === `CVTINTUNIT) & ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[`XLEN-1:0] === (`XLEN)'(0))) | - (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[`XLEN-1:0] === {1'b0, {`XLEN-1{1'b1}}})) | - (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[`XLEN-1:0] === {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | - (~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin - errors += 1; - $display("There is an error in %s", Tests[TestNum]); - $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); - $stop; - end - - // Add extra clock cycles in beginning for fdivsqrt to adequate reset state - if(~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin - repeat (12) - @(posedge clk); - if (reset != 1'b1) - VectorNum += 1; // increment the vector - end + // instantiate devices under test + if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma + fma #(P) fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), + .Xe(Xe), .Ye(Ye), .Ze(Ze), + .Xm(Xm), .Ym(Ym), .Zm(Zm), + .XZero, .YZero, .ZZero, .Ss, .Se, + .OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps, + .ASticky); + end - if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof + postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]), + .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), + .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss), + .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE), + .XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE), + .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), + .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, + .FmaASticky(ASticky), .FmaSe(Se), + .FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), + .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes)); + + if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt + fcvt #(P) fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), + .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero, + .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), + .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); + end - // increment the test - TestNum += 1; + if (TEST === "cmp" | TEST === "all") begin: fcmp + fcmp #(P) fcmp (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye, + .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes), + .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes)); + end + if (TEST === "div" | TEST === "sqrt" | TEST === "all") begin: fdivsqrt + fdivsqrt #(P) fdivsqrt(.clk, .reset, .XsE(Xs), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), + .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), + .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), + .XNaNE(XNaN), .YNaNE(YNaN), + .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), + .StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .QeM(DivCalcExp), + .QmM(Quot), + .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), + .Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM), + .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE)); + end - // clear the vectors - for(int i=0; i<6133248; i++) TestVectors[i] = {`FLEN*4+8{1'bx}}; - // read next files - $readmemh({`PATH, Tests[TestNum]}, TestVectors); + assign CmpFlg[3:0] = 0; - // set the vector index back to 0 - VectorNum = 0; - // incemet the operation if all the rounding modes have been tested - if(FrmNum === 4) OpCtrlNum += 1; - // increment the rounding mode or loop back to rne - if(FrmNum < 4) FrmNum += 1; - else FrmNum = 0; + // produce clock + always begin + clk = 1; #5; clk = 0; #5; + end - // if no more Tests - finish - if(Tests[TestNum] === "") begin - $display("\nAll Tests completed with %d errors\n", errors); - $stop; - end + // Provide reset for divsqrt to reset state to IDLE + // Previous version did not initiate a divide due to missing state + // information. This starts the FSM by putting the fdivsqrt into + // the IDLE state. + initial + begin + #0 reset = 1'b1; + #25 reset = 1'b0; + end + + /////////////////////////////////////////////////////////////////////////////////////////////// - $display("Running %s vectors", Tests[TestNum]); - end - end + // ||||| ||| |||||||||| ||||| ||| + // ||||||| ||| ||| ||| ||||||| ||| + // |||| ||| ||| |||||||||| |||| ||| ||| + // |||| ||| ||| ||| ||| |||| ||| ||| + // |||| ||| ||| ||| ||| |||| ||| ||| + // |||| |||||| ||| ||| |||| |||||| + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // Check if the correct answer and result is a NaN + always_comb begin + if(UnitVal === `CVTINTUNIT | UnitVal === `CMPUNIT) begin + // an integer output can't be a NaN + AnsNaN = 1'b0; + ResNaN = 1'b0; + end + else if (UnitVal === `CVTFPUNIT) begin + case (OpCtrlVal[1:0]) + 4'b11: begin // quad + AnsNaN = &Ans[`Q_LEN-2:`NF]&(|Ans[`Q_NF-1:0]); + ResNaN = &Res[`Q_LEN-2:`NF]&(|Res[`Q_NF-1:0]); + end + 4'b01: begin // double + AnsNaN = &Ans[`D_LEN-2:`D_NF]&(|Ans[`D_NF-1:0]); + ResNaN = &Res[`D_LEN-2:`D_NF]&(|Res[`D_NF-1:0]); + end + 4'b00: begin // single + AnsNaN = &Ans[`S_LEN-2:`S_NF]&(|Ans[`S_NF-1:0]); + ResNaN = &Res[`S_LEN-2:`S_NF]&(|Res[`S_NF-1:0]); + end + 4'b10: begin // half + AnsNaN = &Ans[`H_LEN-2:`H_NF]&(|Ans[`H_NF-1:0]); + ResNaN = &Res[`H_LEN-2:`H_NF]&(|Res[`H_NF-1:0]); + end + endcase + end + else begin + case (FmtVal) + 4'b11: begin // quad + AnsNaN = &Ans[`Q_LEN-2:`Q_NF]&(|Ans[`Q_NF-1:0]); + ResNaN = &Res[`Q_LEN-2:`Q_NF]&(|Res[`Q_NF-1:0]); + end + 4'b01: begin // double + AnsNaN = &Ans[`D_LEN-2:`D_NF]&(|Ans[`D_NF-1:0]); + ResNaN = &Res[`D_LEN-2:`D_NF]&(|Res[`D_NF-1:0]); + end + 4'b00: begin // single + AnsNaN = &Ans[`S_LEN-2:`S_NF]&(|Ans[`S_NF-1:0]); + ResNaN = &Res[`S_LEN-2:`S_NF]&(|Res[`S_NF-1:0]); + end + 4'b10: begin // half + AnsNaN = &Ans[`H_LEN-2:`H_NF]&(|Ans[`H_NF-1:0]); + ResNaN = &Res[`H_LEN-2:`H_NF]&(|Res[`H_NF-1:0]); + end + endcase + end + end + always_comb begin + // select the result to check + case (UnitVal) + `FMAUNIT: Res = FpRes; + `DIVUNIT: Res = FpRes; + `CMPUNIT: Res = CmpRes; + `CVTINTUNIT: if(WriteIntVal) Res = IntRes; else Res = FpRes; + `CVTFPUNIT: Res = FpRes; + endcase + + // select the flag to check + case (UnitVal) + `FMAUNIT: ResFlg = Flg; + `DIVUNIT: ResFlg = Flg; + `CMPUNIT: ResFlg = CmpFlg; + `CVTINTUNIT: ResFlg = Flg; + `CVTFPUNIT: ResFlg = Flg; + endcase + end + + logic ResMatch, FlagMatch, CheckNow; + + always @(posedge clk) + OldFDivBusyE = FDivDoneE; + + // check results on falling edge of clk + always @(negedge clk) begin + + // check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify: + // - the sign of the NaN does not matter for the opperations being tested + // - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter + if (UnitVal !== `CVTFPUNIT & UnitVal !== `CVTINTUNIT) + case (FmtVal) + 4'b11: NaNGood = (((`IEEE754==0)&AnsNaN&(Res === {1'b0, {`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | + (XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) | + (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]})) | + (ZNaN&(Res[`Q_LEN-2:0] === {Z[`Q_LEN-2:`Q_NF],1'b1,Z[`Q_NF-2:0]}))); + 4'b01: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`D_LEN-1:0] === {1'b0, {`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | + (XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | + (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})) | + (ZNaN&(Res[`D_LEN-2:0] === {Z[`D_LEN-2:`D_NF],1'b1,Z[`D_NF-2:0]}))); + 4'b00: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`S_LEN-1:0] === {1'b0, {`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | + (XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | + (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})) | + (ZNaN&(Res[`S_LEN-2:0] === {Z[`S_LEN-2:`S_NF],1'b1,Z[`S_NF-2:0]}))); + 4'b10: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`H_LEN-1:0] === {1'b0, {`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | + (XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | + (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})) | + (ZNaN&(Res[`H_LEN-2:0] === {Z[`H_LEN-2:`H_NF],1'b1,Z[`H_NF-2:0]}))); + endcase + else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format + case (OpCtrlVal[1:0]) + 2'b11: NaNGood = (((`IEEE754==0)&AnsNaN&(Res === {1'b0, {`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) | + (AnsNaN&(Res[`Q_LEN-2:0] === Ans[`Q_LEN-2:0])) | + (XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) | + (YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]}))); + 2'b01: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`D_LEN-1:0] === {1'b0, {`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) | + (AnsNaN&(Res[`D_LEN-2:0] === Ans[`D_LEN-2:0])) | + (XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) | + (YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]}))); + 2'b00: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`S_LEN-1:0] === {1'b0, {`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) | + (AnsNaN&(Res[`S_LEN-2:0] === Ans[`S_LEN-2:0])) | + (XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) | + (YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]}))); + 2'b10: NaNGood = (((`IEEE754==0)&AnsNaN&(Res[`H_LEN-1:0] === {1'b0, {`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) | + (AnsNaN&(Res[`H_LEN-2:0] === Ans[`H_LEN-2:0])) | + (XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) | + (YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]}))); + endcase + else NaNGood = 1'b0; // integers can't be NaNs + + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // ||||||| ||| ||| ||||||| ||||||| ||| ||| + // ||| ||| ||| ||| ||| ||| ||| + // ||| |||||||||| ||||||| ||| |||||| + // ||| ||| ||| ||| ||| ||| ||| + // ||||||| ||| ||| ||||||| ||||||| ||| ||| + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // check if result is correct + // - wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage) + ResMatch = (Res === Ans | NaNGood | NaNGood === 1'bx); + FlagMatch = (ResFlg === AnsFlg | AnsFlg === 5'bx); + divsqrtop = OpCtrlVal == `SQRT_OPCTRL | OpCtrlVal == `DIV_OPCTRL; + assign DivDone = OldFDivBusyE & ~FDivBusyE; + + //assign divsqrtop = OpCtrl[TestNum] == `SQRT_OPCTRL | OpCtrl[TestNum] == `DIV_OPCTRL; + CheckNow = (DivDone | ~divsqrtop) & (UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT); + if(~(ResMatch & FlagMatch) & CheckNow) begin + errors += 1; + $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); + $display("Error in %s", Tests[TestNum]); + $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); + $stop; + end + + // TestFloat sets the result to all 1's when there is an invalid result, however in + // http://www.jhauser.us/arithmetic/TestFloat-3/doc/TestFloat-general.html it says + // for an unsigned integer result 0 is also okay + + // Testfloat outputs 800... for both the largest integer values for both positive and negitive numbers but + // the riscv spec specifies 2^31-1 for positive values out of range and NaNs ie 7fff... + else if ((UnitVal === `CVTINTUNIT) & ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[`XLEN-1:0] === (`XLEN)'(0))) | + (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[`XLEN-1:0] === {1'b0, {`XLEN-1{1'b1}}})) | + (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[`XLEN-1:0] === {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | + (~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin + errors += 1; + $display("There is an error in %s", Tests[TestNum]); + $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); + $stop; + end + + // Add extra clock cycles in beginning for fdivsqrt to adequate reset state + if(~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin + repeat (12) + @(posedge clk); + if (reset != 1'b1) + VectorNum += 1; // increment the vector + end + + if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof + // increment the test + TestNum += 1; + // clear the vectors + for(int i=0; i<6133248; i++) TestVectors[i] = {`FLEN*4+8{1'bx}}; + // read next files + $readmemh({`PATH, Tests[TestNum]}, TestVectors); + // set the vector index back to 0 + VectorNum = 0; + // incemet the operation if all the rounding modes have been tested + if(FrmNum === 4) OpCtrlNum += 1; + // increment the rounding mode or loop back to rne + if(FrmNum < 4) FrmNum += 1; + else FrmNum = 0; + + // if no more Tests - finish + if(Tests[TestNum] === "") begin + $display("\nAll Tests completed with %d errors\n", errors); + $stop; + end + + $display("Running %s vectors", Tests[TestNum]); + end + end endmodule module readvectors ( - input logic clk, - input logic [`FLEN*4+7:0] TestVector, - input logic [`FMTBITS-1:0] ModFmt, - input logic [1:0] Fmt, - input logic [2:0] Unit, - input logic [31:0] VectorNum, - input logic [31:0] TestNum, - input logic [2:0] OpCtrl, - output logic [`FLEN-1:0] Ans, - output logic [`XLEN-1:0] SrcA, - output logic [4:0] AnsFlg, - output logic Xs, Ys, Zs, // sign bits of XYZ - output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) - output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) - output logic XNaN, YNaN, ZNaN, // is XYZ a NaN - output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN - output logic XSubnorm, ZSubnorm, // is XYZ denormalized - output logic XZero, YZero, ZZero, // is XYZ zero - output logic XInf, YInf, ZInf, // is XYZ infinity - output logic XExpMax, - output logic DivStart, - output logic [`FLEN-1:0] X, Y, Z, XPostBox -); + input logic clk, + input logic [`FLEN*4+7:0] TestVector, + input logic [`FMTBITS-1:0] ModFmt, + input logic [1:0] Fmt, + input logic [2:0] Unit, + input logic [31:0] VectorNum, + input logic [31:0] TestNum, + input logic [2:0] OpCtrl, + output logic [`FLEN-1:0] Ans, + output logic [`XLEN-1:0] SrcA, + output logic [4:0] AnsFlg, + output logic Xs, Ys, Zs, // sign bits of XYZ + output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) + output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) + output logic XNaN, YNaN, ZNaN, // is XYZ a NaN + output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN + output logic XSubnorm, ZSubnorm, // is XYZ denormalized + output logic XZero, YZero, ZZero, // is XYZ zero + output logic XInf, YInf, ZInf, // is XYZ infinity + output logic XExpMax, + output logic DivStart, + output logic [`FLEN-1:0] X, Y, Z, XPostBox + ); + +`include "parameter-defs.vh" + localparam Q_LEN = 32'd128; - logic XEn, YEn, ZEn; + logic XEn, YEn, ZEn; - `include "parameter-defs.vh" - - // apply test vectors on rising edge of clk - // Format of vectors Inputs(1/2/3)_AnsFlg - always @(VectorNum) begin - #1; - AnsFlg = TestVector[4:0]; - DivStart = 1'b0; - case (Unit) - `FMAUNIT: - case (Fmt) - 2'b11: begin // quad - if(OpCtrl === `FMA_OPCTRL) begin - X = TestVector[8+4*(`Q_LEN)-1:8+3*(`Q_LEN)]; - Y = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; - Z = TestVector[8+2*(`Q_LEN)-1:8+`Q_LEN]; - end - else begin - X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; - if(OpCtrl === `MUL_OPCTRL) Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; else Y = {2'b0, {`Q_NE-1{1'b1}}, (`Q_NF)'(0)}; - if(OpCtrl === `MUL_OPCTRL) Z = 0; else Z = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; - end - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: if (`D_SUPPORTED)begin // double - if(OpCtrl === `FMA_OPCTRL) begin - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+4*(`D_LEN)-1:8+3*(`D_LEN)]}; - Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; - Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+`D_LEN]}; - end - else begin - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; - if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; - else Y = {{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, (`D_NF)'(0)}; - if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}}; - else Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; - end - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b00: if (`S_SUPPORTED)begin // single - if(OpCtrl === `FMA_OPCTRL) begin - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+4*(`S_LEN)-1:8+3*(`S_LEN)]}; - Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; - Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+`S_LEN]}; - end - else begin - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; - if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]}; - else Y = {{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, (`S_NF)'(0)}; - if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`S_LEN{1'b1}}, {`S_LEN{1'b0}}}; - else Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]}; - end - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // half - if(OpCtrl === `FMA_OPCTRL) begin - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+4*(`H_LEN)-1:8+3*(`H_LEN)]}; - Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; - Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+`H_LEN]}; - end - else begin - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; - if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; - else Y = {{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)}; - if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}}; - else Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; - end - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - endcase - `DIVUNIT: - if(OpCtrl[0]) + // apply test vectors on rising edge of clk + // Format of vectors Inputs(1/2/3)_AnsFlg + always @(VectorNum) begin + #1; + AnsFlg = TestVector[4:0]; + DivStart = 1'b0; + case (Unit) + `FMAUNIT: case (Fmt) 2'b11: begin // quad - X = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; - Ans = TestVector[8+(`Q_LEN-1):8]; - if (~clk) #5; - DivStart = 1'b1; #10 // one clk cycle - DivStart = 1'b0; + if(OpCtrl === `FMA_OPCTRL) begin + X = TestVector[8+4*(`Q_LEN)-1:8+3*(`Q_LEN)]; + Y = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; + Z = TestVector[8+2*(`Q_LEN)-1:8+`Q_LEN]; + end + else begin + X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; + if(OpCtrl === `MUL_OPCTRL) Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; else Y = {2'b0, {`Q_NE-1{1'b1}}, (`Q_NF)'(0)}; + if(OpCtrl === `MUL_OPCTRL) Z = 0; else Z = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; + end + Ans = TestVector[8+(`Q_LEN-1):8]; end 2'b01: if (`D_SUPPORTED)begin // double - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + if(OpCtrl === `FMA_OPCTRL) begin + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+4*(`D_LEN)-1:8+3*(`D_LEN)]}; + Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; + Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+`D_LEN]}; + end + else begin + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; + if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; + else Y = {{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, (`D_NF)'(0)}; + if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}}; + else Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; + end + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; end 2'b00: if (`S_SUPPORTED)begin // single - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + if(OpCtrl === `FMA_OPCTRL) begin + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+4*(`S_LEN)-1:8+3*(`S_LEN)]}; + Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; + Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+`S_LEN]}; + end + else begin + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; + if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]}; + else Y = {{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, (`S_NF)'(0)}; + if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`S_LEN{1'b1}}, {`S_LEN{1'b0}}}; + else Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]}; + end + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; end 2'b10: begin // half - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + if(OpCtrl === `FMA_OPCTRL) begin + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+4*(`H_LEN)-1:8+3*(`H_LEN)]}; + Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; + Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+`H_LEN]}; + end + else begin + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; + if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; + else Y = {{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)}; + if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}}; + else Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; + end + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; end endcase - else + `DIVUNIT: + if(OpCtrl[0]) + case (Fmt) + 2'b11: begin // quad + X = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; + Ans = TestVector[8+(`Q_LEN-1):8]; + if (~clk) #5; + DivStart = 1'b1; #10 // one clk cycle + DivStart = 1'b0; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + 2'b00: if (`S_SUPPORTED)begin // single + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + 2'b10: begin // half + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + endcase + else + case (Fmt) + 2'b11: begin // quad + X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; + Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; + Ans = TestVector[8+(`Q_LEN-1):8]; + if (~clk) #5; + DivStart = 1'b1; #10 // one clk cycle + DivStart = 1'b0; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; + Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + 2'b00: if (`S_SUPPORTED)begin // single + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; + Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + 2'b10: begin // half + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; + Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + if (~clk) #5; + DivStart = 1'b1; #10 + DivStart = 1'b0; + end + endcase + `CMPUNIT: + case (Fmt) + 2'b11: begin // quad + X = TestVector[12+2*(`Q_LEN)-1:12+(`Q_LEN)]; + Y = TestVector[12+(`Q_LEN)-1:12]; + Ans = TestVector[8]; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[12+2*(`D_LEN)-1:12+(`D_LEN)]}; + Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[12+(`D_LEN)-1:12]}; + Ans = TestVector[8]; + end + 2'b00: if (`S_SUPPORTED)begin // single + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[12+2*(`S_LEN)-1:12+(`S_LEN)]}; + Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[12+(`S_LEN)-1:12]}; + Ans = TestVector[8]; + end + 2'b10: begin // half + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[12+2*(`H_LEN)-1:12+(`H_LEN)]}; + Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[12+(`H_LEN)-1:12]}; + Ans = TestVector[8]; + end + endcase + `CVTFPUNIT: case (Fmt) 2'b11: begin // quad - X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)]; - Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; - Ans = TestVector[8+(`Q_LEN-1):8]; - if (~clk) #5; - DivStart = 1'b1; #10 // one clk cycle - DivStart = 1'b0; + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {TestVector[8+`Q_LEN+`Q_LEN-1:8+(`Q_LEN)]}; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {TestVector[8+`Q_LEN+`D_LEN-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b00: begin // single + X = {TestVector[8+`Q_LEN+`S_LEN-1:8+(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b10: begin // half + X = {TestVector[8+`Q_LEN+`H_LEN-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + endcase end 2'b01: if (`D_SUPPORTED)begin // double - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]}; - Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`Q_LEN-1:8+(`Q_LEN)]}; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b01: begin // double + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`D_LEN-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b00: begin // single + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`S_LEN-1:8+(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b10: begin // half + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`H_LEN-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + endcase end 2'b00: if (`S_SUPPORTED)begin // single - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]}; - Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`Q_LEN-1:8+(`Q_LEN)]}; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`D_LEN-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b00: begin // single + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`S_LEN-1:8+(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b10: begin // half + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`H_LEN-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + endcase end 2'b10: begin // half - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]}; - Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - if (~clk) #5; - DivStart = 1'b1; #10 - DivStart = 1'b0; + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`Q_LEN-1:8+(`Q_LEN)]}; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b01: if (`D_SUPPORTED)begin // double + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`D_LEN-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b00: if (`S_SUPPORTED)begin // single + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`S_LEN-1:8+(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b10: begin // half + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`H_LEN-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + endcase end endcase - `CMPUNIT: - case (Fmt) - 2'b11: begin // quad - X = TestVector[12+2*(`Q_LEN)-1:12+(`Q_LEN)]; - Y = TestVector[12+(`Q_LEN)-1:12]; - Ans = TestVector[8]; - end - 2'b01: if (`D_SUPPORTED)begin // double - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[12+2*(`D_LEN)-1:12+(`D_LEN)]}; - Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[12+(`D_LEN)-1:12]}; - Ans = TestVector[8]; - end - 2'b00: if (`S_SUPPORTED)begin // single - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[12+2*(`S_LEN)-1:12+(`S_LEN)]}; - Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[12+(`S_LEN)-1:12]}; - Ans = TestVector[8]; - end - 2'b10: begin // half - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[12+2*(`H_LEN)-1:12+(`H_LEN)]}; - Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[12+(`H_LEN)-1:12]}; - Ans = TestVector[8]; - end - endcase - `CVTFPUNIT: - case (Fmt) - 2'b11: begin // quad - case (OpCtrl[1:0]) - 2'b11: begin // quad - X = {TestVector[8+`Q_LEN+`Q_LEN-1:8+(`Q_LEN)]}; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: if (`D_SUPPORTED)begin // double - X = {TestVector[8+`Q_LEN+`D_LEN-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b00: begin // single - X = {TestVector[8+`Q_LEN+`S_LEN-1:8+(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // half - X = {TestVector[8+`Q_LEN+`H_LEN-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - endcase - end - 2'b01: if (`D_SUPPORTED)begin // double - case (OpCtrl[1:0]) - 2'b11: begin // quad - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`Q_LEN-1:8+(`Q_LEN)]}; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: begin // double - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`D_LEN-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b00: begin // single - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`S_LEN-1:8+(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // half - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`H_LEN-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - endcase - end - 2'b00: if (`S_SUPPORTED)begin // single - case (OpCtrl[1:0]) - 2'b11: begin // quad - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`Q_LEN-1:8+(`Q_LEN)]}; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: if (`D_SUPPORTED)begin // double - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`D_LEN-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b00: begin // single - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`S_LEN-1:8+(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // half - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`H_LEN-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - endcase - end - 2'b10: begin // half - case (OpCtrl[1:0]) - 2'b11: begin // quad - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`Q_LEN-1:8+(`Q_LEN)]}; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: if (`D_SUPPORTED)begin // double - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`D_LEN-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b00: if (`S_SUPPORTED)begin // single - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`S_LEN-1:8+(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // half - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`H_LEN-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - endcase - end - endcase - `CVTINTUNIT: - case (Fmt) - 2'b11: begin // quad - // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) - 2'b11: begin // long -> quad - X = {`FLEN{1'bx}}; - SrcA = TestVector[8+`Q_LEN+`XLEN-1:8+(`Q_LEN)]; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b10: begin // int -> quad - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {`FLEN{1'bx}}; - SrcA = {{`XLEN-32{TestVector[8+`Q_LEN+32-1]}}, TestVector[8+`Q_LEN+32-1:8+(`Q_LEN)]}; - Ans = TestVector[8+(`Q_LEN-1):8]; - end - 2'b01: begin // quad -> long - X = {TestVector[8+`XLEN+`Q_LEN-1:8+(`XLEN)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {TestVector[8+(`XLEN-1):8]}; - end - 2'b00: begin // quad -> int - X = {TestVector[8+32+`Q_LEN-1:8+(32)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b01: if (`D_SUPPORTED)begin // double - // {Int->Fp?, is the integer a long} - casex ({OpCtrl[2:1]}) - 2'b11: begin // long -> double - X = {`FLEN{1'bx}}; - SrcA = TestVector[8+`D_LEN+`XLEN-1:8+(`D_LEN)]; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b10: begin // int -> double - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {`FLEN{1'bx}}; - SrcA = {{`XLEN-32{TestVector[8+`D_LEN+32-1]}}, TestVector[8+`D_LEN+32-1:8+(`D_LEN)]}; - Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; - end - 2'b01: begin // double -> long - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`XLEN+`D_LEN-1:8+(`XLEN)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {TestVector[8+(`XLEN-1):8]}; - end - 2'b00: begin // double -> int - X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+32+`D_LEN-1:8+(32)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b00: if (`S_SUPPORTED)begin // single - // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) - 2'b11: begin // long -> single - X = {`FLEN{1'bx}}; - SrcA = TestVector[8+`S_LEN+`XLEN-1:8+(`S_LEN)]; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b10: begin // int -> single - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {`FLEN{1'bx}}; - SrcA = {{`XLEN-32{TestVector[8+`S_LEN+32-1]}}, TestVector[8+`S_LEN+32-1:8+(`S_LEN)]}; - Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; - end - 2'b01: begin // single -> long - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`XLEN+`S_LEN-1:8+(`XLEN)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {TestVector[8+(`XLEN-1):8]}; - end - 2'b00: begin // single -> int - X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+32+`S_LEN-1:8+(32)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b10: begin // half - // {is the integer a long, is the opperation to an integer} - casex ({OpCtrl[2:1]}) - 2'b11: begin // long -> half - X = {`FLEN{1'bx}}; - SrcA = TestVector[8+`H_LEN+`XLEN-1:8+(`H_LEN)]; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - 2'b10: begin // int -> half - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {`FLEN{1'bx}}; - SrcA = {{`XLEN-32{TestVector[8+`H_LEN+32-1]}}, TestVector[8+`H_LEN+32-1:8+(`H_LEN)]}; - Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; - end - 2'b01: begin // half -> long - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`XLEN+`H_LEN-1:8+(`XLEN)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {TestVector[8+(`XLEN-1):8]}; - end - 2'b00: begin // half -> int - X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+32+`H_LEN-1:8+(32)]}; - SrcA = {`XLEN{1'bx}}; - Ans = {{`XLEN-32{TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; - end - endcase - end - endcase - endcase - end - - assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]); - assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0])); - assign ZEn = (Unit == `FMAUNIT); - - unpack #(P) unpack(.X, .Y, .Z, .Fmt(ModFmt), .Xs, .Ys, .Zs, .Xe, .Ye, .Ze, - .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, - .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, - .XEn, .YEn, .ZEn, .XExpMax, .XPostBox); + `CVTINTUNIT: + case (Fmt) + 2'b11: begin // quad + // {is the integer a long, is the opperation to an integer} + casex ({OpCtrl[2:1]}) + 2'b11: begin // long -> quad + X = {`FLEN{1'bx}}; + SrcA = TestVector[8+`Q_LEN+`XLEN-1:8+(`Q_LEN)]; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b10: begin // int -> quad + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {`FLEN{1'bx}}; + SrcA = {{`XLEN-32{TestVector[8+`Q_LEN+32-1]}}, TestVector[8+`Q_LEN+32-1:8+(`Q_LEN)]}; + Ans = TestVector[8+(`Q_LEN-1):8]; + end + 2'b01: begin // quad -> long + X = {TestVector[8+`XLEN+`Q_LEN-1:8+(`XLEN)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {TestVector[8+(`XLEN-1):8]}; + end + 2'b00: begin // quad -> int + X = {TestVector[8+32+`Q_LEN-1:8+(32)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b01: if (`D_SUPPORTED)begin // double + // {Int->Fp?, is the integer a long} + casex ({OpCtrl[2:1]}) + 2'b11: begin // long -> double + X = {`FLEN{1'bx}}; + SrcA = TestVector[8+`D_LEN+`XLEN-1:8+(`D_LEN)]; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b10: begin // int -> double + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {`FLEN{1'bx}}; + SrcA = {{`XLEN-32{TestVector[8+`D_LEN+32-1]}}, TestVector[8+`D_LEN+32-1:8+(`D_LEN)]}; + Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]}; + end + 2'b01: begin // double -> long + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`XLEN+`D_LEN-1:8+(`XLEN)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {TestVector[8+(`XLEN-1):8]}; + end + 2'b00: begin // double -> int + X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+32+`D_LEN-1:8+(32)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b00: if (`S_SUPPORTED)begin // single + // {is the integer a long, is the opperation to an integer} + casex ({OpCtrl[2:1]}) + 2'b11: begin // long -> single + X = {`FLEN{1'bx}}; + SrcA = TestVector[8+`S_LEN+`XLEN-1:8+(`S_LEN)]; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b10: begin // int -> single + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {`FLEN{1'bx}}; + SrcA = {{`XLEN-32{TestVector[8+`S_LEN+32-1]}}, TestVector[8+`S_LEN+32-1:8+(`S_LEN)]}; + Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]}; + end + 2'b01: begin // single -> long + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`XLEN+`S_LEN-1:8+(`XLEN)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {TestVector[8+(`XLEN-1):8]}; + end + 2'b00: begin // single -> int + X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+32+`S_LEN-1:8+(32)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {{`XLEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b10: begin // half + // {is the integer a long, is the opperation to an integer} + casex ({OpCtrl[2:1]}) + 2'b11: begin // long -> half + X = {`FLEN{1'bx}}; + SrcA = TestVector[8+`H_LEN+`XLEN-1:8+(`H_LEN)]; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + 2'b10: begin // int -> half + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {`FLEN{1'bx}}; + SrcA = {{`XLEN-32{TestVector[8+`H_LEN+32-1]}}, TestVector[8+`H_LEN+32-1:8+(`H_LEN)]}; + Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]}; + end + 2'b01: begin // half -> long + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`XLEN+`H_LEN-1:8+(`XLEN)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {TestVector[8+(`XLEN-1):8]}; + end + 2'b00: begin // half -> int + X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+32+`H_LEN-1:8+(32)]}; + SrcA = {`XLEN{1'bx}}; + Ans = {{`XLEN-32{TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; + end + endcase + end + endcase + endcase + end + + assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]); + assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0])); + assign ZEn = (Unit == `FMAUNIT); + + unpack #(P) unpack(.X, .Y, .Z, .Fmt(ModFmt), .Xs, .Ys, .Zs, .Xe, .Ye, .Ze, + .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, + .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, + .XEn, .YEn, .ZEn, .XExpMax, .XPostBox); endmodule diff --git a/testbench/testbench-linux-imperas.sv b/testbench/testbench-linux-imperas.sv index 223e3529b..79b354cb0 100644 --- a/testbench/testbench-linux-imperas.sv +++ b/testbench/testbench-linux-imperas.sv @@ -30,7 +30,7 @@ // `define USE_IMPERAS_DV `ifdef USE_IMPERAS_DV - `include "rvvi/imperasDV.svh" + `include "idv/idv.svh" `endif `define DEBUG_TRACE 0 @@ -55,7 +55,7 @@ module testbench; `ifdef USE_IMPERAS_DV - import rvviPkg::*; + import idvPkg::*; import rvviApiPkg::*; import idvApiPkg::*; `endif @@ -302,7 +302,7 @@ module testbench; initial begin int iter; #1; - MAX_ERRS = 3; + IDV_MAX_ERRS = 3; // Initialize REF (do this before initializing the DUT) if (!rvviVersionCheck(RVVI_API_VERSION)) begin diff --git a/testbench/testbench-linux.sv b/testbench/testbench-linux.sv index 908660ffe..5c83aca29 100644 --- a/testbench/testbench-linux.sv +++ b/testbench/testbench-linux.sv @@ -24,7 +24,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" +`include "config.vh" +import cvw::*; `define DEBUG_TRACE 0 // Debug Levels @@ -47,12 +48,7 @@ module testbench; parameter NO_SPOOFING = 0; - - - - - - +`include "parameter-defs.vh" //////////////////////////////////////////////////////////////////////////////////// @@ -85,40 +81,40 @@ module testbench; integer TokenIndex``STAGE; \ integer MarkerIndex``STAGE; \ integer NumCSR``STAGE; \ - logic [`XLEN-1:0] ExpectedPC``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 [`XLEN-1:0] ExpectedRegValue``STAGE; \ - logic [`XLEN-1:0] ExpectedIEUAdr``STAGE, ExpectedMemReadData``STAGE, ExpectedMemWriteData``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 [`XLEN-1:0] ExpectedCSRArrayValue``STAGE[10:0]; // *** might be redundant? + 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 [`AHBW-1:0] readDataExpected; + logic [P.AHBW-1:0] readDataExpected; // W-stage expected values logic checkInstrW; - logic [`XLEN-1:0] ExpectedPCW; + logic [P.XLEN-1:0] ExpectedPCW; logic [31:0] ExpectedInstrW; string textW; string RegWriteW; integer ExpectedRegAdrW; - logic [`XLEN-1:0] ExpectedRegValueW; + logic [P.XLEN-1:0] ExpectedRegValueW; string MemOpW; - logic [`XLEN-1:0] ExpectedIEUAdrW, ExpectedMemReadDataW, ExpectedMemWriteDataW; + logic [P.XLEN-1:0] ExpectedIEUAdrW, ExpectedMemReadDataW, ExpectedMemWriteDataW; integer NumCSRW; string ExpectedCSRArrayW[10:0]; - logic [`XLEN-1:0] ExpectedCSRArrayValueW[10:0]; - logic [`XLEN-1:0] ExpectedIntType; + logic [P.XLEN-1:0] ExpectedCSRArrayValueW[10:0]; + logic [P.XLEN-1:0] ExpectedIntType; integer NumCSRWIndex; integer NumCSRPostWIndex; - logic [`XLEN-1:0] InstrCountW; + logic [P.XLEN-1:0] InstrCountW; // ========== Interrupt parsing & spoofing ========== string interrupt; string interruptLine; @@ -132,7 +128,7 @@ module testbench; string interruptDesc; integer NextMIPexpected, NextSIPexpected; integer NextMepcExpected; - logic [`XLEN-1:0] AttemptedInstructionCount; + logic [P.XLEN-1:0] AttemptedInstructionCount; // ========== Misc Aliases ========== `define RF dut.core.ieu.dp.regf.rf `define PC dut.core.ifu.pcreg.q @@ -238,14 +234,14 @@ module testbench; initial begin reset_ext <= 1; # 22; reset_ext <= 0; end always begin clk <= 1; # 5; clk <= 0; # 5; end // Wally Interface - logic [`AHBW-1:0] HRDATAEXT; + logic [P.AHBW-1:0] HRDATAEXT; logic HREADYEXT, HRESPEXT; logic HCLK, HRESETn; logic HREADY; logic HSELEXT; - logic [`PA_BITS-1:0] HADDR; - logic [`AHBW-1:0] HWDATA; - logic [`XLEN/8-1:0] HWSTRB; + 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; @@ -268,7 +264,7 @@ module testbench; assign UARTSin = 1; // Wally - wallypipelinedsoc dut(.clk, .reset, .reset_ext, + wallypipelinedsoc #(P) dut(.clk, .reset, .reset_ext, .HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, @@ -278,18 +274,18 @@ module testbench; // W-stage hardware not needed by Wally itself parameter nop = 'h13; - logic [`XLEN-1:0] PCW; + logic [P.XLEN-1:0] PCW; logic [31:0] InstrW; logic InstrValidW; - logic [`XLEN-1:0] IEUAdrW, WriteDataW; + logic [P.XLEN-1:0] IEUAdrW, WriteDataW; logic TrapW; `define FLUSHW dut.core.FlushW `define STALLW dut.core.StallW - flopenrc #(`XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW); + flopenrc #(P.XLEN) PCWReg(clk, reset, `FLUSHW, ~`STALLW, `PCM, PCW); flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW); flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW); - flopenrc #(`XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW); - flopenrc #(`XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW); + 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); @@ -365,29 +361,29 @@ module testbench; end genvar i; - `INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1); - `INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0); - `INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(MEDELEG, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(MIDELEG, [`XLEN-1:0]); + `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, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(SCAUSE, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(MEPC, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(SEPC, [`XLEN-1:0]); + `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, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(SSCRATCH, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(MTVEC, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(STVEC, [`XLEN-1:0]); - `INIT_CHECKPOINT_VAL(SATP, [`XLEN-1: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],`PLIC_NUM_SRC,1); - `MAKE_CHECKPOINT_INIT_SIGNAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:0],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 @@ -402,8 +398,8 @@ module testbench; `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, [`XLEN-1:0],0,0); - `MAKE_CHECKPOINT_INIT_SIGNAL(SSTATUS, [`XLEN-1:0],0,0); + `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 @@ -458,7 +454,7 @@ module testbench; 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][`PLIC_NUM_SRC:1],initPLIC_INT_ENABLE[0][`PLIC_NUM_SRC:1]}; // would need to expand into a generate loop to cover an arbitrary number of contexts + 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; @@ -789,7 +785,7 @@ module testbench; //////////////////////////////// Extra Features /////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Function Tracking - FunctionName FunctionName(.reset(reset), + FunctionName #(P) FunctionName(.reset(reset), .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); @@ -814,12 +810,12 @@ module testbench; * explanation of the below algorithm. */ logic SvMode, PTE_R, PTE_X; - logic [`XLEN-1:0] SATP, PTE; + logic [P.XLEN-1:0] SATP, PTE; logic [55:0] BaseAdr, PAdr; logic [8:0] VPN [2:0]; logic [11:0] Offset; - function logic [`XLEN-1:0] adrTranslator( - input logic [`XLEN-1:0] adrIn); + function logic [P.XLEN-1:0] adrTranslator( + input logic [P.XLEN-1:0] adrIn); begin int i; // Grab the SATP register from privileged unit diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 9712693ec..4cab1a105 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -25,136 +25,40 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" +`include "config.vh" `include "tests.vh" -`define PrintHPMCounters 0 -`define BPRED_LOGGER 0 -`define I_CACHE_ADDR_LOGGER 0 -`define D_CACHE_ADDR_LOGGER 0 +import cvw::*; module testbench; + /* verilator lint_off WIDTHTRUNC */ + /* verilator lint_off WIDTHEXPAND */ parameter DEBUG=0; parameter TEST="none"; + parameter PrintHPMCounters=0; + parameter BPRED_LOGGER=0; + parameter I_CACHE_ADDR_LOGGER=0; + parameter D_CACHE_ADDR_LOGGER=0; +`include "parameter-defs.vh" + logic clk; logic reset_ext, reset; + logic ResetMem; - parameter SIGNATURESIZE = 5000000; - - int test, i, errors, totalerrors; - logic [31:0] sig32[0:SIGNATURESIZE]; - logic [`XLEN-1:0] signature[0:SIGNATURESIZE]; - logic [`XLEN-1:0] testadr, testadrNoBase; - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - - string tests[]; - logic [3:0] dummy; - - logic [`AHBW-1:0] HRDATAEXT; - logic HREADYEXT, HRESPEXT; - logic [`PA_BITS-1:0] HADDR; - logic [`AHBW-1:0] HWDATA; - logic [`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 HCLK, HRESETn; - logic [`XLEN-1:0] PCW; - - string ProgramAddrMapFile, ProgramLabelMapFile; - integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 }; - - logic DCacheFlushDone, DCacheFlushStart; - logic riscofTest; - logic StartSample, EndSample; - - flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); - flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); - - // check assertions for a legal configuration - riscvassertions riscvassertions(); - - // pick tests based on modes supported - initial begin - $display("TEST is %s", TEST); - //tests = '{}; - if (`XLEN == 64) begin // RV64 - case (TEST) - "arch64i": tests = arch64i; - "arch64priv": tests = arch64priv; - "arch64c": if (`C_SUPPORTED) - if (`ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv}; - else tests = {arch64c}; - "arch64m": if (`M_SUPPORTED) tests = arch64m; - "arch64f": if (`F_SUPPORTED) tests = arch64f; - "arch64d": if (`D_SUPPORTED) tests = arch64d; - "arch64f_fma": if (`F_SUPPORTED) tests = arch64f_fma; - "arch64d_fma": if (`D_SUPPORTED) tests = arch64d_fma; - "arch64zi": if (`ZIFENCEI_SUPPORTED) tests = arch64zi; - "imperas64i": tests = imperas64i; - "imperas64f": if (`F_SUPPORTED) tests = imperas64f; - "imperas64d": if (`D_SUPPORTED) tests = imperas64d; - "imperas64m": if (`M_SUPPORTED) tests = imperas64m; - "wally64a": if (`A_SUPPORTED) tests = wally64a; - "imperas64c": if (`C_SUPPORTED) tests = imperas64c; - else tests = imperas64iNOc; - "custom": tests = custom; - "wally64i": tests = wally64i; - "wally64priv": tests = wally64priv; - "wally64periph": tests = wally64periph; - "coremark": tests = coremark; - "fpga": tests = fpga; - "ahb" : tests = ahb; - "coverage64gc" : tests = coverage64gc; - "arch64zba": if (`ZBA_SUPPORTED) tests = arch64zba; - "arch64zbb": if (`ZBB_SUPPORTED) tests = arch64zbb; - "arch64zbc": if (`ZBC_SUPPORTED) tests = arch64zbc; - "arch64zbs": if (`ZBS_SUPPORTED) tests = arch64zbs; - endcase - end else begin // RV32 - case (TEST) - "arch32i": tests = arch32i; - "arch32priv": tests = arch32priv; - "arch32c": if (`C_SUPPORTED) - if (`ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv}; - else tests = {arch32c}; - "arch32m": if (`M_SUPPORTED) tests = arch32m; - "arch32f": if (`F_SUPPORTED) tests = arch32f; - "arch32d": if (`D_SUPPORTED) tests = arch32d; - "arch32f_fma": if (`F_SUPPORTED) tests = arch32f_fma; - "arch32d_fma": if (`D_SUPPORTED) tests = arch32d_fma; - "arch32zi": if (`ZIFENCEI_SUPPORTED) tests = arch32zi; - "imperas32i": tests = imperas32i; - "imperas32f": if (`F_SUPPORTED) tests = imperas32f; - "imperas32m": if (`M_SUPPORTED) tests = imperas32m; - "wally32a": if (`A_SUPPORTED) tests = wally32a; - "imperas32c": if (`C_SUPPORTED) tests = imperas32c; - else tests = imperas32iNOc; - "wally32i": tests = wally32i; - "wally32e": tests = wally32e; - "wally32priv": tests = wally32priv; - "wally32periph": tests = wally32periph; - "embench": tests = embench; - "coremark": tests = coremark; - "arch32zba": if (`ZBA_SUPPORTED) tests = arch32zba; - "arch32zbb": if (`ZBB_SUPPORTED) tests = arch32zbb; - "arch32zbc": if (`ZBC_SUPPORTED) tests = arch32zbc; - "arch32zbs": if (`ZBS_SUPPORTED) tests = arch32zbs; - endcase - end - if (tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); - $stop; - end - end - - string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile; - integer outputFilePointer; + // DUT signals + logic [P.AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + 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 HCLK, HRESETn; logic [31:0] GPIOIN, GPIOOUT, GPIOEN; logic UARTSin, UARTSout; @@ -169,28 +73,315 @@ module testbench; logic HREADY; logic HSELEXT; + - logic InitializingMemories; - integer ResetCount, ResetThreshold; - logic InReset; - logic BeginSample; + string ProgramAddrMapFile, ProgramLabelMapFile; + integer ProgramAddrLabelArray [string]; + + int test, i, errors, totalerrors; + + string outputfile; + integer outputFilePointer; + + string tests[]; + logic DCacheFlushDone, DCacheFlushStart; + logic riscofTest; + logic Validate; + logic SelectTest; + + + // pick tests based on modes supported + initial begin + $display("TEST is %s", TEST); + //tests = '{}; + if (P.XLEN == 64) begin // RV64 + case (TEST) + "arch64i": tests = arch64i; + "arch64priv": tests = arch64priv; + "arch64c": if (P.C_SUPPORTED) + if (P.ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv}; + else tests = {arch64c}; + "arch64m": if (P.M_SUPPORTED) tests = arch64m; + "arch64f": if (P.F_SUPPORTED) tests = arch64f; + "arch64d": if (P.D_SUPPORTED) tests = arch64d; + "arch64f_fma": if (P.F_SUPPORTED) tests = arch64f_fma; + "arch64d_fma": if (P.D_SUPPORTED) tests = arch64d_fma; + "arch64zi": if (P.ZIFENCEI_SUPPORTED) tests = arch64zi; + "imperas64i": tests = imperas64i; + "imperas64f": if (P.F_SUPPORTED) tests = imperas64f; + "imperas64d": if (P.D_SUPPORTED) tests = imperas64d; + "imperas64m": if (P.M_SUPPORTED) tests = imperas64m; + "wally64a": if (P.A_SUPPORTED) tests = wally64a; + "imperas64c": if (P.C_SUPPORTED) tests = imperas64c; + else tests = imperas64iNOc; + "custom": tests = custom; + "wally64i": tests = wally64i; + "wally64priv": tests = wally64priv; + "wally64periph": tests = wally64periph; + "coremark": tests = coremark; + "fpga": tests = fpga; + "ahb" : tests = ahb; + "coverage64gc" : tests = coverage64gc; + "arch64zba": if (P.ZBA_SUPPORTED) tests = arch64zba; + "arch64zbb": if (P.ZBB_SUPPORTED) tests = arch64zbb; + "arch64zbc": if (P.ZBC_SUPPORTED) tests = arch64zbc; + "arch64zbs": if (P.ZBS_SUPPORTED) tests = arch64zbs; + endcase + end else begin // RV32 + case (TEST) + "arch32i": tests = arch32i; + "arch32priv": tests = arch32priv; + "arch32c": if (P.C_SUPPORTED) + if (P.ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv}; + else tests = {arch32c}; + "arch32m": if (P.M_SUPPORTED) tests = arch32m; + "arch32f": if (P.F_SUPPORTED) tests = arch32f; + "arch32d": if (P.D_SUPPORTED) tests = arch32d; + "arch32f_fma": if (P.F_SUPPORTED) tests = arch32f_fma; + "arch32d_fma": if (P.D_SUPPORTED) tests = arch32d_fma; + "arch32zi": if (P.ZIFENCEI_SUPPORTED) tests = arch32zi; + "imperas32i": tests = imperas32i; + "imperas32f": if (P.F_SUPPORTED) tests = imperas32f; + "imperas32m": if (P.M_SUPPORTED) tests = imperas32m; + "wally32a": if (P.A_SUPPORTED) tests = wally32a; + "imperas32c": if (P.C_SUPPORTED) tests = imperas32c; + else tests = imperas32iNOc; + "wally32i": tests = wally32i; + "wally32e": tests = wally32e; + "wally32priv": tests = wally32priv; + "wally32periph": tests = wally32periph; + "embench": tests = embench; + "coremark": tests = coremark; + "arch32zba": if (P.ZBA_SUPPORTED) tests = arch32zba; + "arch32zbb": if (P.ZBB_SUPPORTED) tests = arch32zbb; + "arch32zbc": if (P.ZBC_SUPPORTED) tests = arch32zbc; + "arch32zbs": if (P.ZBS_SUPPORTED) tests = arch32zbs; + endcase + end + if (tests.size() == 0) begin + $display("TEST %s not supported in this configuration", TEST); + $stop; + end + end // initial begin + + // Model the testbench as an fsm. + // Do this in parts so it easier to verify + // part 1: build a version which echos the same behavior as the below code, but does not drive anything + // part 2: drive some of the controls + // part 3: drive all logic and remove old inital and always @ negedge clk block + + typedef enum logic [3:0]{STATE_TESTBENCH_RESET, + STATE_INIT_TEST, + STATE_RESET_MEMORIES, + STATE_RESET_MEMORIES2, + STATE_LOAD_MEMORIES, + STATE_RESET_TEST, + STATE_RUN_TEST, + STATE_CHECK_TEST, + STATE_CHECK_TEST_WAIT, + STATE_VALIDATE, + STATE_INCR_TEST} statetype; + statetype CurrState, NextState; + logic TestBenchReset; + logic [2:0] ResetCount, ResetThreshold; + logic LoadMem; + logic ResetCntEn; + logic ResetCntRst; + + string signame, memfilename, pathname; + integer begin_signature_addr; + + assign ResetThreshold = 3'd5; + + initial begin + TestBenchReset = 1; + # 100; + TestBenchReset = 0; + end + + always_ff @(posedge clk) + if (TestBenchReset) CurrState <= #1 STATE_TESTBENCH_RESET; + else CurrState <= #1 NextState; + + // fsm next state logic + always_comb begin + // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests + // and tests[0] == "2" refers to WallyRiscvArchTests + riscofTest = tests[0] == "1" | tests[0] == "2"; + pathname = tvpaths[tests[0].atoi()]; + + case(CurrState) + STATE_TESTBENCH_RESET: NextState = STATE_INIT_TEST; + STATE_INIT_TEST: NextState = STATE_RESET_MEMORIES; + STATE_RESET_MEMORIES: NextState = STATE_RESET_MEMORIES2; + STATE_RESET_MEMORIES2: NextState = STATE_LOAD_MEMORIES; // Give the reset enough time to ensure the bus is reset before loading the memories. + STATE_LOAD_MEMORIES: NextState = STATE_RESET_TEST; + STATE_RESET_TEST: if(ResetCount < ResetThreshold) NextState = STATE_RESET_TEST; + else NextState = STATE_RUN_TEST; + STATE_RUN_TEST: if(DCacheFlushStart) NextState = STATE_CHECK_TEST; + else NextState = STATE_RUN_TEST; + STATE_CHECK_TEST: if (DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_CHECK_TEST_WAIT: if(DCacheFlushDone) NextState = STATE_VALIDATE; + else NextState = STATE_CHECK_TEST_WAIT; + STATE_VALIDATE: NextState = STATE_INIT_TEST; + STATE_INCR_TEST: NextState = STATE_INIT_TEST; + default: NextState = STATE_TESTBENCH_RESET; + endcase + end // always_comb + // fsm output control logic + assign reset_ext = CurrState == STATE_TESTBENCH_RESET | CurrState == STATE_INIT_TEST | + CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2 | + CurrState == STATE_LOAD_MEMORIES | CurrState ==STATE_RESET_TEST; + // this initialization is very expensive, only do it for coremark. + assign ResetMem = (CurrState == STATE_RESET_MEMORIES | CurrState == STATE_RESET_MEMORIES2) & TEST == "coremark"; + assign LoadMem = CurrState == STATE_LOAD_MEMORIES; + assign ResetCntRst = CurrState == STATE_INIT_TEST; + assign ResetCntEn = CurrState == STATE_RESET_TEST; + assign Validate = CurrState == STATE_VALIDATE; + assign SelectTest = CurrState == STATE_INIT_TEST; + + // fsm reset counter + counter #(3) RstCounter(clk, ResetCntRst, ResetCntEn, ResetCount); + + //////////////////////////////////////////////////////////////////////////////// + // Find the test vector files and populate the PC to function label converter + //////////////////////////////////////////////////////////////////////////////// + logic [P.XLEN-1:0] testadr; + assign begin_signature_addr = ProgramAddrLabelArray["begin_signature"]; + always @(posedge clk) begin + if(SelectTest) begin + if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"}; + else memfilename = {pathname, tests[test], ".elf.memfile"}; + if (riscofTest) begin + ProgramAddrMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.addr"}; + ProgramLabelMapFile = {pathname, tests[test], "/ref/ref.elf.objdump.lab"}; + end else begin + ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; + ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; + end + // declare memory labels that interest us, the updateProgramAddrLabelArray task will find + // the addr of each label and fill the array. To expand, add more elements to this array + // and initialize them to zero (also initilaize them to zero at the start of the next test) + if(!P.FPGA) begin + updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray); + end + end + + //////////////////////////////////////////////////////////////////////////////// + // Verify the test ran correctly by checking the memory against a known signature. + //////////////////////////////////////////////////////////////////////////////// + if(TestBenchReset) test = 1; + if (TEST == "coremark") + if (dut.core.EcallFaultM) begin + $display("Benchmark: coremark is done."); + $stop; + end + if(Validate) begin + if (TEST == "embench") begin + // Writes contents of begin_signature to .sim.output file + // this contains instret and cycles for start and end of test run, used by embench + // python speed script to calculate embench speed score. + // also, begin_signature contains the results of the self checking mechanism, + // which will be read by the python script for error checking + $display("Embench Benchmark: %s is done.", tests[test]); + if (riscofTest) outputfile = {pathname, tests[test], "/ref/ref.sim.output"}; + else outputfile = {pathname, tests[test], ".sim.output"}; + outputFilePointer = $fopen(outputfile, "w"); + i = 0; + testadr = ($unsigned(begin_signature_addr))/(P.XLEN/8); + while ($unsigned(i) < $unsigned(5'd5)) begin + $fdisplayh(outputFilePointer, DCacheFlushFSM.ShadowRAM[testadr+i]); + i = i + 1; + end + $fclose(outputFilePointer); + $display("Embench Benchmark: created output file: %s", outputfile); + end else if (TEST == "coverage64gc") begin + $display("Coverage tests don't get checked"); + end else begin + // for tests with no self checking mechanism, read .signature.output file and compare to check for errors + // clear signature to prevent contamination from previous tests + end + + if (!begin_signature_addr) + $display("begin_signature addr not found in %s", ProgramLabelMapFile); + else if (TEST != "embench") begin // *** quick hack for embench. need a better long term solution + CheckSignature(pathname, tests[test], riscofTest, begin_signature_addr, errors); + end + if(errors > 0) totalerrors = totalerrors + 1; + test = test + 1; // *** this probably needs to be moved. + if (test == tests.size()) begin + if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); + else $display("FAIL: %d test programs had errors", totalerrors); + $stop; + end + end + end + + + //////////////////////////////////////////////////////////////////////////////// + // Some memories are not reset, but should be zeros or set to some initial value for simulation + //////////////////////////////////////////////////////////////////////////////// + integer adrindex; + always @(posedge clk) begin + if (ResetMem) // program memory is sometimes reset + if (P.UNCORE_RAM_SUPPORTED) + for (adrindex=0; adrindex<(P.UNCORE_RAM_RANGE>>1+(P.XLEN/32)); adrindex = adrindex+1) + dut.uncore.uncore.ram.ram.memory.RAM[adrindex] = '0; + if(reset) begin // branch predictor must always be reset + if (P.BPRED_SUPPORTED) begin + // local history only + if (P.BPRED_TYPE == BP_LOCAL_AHEAD | P.BPRED_TYPE == BP_LOCAL_REPAIR) + for(adrindex = 0; adrindex < 2**P.BPRED_NUM_LHR; adrindex++) + dut.core.ifu.bpred.bpred.Predictor.DirPredictor.BHT.mem[adrindex] = 0; + for(adrindex = 0; adrindex < 2**P.BTB_SIZE; adrindex++) + dut.core.ifu.bpred.bpred.TargetPredictor.memory.mem[adrindex] = 0; + for(adrindex = 0; adrindex < 2**P.BPRED_SIZE; adrindex++) + dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PHT.mem[adrindex] = 0; + end + end + end + + //////////////////////////////////////////////////////////////////////////////// + // load memories with program image + //////////////////////////////////////////////////////////////////////////////// + always @(posedge clk) begin + if (LoadMem) begin + if (P.FPGA) begin + string romfilename, sdcfilename; + romfilename = {"../tests/custom/fpga-test-sdc/bin/fpga-test-sdc.memfile"}; + sdcfilename = {"../testbench/sdc/ramdisk2.hex"}; + $readmemh(romfilename, dut.uncore.uncore.bootrom.bootrom.memory.ROM); + $readmemh(sdcfilename, sdcard.sdcard.FLASHmem); + // shorten sdc timers for simulation + dut.uncore.uncore.sdc.SDC.LimitTimers = 1; + end + else if (P.IROM_SUPPORTED) $readmemh(memfilename, dut.core.ifu.irom.irom.rom.ROM); + else if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); + if (P.DTIM_SUPPORTED) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); + $display("Read memfile %s", memfilename); + end + end + + //////////////////////////////////////////////////////////////////////////////// + // Actual hardware + //////////////////////////////////////////////////////////////////////////////// + // instantiate device to be tested assign GPIOIN = 0; assign UARTSin = 1; - if(`EXT_MEM_SUPPORTED) begin - ram_ahb #(.BASE(`EXT_MEM_BASE), .RANGE(`EXT_MEM_RANGE)) + if(P.EXT_MEM_SUPPORTED) begin + ram_ahb #(.BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), - .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, - .HWSTRB); + .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB); end else begin assign HREADYEXT = 1; - assign HRESPEXT = 0; - assign HRDATAEXT = 0; + assign {HRESPEXT, HRDATAEXT} = '0; end - if(`FPGA) begin : sdcard + if(P.FPGA) begin : sdcard sdModel sdcard (.sdClk(SDCCLK), .cmd(SDCCmd), @@ -204,319 +395,48 @@ module testbench; assign SDCDat = '0; end - wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, - .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, - .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, - .UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK); + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, + .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, + .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, + .UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK); + + // generate clock to sequence tests + always begin + clk = 1; # 5; clk = 0; # 5; + end + + //////////////////////////////////////////////////////////////////////////////// + // Support logic + //////////////////////////////////////////////////////////////////////////////// + + watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck + riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration + loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) + loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename); + + // track the current function or global label + if (DEBUG == 1 | (PrintHPMCounters & P.ZICNTR_SUPPORTED)) begin : FunctionName + FunctionName #(P) FunctionName(.reset(reset_ext | TestBenchReset), + .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); + end // Track names of instructions + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, dut.core.ifu.InstrRawF[31:0], dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); - // initialize tests - localparam MemStartAddr = 0; - localparam MemEndAddr = `UNCORE_RAM_RANGE>>1+(`XLEN/32); - - initial - begin - ResetCount = 0; - ResetThreshold = 2; - InReset = 1; - test = 1; - totalerrors = 0; - testadr = 0; - testadrNoBase = 0; - // riscof tests have a different signature, tests[0] == "1" refers to RiscvArchTests - // and tests[0] == "2" refers to WallyRiscvArchTests - riscofTest = tests[0] == "1" | tests[0] == "2"; - // fill memory with defined values to reduce Xs in simulation - // Quick note the memory will need to be initialized. The C library does not - // guarantee the initialized reads. For example a strcmp can read 6 byte - // strings, but uses a load double to read them in. If the last 2 bytes are - // not initialized the compare results in an 'x' which propagates through - // the design. - if (TEST == "coremark") - for (i=MemStartAddr; i= 4 & sig32[i-4] === 'bx) begin + if (i == 4) begin + i = SIGNATURESIZE+1; // flag empty file + $display(" Error: empty test file"); + end else i = SIGNATURESIZE; // skip over the rest of the x's for efficiency end end - end - // check for hang up. - logic [`XLEN-1:0] OldPCW; - integer WatchDogTimerCount; - localparam WatchDogTimerThreshold = 1000000; - logic WatchDogTimeOut; - always_ff @(posedge clk) begin - OldPCW <= PCW; - if(OldPCW == PCW) WatchDogTimerCount = WatchDogTimerCount + 1'b1; - else WatchDogTimerCount = '0; - end + // Check errors + errors = (i == SIGNATURESIZE+1); // error if file is empty + i = 0; + testadr = ($unsigned(begin_signature_addr))/(P.XLEN/8); + testadrNoBase = (begin_signature_addr - P.UNCORE_RAM_BASE)/(P.XLEN/8); + /* verilator lint_off INFINITELOOP */ + while (signature[i] !== 'bx) begin + logic [P.XLEN-1:0] sig; + if (P.DTIM_SUPPORTED) sig = testbench.dut.core.lsu.dtim.dtim.ram.RAM[testadrNoBase+i]; + else if (P.UNCORE_RAM_SUPPORTED) sig = testbench.dut.uncore.uncore.ram.ram.memory.RAM[testadrNoBase+i]; + //$display("signature[%h] = %h sig = %h", i, signature[i], sig); + if (signature[i] !== sig & (signature[i] !== testbench.DCacheFlushFSM.ShadowRAM[testadr+i])) begin + errors = errors+1; + $display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DTIM_SUPPORTED) = %h, signature = %h", + TestName, i, (testadr+i)*(P.XLEN/8), testbench.DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]); + $stop; //***debug + end + i = i + 1; + end + /* verilator lint_on INFINITELOOP */ + if (errors == 0) begin + $display("%s succeeded. Brilliant!!!", TestName); + end else begin + $display("%s failed with %d errors. :(", TestName, errors); + //totalerrors = totalerrors+1; + end - always_comb begin - WatchDogTimeOut = WatchDogTimerCount >= WatchDogTimerThreshold; - if(WatchDogTimeOut) begin - $display("FAILURE: Watch Dog Time Out triggered. PCW stuck at %x for more than %d cycles", PCW, WatchDogTimerCount); - $stop; - end - end + endtask // + /* verilator lint_on WIDTHTRUNC */ + /* verilator lint_on WIDTHEXPAND */ + endmodule /* verilator lint_on STMTDLY */ /* verilator lint_on WIDTH */ -module DCacheFlushFSM - (input logic clk, - input logic reset, - input logic start, - output logic done); - - genvar adr; - - logic [`XLEN-1:0] ShadowRAM[`UNCORE_RAM_BASE>>(1+`XLEN/32):(`UNCORE_RAM_RANGE+`UNCORE_RAM_BASE)>>1+(`XLEN/32)]; - - if(`DCACHE_SUPPORTED) begin - localparam numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES; - localparam numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS; - localparam linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN; - localparam linelen = testbench.dut.core.lsu.bus.dcache.dcache.LINELEN; - localparam sramlen = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].SRAMLEN; - localparam cachesramwords = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].NUMSRAM; - localparam numwords = sramlen/`XLEN; - localparam lognumlines = $clog2(numlines); - localparam loglinebytelen = $clog2(linebytelen); - localparam lognumways = $clog2(numways); - localparam tagstart = lognumlines + loglinebytelen; - - - - genvar index, way, cacheWord; - logic [sramlen-1:0] CacheData [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic [sramlen-1:0] cacheline; - logic [`XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic CacheValid [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic CacheDirty [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic [`PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - for(index = 0; index < numlines; index++) begin - for(way = 0; way < numways; way++) begin - for(cacheWord = 0; cacheWord < cachesramwords; cacheWord++) begin - copyShadow #(.tagstart(tagstart), - .loglinebytelen(loglinebytelen), .sramlen(sramlen)) - copyShadow(.clk, - .start, - .tag(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS-1-tagstart:0]), - .valid(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].ValidBits[index]), - .dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]), - // these dirty bit selections would be needed if dirty is moved inside the tag array. - //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]), - //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS+tagstart]), - .data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].wordram.CacheDataMem.RAM[index]), - .index(index), - .cacheWord(cacheWord), - .CacheData(CacheData[way][index][cacheWord]), - .CacheAdr(CacheAdr[way][index][cacheWord]), - .CacheTag(CacheTag[way][index][cacheWord]), - .CacheValid(CacheValid[way][index][cacheWord]), - .CacheDirty(CacheDirty[way][index][cacheWord])); - end - end - end - - integer i, j, k, l; - - always @(posedge clk) begin - if (start) begin - for(i = 0; i < numlines; i++) begin - for(j = 0; j < numways; j++) begin - for(l = 0; l < cachesramwords; l++) begin - if (CacheValid[j][i][l] & CacheDirty[j][i][l]) begin - for(k = 0; k < numwords; k++) begin - //cacheline = CacheData[j][i][0]; - // does not work with modelsim - // # ** Error: ../testbench/testbench.sv(483): Range must be bounded by constant expressions. - // see https://verificationacademy.com/forums/systemverilog/range-must-be-bounded-constant-expressions - //ShadowRAM[CacheAdr[j][i][k] >> $clog2(`XLEN/8)] = cacheline[`XLEN*(k+1)-1:`XLEN*k]; - ShadowRAM[(CacheAdr[j][i][l] >> $clog2(`XLEN/8)) + k] = CacheData[j][i][l][`XLEN*k +: `XLEN]; - end - end - end - end - end - end - end - end - flop #(1) doneReg(.clk, .d(start), .q(done)); -endmodule - -module copyShadow - #(parameter tagstart, loglinebytelen, sramlen) - (input logic clk, - input logic start, - input logic [`PA_BITS-1:tagstart] tag, - input logic valid, dirty, - input logic [sramlen-1:0] data, - input logic [32-1:0] index, - input logic [32-1:0] cacheWord, - output logic [sramlen-1:0] CacheData, - output logic [`PA_BITS-1:0] CacheAdr, - output logic [`XLEN-1:0] CacheTag, - output logic CacheValid, - output logic CacheDirty); - - - always_ff @(posedge clk) begin - if(start) begin - CacheTag = tag; - CacheValid = valid; - CacheDirty = dirty; - CacheData = data; - CacheAdr = (tag << tagstart) + (index << loglinebytelen) + (cacheWord << $clog2(sramlen/8)); - end - end - -endmodule - task automatic updateProgramAddrLabelArray; + /* verilator lint_off WIDTHTRUNC */ + /* verilator lint_off WIDTHEXPAND */ input string ProgramAddrMapFile, ProgramLabelMapFile; inout integer ProgramAddrLabelArray [string]; // Gets the memory location of begin_signature integer ProgramLabelMapFP, ProgramAddrMapFP; ProgramLabelMapFP = $fopen(ProgramLabelMapFile, "r"); ProgramAddrMapFP = $fopen(ProgramAddrMapFile, "r"); - + + if (ProgramLabelMapFP & ProgramAddrMapFP) begin // check we found both files + // *** RT: I'm a bit confused by the required initialization here. + ProgramAddrLabelArray["begin_signature"] = 0; + ProgramAddrLabelArray["tohost"] = 0; while (!$feof(ProgramLabelMapFP)) begin string label, adrstr; integer returncode; @@ -817,5 +553,7 @@ task automatic updateProgramAddrLabelArray; end $fclose(ProgramLabelMapFP); $fclose(ProgramAddrMapFP); + /* verilator lint_on WIDTHTRUNC */ + /* verilator lint_on WIDTHEXPAND */ endtask diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index b6d22feaf..0ca45420a 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -25,39 +25,44 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" +`include "config.vh" + // This is set from the command line script // `define USE_IMPERAS_DV `ifdef USE_IMPERAS_DV - `include "rvvi/imperasDV.svh" + `include "idv/idv.svh" `endif +import cvw::*; + module testbench; parameter DEBUG=0; `ifdef USE_IMPERAS_DV - import rvviPkg::*; + import idvPkg::*; import rvviApiPkg::*; import idvApiPkg::*; `endif + `include "parameter-defs.vh" + logic clk; logic reset_ext, reset; - logic [`XLEN-1:0] testadr, testadrNoBase; + logic [P.XLEN-1:0] testadr, testadrNoBase; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] InstrW; logic [3:0] dummy; - logic [`AHBW-1:0] HRDATAEXT; + logic [P.AHBW-1:0] HRDATAEXT; logic HREADYEXT, HRESPEXT; - logic [`PA_BITS-1:0] HADDR; - logic [`AHBW-1:0] HWDATA; - logic [`XLEN/8-1:0] HWSTRB; + 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; @@ -65,7 +70,7 @@ module testbench; logic [1:0] HTRANS; logic HMASTLOCK; logic HCLK, HRESETn; - logic [`XLEN-1:0] PCW; + logic [P.XLEN-1:0] PCW; string ProgramAddrMapFile, ProgramLabelMapFile; integer ProgramAddrLabelArray [string] = '{ "begin_signature" : 0, "tohost" : 0 }; @@ -108,7 +113,7 @@ module testbench; $error("Must specify test directory using plusarg testDir"); end - if (`BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); + if (P.BUS_SUPPORTED) $readmemh(memfilename, dut.uncore.uncore.ram.ram.memory.RAM); else $error("Imperas test bench requires BUS."); ProgramAddrMapFile = {testDir, "/ref/ref.elf.objdump.addr"}; @@ -123,8 +128,8 @@ module testbench; `ifdef USE_IMPERAS_DV - rvviTrace #(.XLEN(`XLEN), .FLEN(`FLEN)) rvvi(); - wallyTracer wallyTracer(rvvi); + rvviTrace #(.XLEN(P.XLEN), .FLEN(P.FLEN)) rvvi(); + wallyTracer #(P) wallyTracer(rvvi); trace2log idv_trace2log(rvvi); trace2cov idv_trace2cov(rvvi); @@ -140,7 +145,7 @@ module testbench; initial begin - MAX_ERRS = 3; + IDV_MAX_ERRS = 3; // Initialize REF (do this before initializing the DUT) if (!rvviVersionCheck(RVVI_API_VERSION)) begin @@ -171,23 +176,23 @@ module testbench; // 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 (`CLINT_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE))); + if (P.CLINT_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.CLINT_BASE, (P.CLINT_BASE + P.CLINT_RANGE))); end - if (`GPIO_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE))); + if (P.GPIO_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.GPIO_BASE, (P.GPIO_BASE + P.GPIO_RANGE))); end - if (`UART_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); + if (P.UART_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.UART_BASE, (P.UART_BASE + P.UART_RANGE))); end - if (`PLIC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE))); + if (P.PLIC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.PLIC_BASE, (P.PLIC_BASE + P.PLIC_RANGE))); end - if (`SDC_SUPPORTED) begin - void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE))); + if (P.SDC_SUPPORTED) begin + void'(rvviRefMemorySetVolatile(P.SDC_BASE, (P.SDC_BASE + P.SDC_RANGE))); end - if(`XLEN==32) begin + if(P.XLEN==32) begin void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH @@ -211,19 +216,19 @@ module testbench; `endif - flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); + flopenr #(P.XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); // check assertions for a legal configuration - riscvassertions riscvassertions(); + riscvassertions #(P) riscvassertions(); // instantiate device to be tested assign GPIOIN = 0; assign UARTSin = 1; - if(`EXT_MEM_SUPPORTED) begin - ram_ahb #(.BASE(`EXT_MEM_BASE), .RANGE(`EXT_MEM_RANGE)) + if(P.EXT_MEM_SUPPORTED) begin + ram_ahb #(.BASE(P.EXT_MEM_BASE), .RANGE(P.EXT_MEM_RANGE)) ram (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELRam(HSELEXT), .HREADRam(HRDATAEXT), .HREADYRam(HREADYEXT), .HRESPRam(HRESPEXT), .HREADY, .HWSTRB); @@ -233,7 +238,7 @@ module testbench; assign HRDATAEXT = 0; end - if(`FPGA) begin : sdcard + if(P.FPGA) begin : sdcard sdModel sdcard (.sdClk(SDCCLK), .cmd(SDCCmd), @@ -247,7 +252,7 @@ module testbench; assign SDCDat = '0; end - wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK); @@ -287,7 +292,7 @@ module testbench; // track the current function or global label if (DEBUG == 1) begin : FunctionName - FunctionName FunctionName(.reset(reset), + FunctionName #(P) FunctionName(.reset(reset), .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); @@ -299,7 +304,7 @@ module testbench; // or sd gp, -56(t0) // or on a jump to self infinite loop (6f) for RISC-V Arch tests logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls - if (`ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; + if (P.ZICSR_SUPPORTED) assign ecf = dut.core.priv.priv.EcallFaultM; else assign ecf = 0; assign DCacheFlushStart = ecf & (dut.core.ieu.dp.regf.rf[3] == 1 | @@ -309,13 +314,13 @@ module testbench; ((dut.core.ifu.InstrM == 32'h6f | dut.core.ifu.InstrM == 32'hfc32a423 | dut.core.ifu.InstrM == 32'hfc32a823) & dut.core.ieu.c.InstrValidM ) | ((dut.core.lsu.IEUAdrM == ProgramAddrLabelArray["tohost"]) & InstrMName == "SW" ); - DCacheFlushFSM DCacheFlushFSM(.clk(clk), + DCacheFlushFSM #(P) DCacheFlushFSM(.clk(clk), .reset(reset), .start(DCacheFlushStart), .done(DCacheFlushDone)); // initialize the branch predictor - if (`BPRED_SUPPORTED == 1) + if (P.BPRED_SUPPORTED == 1) begin genvar adrindex; @@ -331,24 +336,7 @@ module testbench; end end - // check for hange up. - logic [`XLEN-1:0] OldPCW; - integer WatchDogTimerCount; - localparam WatchDogTimerThreshold = 1000000; - logic WatchDogTimeOut; - always_ff @(posedge clk) begin - OldPCW <= PCW; - if(OldPCW == PCW) WatchDogTimerCount = WatchDogTimerCount + 1'b1; - else WatchDogTimerCount = '0; - end - - always_comb begin - WatchDogTimeOut = WatchDogTimerCount >= WatchDogTimerThreshold; - if(WatchDogTimeOut) begin - $display("FAILURE: Watch Dog Time Out triggered. PCW stuck at %x for more than %d cycles", PCW, WatchDogTimerCount); - $stop; - end - end + watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck endmodule @@ -356,120 +344,6 @@ endmodule /* verilator lint_on STMTDLY */ /* verilator lint_on WIDTH */ -module DCacheFlushFSM - (input logic clk, - input logic reset, - input logic start, - output logic done); - - genvar adr; - - logic [`XLEN-1:0] ShadowRAM[`UNCORE_RAM_BASE>>(1+`XLEN/32):(`UNCORE_RAM_RANGE+`UNCORE_RAM_BASE)>>1+(`XLEN/32)]; - - if(`DCACHE_SUPPORTED) begin - localparam integer numlines = testbench.dut.core.lsu.bus.dcache.dcache.NUMLINES; - localparam integer numways = testbench.dut.core.lsu.bus.dcache.dcache.NUMWAYS; - localparam integer linebytelen = testbench.dut.core.lsu.bus.dcache.dcache.LINEBYTELEN; - localparam integer linelen = testbench.dut.core.lsu.bus.dcache.dcache.LINELEN; - localparam integer sramlen = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].SRAMLEN; - localparam integer cachesramwords = testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[0].NUMSRAM; - -//testbench.dut.core.lsu.bus.dcache.dcache.CacheWays.NUMSRAM; - localparam integer numwords = sramlen/`XLEN; - localparam integer lognumlines = $clog2(numlines); - localparam integer loglinebytelen = $clog2(linebytelen); - localparam integer lognumways = $clog2(numways); - localparam integer tagstart = lognumlines + loglinebytelen; - - - - genvar index, way, cacheWord; - logic [sramlen-1:0] CacheData [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic [sramlen-1:0] cacheline; - logic [`XLEN-1:0] CacheTag [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic CacheValid [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic CacheDirty [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - logic [`PA_BITS-1:0] CacheAdr [numways-1:0] [numlines-1:0] [cachesramwords-1:0]; - for(index = 0; index < numlines; index++) begin - for(way = 0; way < numways; way++) begin - for(cacheWord = 0; cacheWord < cachesramwords; cacheWord++) begin - copyShadow #(.tagstart(tagstart), - .loglinebytelen(loglinebytelen), .sramlen(sramlen)) - copyShadow(.clk, - .start, - .tag(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS-1-tagstart:0]), - .valid(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].ValidBits[index]), - .dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].DirtyBits[index]), - // these dirty bit selections would be needed if dirty is moved inside the tag array. - //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].dirty.DirtyMem.RAM[index]), - //.dirty(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].CacheTagMem.RAM[index][`PA_BITS+tagstart]), - .data(testbench.dut.core.lsu.bus.dcache.dcache.CacheWays[way].word[cacheWord].wordram.CacheDataMem.RAM[index]), - .index(index), - .cacheWord(cacheWord), - .CacheData(CacheData[way][index][cacheWord]), - .CacheAdr(CacheAdr[way][index][cacheWord]), - .CacheTag(CacheTag[way][index][cacheWord]), - .CacheValid(CacheValid[way][index][cacheWord]), - .CacheDirty(CacheDirty[way][index][cacheWord])); - end - end - end - - integer i, j, k, l; - - always @(posedge clk) begin - if (start) begin #1 - #1 - for(i = 0; i < numlines; i++) begin - for(j = 0; j < numways; j++) begin - for(l = 0; l < cachesramwords; l++) begin - if (CacheValid[j][i][l] & CacheDirty[j][i][l]) begin - for(k = 0; k < numwords; k++) begin - //cacheline = CacheData[j][i][0]; - // does not work with modelsim - // # ** Error: ../testbench/testbench.sv(483): Range must be bounded by constant expressions. - // see https://verificationacademy.com/forums/systemverilog/range-must-be-bounded-constant-expressions - //ShadowRAM[CacheAdr[j][i][k] >> $clog2(`XLEN/8)] = cacheline[`XLEN*(k+1)-1:`XLEN*k]; - ShadowRAM[(CacheAdr[j][i][l] >> $clog2(`XLEN/8)) + k] = CacheData[j][i][l][`XLEN*k +: `XLEN]; - end - end - end - end - end - end - end - end - flop #(1) doneReg(.clk, .d(start), .q(done)); -endmodule - -module copyShadow - #(parameter tagstart, loglinebytelen, sramlen) - (input logic clk, - input logic start, - input logic [`PA_BITS-1:tagstart] tag, - input logic valid, dirty, - input logic [sramlen-1:0] data, - input logic [32-1:0] index, - input logic [32-1:0] cacheWord, - output logic [sramlen-1:0] CacheData, - output logic [`PA_BITS-1:0] CacheAdr, - output logic [`XLEN-1:0] CacheTag, - output logic CacheValid, - output logic CacheDirty); - - - always_ff @(posedge clk) begin - if(start) begin - CacheTag = tag; - CacheValid = valid; - CacheDirty = dirty; - CacheData = data; - CacheAdr = (tag << tagstart) + (index << loglinebytelen) + (cacheWord << $clog2(sramlen/8)); - end - end - - -endmodule task automatic updateProgramAddrLabelArray; input string ProgramAddrMapFile, ProgramLabelMapFile; diff --git a/testbench/tests.vh b/testbench/tests.vh index 54167f73c..f38f28056 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -75,26 +75,26 @@ string tvpaths[] = '{ string embench[] = '{ `EMBENCH, - "bd_speedopt_speed/src/nsichneu/nsichneu", - "bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches "bd_speedopt_speed/src/aha-mont64/aha-mont64", "bd_speedopt_speed/src/crc32/crc32", + "bd_speedopt_speed/src/cubic/cubic", // cubic is likely going to removed when embench 2.0 launches "bd_speedopt_speed/src/edn/edn", "bd_speedopt_speed/src/huffbench/huffbench", "bd_speedopt_speed/src/matmult-int/matmult-int", - // "bd_speedopt_speed/src/md5sum/md5sum", //commenting out tests from embench 2.0. When embench 2.0 launches stabilty, add these tests back + "bd_speedopt_speed/src/md5sum/md5sum", //commenting out tests from embench 2.0. When embench 2.0 launches stabilty, add these tests back "bd_speedopt_speed/src/minver/minver", "bd_speedopt_speed/src/nettle-aes/nettle-aes", "bd_speedopt_speed/src/nettle-sha256/nettle-sha256", + "bd_speedopt_speed/src/nsichneu/nsichneu", "bd_speedopt_speed/src/nbody/nbody", "bd_speedopt_speed/src/picojpeg/picojpeg", - // "bd_speedopt_speed/src/primecount/primecount", + "bd_speedopt_speed/src/primecount/primecount", "bd_speedopt_speed/src/qrduino/qrduino", "bd_speedopt_speed/src/sglib-combined/sglib-combined", "bd_speedopt_speed/src/slre/slre", "bd_speedopt_speed/src/st/st", "bd_speedopt_speed/src/statemate/statemate", - // "bd_speedopt_speed/src/tarfind/tarfind", + "bd_speedopt_speed/src/tarfind/tarfind", "bd_speedopt_speed/src/ud/ud", "bd_speedopt_speed/src/wikisort/wikisort", "bd_sizeopt_speed/src/aha-mont64/aha-mont64", @@ -103,20 +103,20 @@ string tvpaths[] = '{ "bd_sizeopt_speed/src/edn/edn", "bd_sizeopt_speed/src/huffbench/huffbench", "bd_sizeopt_speed/src/matmult-int/matmult-int", - // "bd_sizeopt_speed/src/md5sum/md5sum", + "bd_sizeopt_speed/src/md5sum/md5sum", "bd_sizeopt_speed/src/minver/minver", "bd_sizeopt_speed/src/nbody/nbody", "bd_sizeopt_speed/src/nettle-aes/nettle-aes", "bd_sizeopt_speed/src/nettle-sha256/nettle-sha256", "bd_sizeopt_speed/src/nsichneu/nsichneu", "bd_sizeopt_speed/src/picojpeg/picojpeg", - // "bd_sizeopt_speed/src/primecount/primecount", + "bd_sizeopt_speed/src/primecount/primecount", "bd_sizeopt_speed/src/qrduino/qrduino", "bd_sizeopt_speed/src/sglib-combined/sglib-combined", "bd_sizeopt_speed/src/slre/slre", "bd_sizeopt_speed/src/st/st", "bd_sizeopt_speed/src/statemate/statemate", - // "bd_sizeopt_speed/src/tarfind/tarfind", + "bd_sizeopt_speed/src/tarfind/tarfind", "bd_sizeopt_speed/src/ud/ud", "bd_sizeopt_speed/src/wikisort/wikisort" }; @@ -1466,7 +1466,7 @@ string arch64zbb[] = '{ "rv64i_m/B/src/andn-01.S", "rv64i_m/B/src/orn-01.S", "rv64i_m/B/src/xnor-01.S", - "rv64i_m/B/src/zext.h-01.S", + "rv64i_m/B/src/zext.h_64-01.S", "rv64i_m/B/src/sext.b-01.S", "rv64i_m/B/src/sext.h-01.S", "rv64i_m/B/src/clz-01.S", diff --git a/testbench/wallywrapper.sv b/testbench/wallywrapper.sv new file mode 100644 index 000000000..747b31806 --- /dev/null +++ b/testbench/wallywrapper.sv @@ -0,0 +1,102 @@ +/////////////////////////////////////////// +// testbench.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Wally Testbench and helper modules +// Applies test programs from the riscv-arch-test and Imperas suites +// +// 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" +`include "tests.vh" + +`define PrintHPMCounters 0 +`define BPRED_LOGGER 0 +`define I_CACHE_ADDR_LOGGER 0 +`define D_CACHE_ADDR_LOGGER 0 + +import cvw::*; + +module wallywrapper; + parameter DEBUG=0; + parameter TEST="none"; + +`include "parameter-defs.vh" + + logic clk; + logic reset_ext, reset; + + parameter SIGNATURESIZE = 5000000; + + int test, i, errors, totalerrors; + logic [31:0] sig32[0:SIGNATURESIZE]; + logic [P.XLEN-1:0] signature[0:SIGNATURESIZE]; + logic [P.XLEN-1:0] testadr, testadrNoBase; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + + string tests[]; + logic [3:0] dummy; + + logic [P.AHBW-1:0] HRDATAEXT; + logic HREADYEXT, HRESPEXT; + 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 HCLK, HRESETn; + + logic [31:0] GPIOIN, GPIOOUT, GPIOEN; + logic UARTSin, UARTSout; + + logic SDCCLK; + logic SDCCmdIn; + logic SDCCmdOut; + logic SDCCmdOE; + logic [3:0] SDCDatIn; + tri1 [3:0] SDCDat; + tri1 SDCCmd; + + logic HREADY; + logic HSELEXT; + + // instantiate device to be tested + assign GPIOIN = 0; + assign UARTSin = 1; + + assign HREADYEXT = 1; + assign HRESPEXT = 0; + assign HRDATAEXT = 0; + + assign SDCCmd = '0; + assign SDCDat = '0; + + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, + .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, + .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, + .UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK); + +endmodule diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 7e67b8ab5..29ad9b418 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -156,6 +156,10 @@ main: .word 0x43007053 // illegal fcvt.d.* (bad Rs2D) .word 0x42207053 // illegal fcvt.d.* (bad Rs2D[1]) + # Test floating point convert to integer and using result + fcvt.w.s t0, f0 + add t1, t0, t0 + j done .section .data