diff --git a/.github/workflows/interactive-debugging.yml b/.github/workflows/interactive-debugging.yml index 570323a50..8415e094d 100644 --- a/.github/workflows/interactive-debugging.yml +++ b/.github/workflows/interactive-debugging.yml @@ -315,3 +315,19 @@ jobs: ${CALIPTRA_ROOT}/.github/scripts/openocd_test.sh \ -f board/caliptra-verilator-rst.cfg \ -f ${CALIPTRA_ROOT}/src/integration/test_suites/infinite_loop/peripheral_access.tcl + + - name: Build Verilated simulation + run: | + export CALIPTRA_ROOT=$(pwd) + rm -rf run/* + make -C run -f ${CALIPTRA_ROOT}/tools/scripts/Makefile verilator-build TESTNAME=infinite_loop DEBUG_UNLOCKED=1 \ + OBJCACHE="" CC=gcc CXX=g++ LINK=g++ + make -C run -f ${CALIPTRA_ROOT}/tools/scripts/Makefile program.hex TESTNAME=infinite_loop + + - name: Test JTAG access with clock gating + run: | + export CALIPTRA_ROOT=$(pwd) + cd run + ${CALIPTRA_ROOT}/.github/scripts/openocd_test.sh \ + -f board/caliptra-verilator.cfg \ + -f ${CALIPTRA_ROOT}/src/integration/test_suites/infinite_loop/jtag_cg.tcl diff --git a/README.md b/README.md index 7070e2e35..3c86dc341 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.*_
# **Caliptra Hands-On Guide** # -_*Last Update: 2023/09/06*_ +_*Last Update: 2023/10/17*_ ## **Tools Used** ## @@ -37,10 +37,12 @@ Simulation: - `Version 2021.2.1` of AHB/APB models - UVM installation - `Version 1.1d` + - Mentor Graphics UVM-Frameworks + - `2022.3` Synthesis: - - Synopsys DC - - `Version 2020.09-SP1` + - Synopsys Fusion Compiler + - `Version 2022.12-SP3` GCC: - RISCV Toolchain for generating memory initialization files @@ -53,7 +55,7 @@ Other: - Playbook (Microsoft Internal workflow management tool) ### **RISCV Toolchain installation** ### -Note that there is significant configurability when installing the RISCV toolchain. +There is significant configurability when installing the RISCV toolchain. These instructions may be used to create a RISCV installation that will be compatible with the provided Makefile for compiling test C programs. @@ -72,7 +74,7 @@ Required for simulation:
`CALIPTRA_ROOT`: Defines the absolute path to the Project repository root (called "Caliptra" or "caliptra-rtl"). Recommended to define as `${CALIPTRA_WORKSPACE}/Caliptra`.
Required for Firmware (i.e. Test suites) makefile:
- `TESTNAME`: Contains the name of one of the tests listed inside the `src/integration/test_suites` folder
+ `TESTNAME`: Contains the name of one of the tests listed inside the `src/integration/test_suites` folder; only used for `caliptra_top_tb` tests
## **Repository Overview** ## ``` @@ -121,6 +123,9 @@ VF files provide absolute filepaths (prefixed by the `CALIPTRA_ROOT` environment The "Integration" sub-component contains the top-level fileset for Caliptra. `src/integration/config/compile.yml` defines the required filesets and sub-component dependencies for this build target. All of the files/dependencies are explicitly listed in `src/integration/config/caliptra_top_tb.vf`. Users may compile the entire design using only this VF filelist.
+## **Verilog File Lists** ## +Verilog file lists are generated via VCS and included in the config directory for each unit. New files added to the design should be included in the vf list. They can be included manually or by using VCS to regenerate the vf file. File lists define the compilation sources (including all dependencies) required to build and simulate a given module or testbench, and should be used for simulation, lint, and synthesis. + ## **Scripts Description** ## `demo.rdl`:Sample RDL file
@@ -138,21 +143,32 @@ The "Integration" sub-component contains the top-level fileset for Caliptra. `sr ## **Simulation Flow** ## -### VCS Steps: ### +### Caliptra Top VCS Steps: ### 1. Setup tools, add to PATH (ensure riscv64-unknown-elf-gcc is also available) 2. Define all environment variables above - For the initial test run after downloading repository, `iccm_lock` is recommended for TESTNAME + - See [Regression Tests](#Regression-Tests) for information about available tests. 3. Create a run folder for build outputs (and cd to it) -4. [OPTIONAL] By default, this run flow will use the riscv64 toolchain to compile test firmware (according to TESTNAME) into program.hex, iccm.hex, dccm.hex, and mailbox.hex. As a first pass, integrators may alternatively use the pre-built hexfiles for convenience (available for `iccm_lock` test). To do this, copy `iccm_lock.hex` to the run directory and rename to `program.hex`. `dccm.hex` should also be copied to the run directory, as-is. Use `touch iccm.hex mailbox.hex` to create empty hex files, as these are unnecessary for `iccm_lock` test. +4. [OPTIONAL] By default, this run flow will use the riscv64 toolchain to compile test firmware (according to TESTNAME) into program.hex, iccm.hex, dccm.hex, and mailbox.hex. As a first pass, integrators may alternatively use the pre-built hexfiles for convenience (available for [iccm_lock](src/integration/test_suites/iccm_lock) test). To do this, copy [iccm_lock.hex](src/integration/test_suites/iccm_lock/iccm_lock.hex) to the run directory and rename to `program.hex`. [dccm.hex](src/integration/test_suites/iccm_lock/iccm_lock.hex) should also be copied to the run directory, as-is. Use `touch iccm.hex mailbox.hex` to create empty hex files, as these are unnecessary for `iccm_lock` test. 5. Invoke `${CALIPTRA_ROOT}/tools/scripts/Makefile` with target 'program.hex' to produce SRAM initialization files from the firmware found in `src/integration/test_suites/${TESTNAME}` - E.g.: `make -f ${CALIPTRA_ROOT}/tools/scripts/Makefile program.hex` + - NOTE: TESTNAME may also be overridden in the makefile command line invocation, e.g. `make -f ${CALIPTRA_ROOT}/tools/scripts/Makefile TESTNAME=iccm_lock program.hex` 6. Compile complete project using `src/integration/config/caliptra_top_tb.vf` as a compilation target in VCS. When running the `vcs` command to generate simv, users should ensure that `caliptra_top_tb` is explicitly specified as the top-level component in their command to ensure this is the sole "top" that gets simulated. -7. Simulate project with `caliptra_top_tb` as the top target +7. Copy the test generator scripts to the run output directory: + - [src/ecc/tb/ecdsa_secp384r1.exe](src/ecc/tb/ecdsa_secp384r1.exe) + * Necessary for [randomized_pcr_signing](src/integration/test_suites/randomized_pcr_signing) + * OPTIONAL otherwise + - [src/doe/tb/doe_test_gen.py](src/doe/tb/doe_test_gen.py) + * Allows use of randomized secret field inputs during testing. + * Required when using the `+RAND_DOE_VALUES` plusarg during simulation + * Also required for several smoke tests that require randomized DOE IV, such as smoke_test_doe_scan, smoke_test_doe_rand, smoke_test_doe_cg +8. Simulate project with `caliptra_top_tb` as the top target -### Verilator Steps: ### +### Caliptra Top Verilator Steps: ### 1. Setup tools, add to PATH (ensure Verilator, GCC, and riscv64-unknown-elf-gcc are available) 2. Define all environment variables above - For the initial test run after downloading repository, `iccm_lock` is recommended for TESTNAME + - See [Regression Tests](#Regression-Tests) for information about available tests. 3. Create a run folder for build outputs - Recommended to place run folder under `${CALIPTRA_WORKSPACE}/scratch/$USER/verilator/` 4. [OPTIONAL] By default, this run flow will use the riscv64 toolchain to compile test firmware (according to TESTNAME) into program.hex, iccm.hex, dccm.hex, and mailbox.hex. As a first pass, integrators may alternatively use the pre-built hexfiles for convenience (available for `iccm_lock` test). To do this, copy `iccm_lock.hex` to the run directory and rename to `program.hex`. `dccm.hex` should also be copied to the run directory, as-is. Use `touch iccm.hex mailbox.hex` to create empty hex files, as these are unnecessary for `iccm_lock` test. @@ -170,6 +186,18 @@ The "Integration" sub-component contains the top-level fileset for Caliptra. `sr 3. NOTE: The script automatically creates run output folders at `${CALIPTRA_WORKSPACE}/scratch/$USER/verilator//` for each test run 4. NOTE: The output folder is populated with a run log that reports the run results and pass/fail status +### Unit Test VCS Steps: ### +1. Setup tools, add to PATH +1. Define all environment variables above +1. Create a run folder for build outputs (and cd to it) +1. Compile complete project using `src//config/_tb.vf` as a compilation target in VCS. When running the `vcs` command to generate simv, users should ensure that `_tb` is explicitly specified as the top-level component in their command to ensure this is the sole "top" that gets simulated. +1. Copy the test generator scripts or test vectors to the run output directory: + - [src/ecc/tb/test_vectors/mm_test_vectors\*.hex](src/ecc/tb/test_vectors) + * Necessary for [ecc_montgomerymultiplier_tb](src/ecc/tb/ecc_montgomerymultiplier_tb.sv) + - [src/sha256/tb/sha256_test_gen.py](src/sha256/tb/sha256_test_gen.py) + * Necessary for [sha256_random_test](src/sha256/tb/sha256_random_test.sv) +1. Simulate project with `_tb` as the top target + ### UVM Testbench Steps for `caliptra_top`:
**Description**:
@@ -178,20 +206,77 @@ The UVM Framework generation tool was used to create the baseline UVM testbench **Prerequisites**:
- QVIP 2021.2.1 for Mentor Graphics (provides the AHB/APB VIP) - UVM 1.1d installation +- Mentor Graphics UVM-Framework installation Steps:
1. Compile UVM 1.1d library -2. Compile the AHB/APB QVIP source -3. Compile the UVMF wrapper for APB/AHB in Caliptra/src/libs/uvmf -4. Compile the `verification_ip` provided for `soc_ifc` found in `Caliptra/src/soc_ifc/uvmf_soc_ifc` -5. Compile the `caliptra_top` testbench found in `Caliptra/src/integration/uvmf_caliptra_top` -6. `Caliptra/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv` is the top-level TB wrapper for the system -7. Select a test to run from the set of tests in `Caliptra/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src` -8. Provide `+UVM_TESTNAME=` argument to simulation +1. Compile the AHB/APB QVIP source +1. Compile the Mentor Graphics UVM-Frameworks base library +1. Compile the UVMF wrapper for APB/AHB in Caliptra/src/libs/uvmf +1. Compile the `verification_ip` provided for `soc_ifc` found in `Caliptra/src/soc_ifc/uvmf_soc_ifc` +1. Compile the `caliptra_top` testbench found in `Caliptra/src/integration/uvmf_caliptra_top` +1. ALL compilation steps may be completed by using the file-list found at `src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top.vf` +1. NOTE: `Caliptra/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv` is the top-level TB wrapper for the system +1. Compile the validation firmware (as described in [Regression Tests](#Regression-Tests)) that will run on Caliptra's embedded RISC-V core + - The expected output products are `program.hex`, `caliptra_fmc.hex`, `caliptra_rt.hex` and must be placed in the simulation run directory + - `make -f ${CALIPTRA_ROOT}/tools/scripts/Makefile TESTNAME=caliptra_top program.hex` + - `make -f ${CALIPTRA_ROOT}/tools/scripts/Makefile TESTNAME=caliptra_fmc caliptra_fmc.hex` + - `make -f ${CALIPTRA_ROOT}/tools/scripts/Makefile TESTNAME=caliptra_rt caliptra_rt.hex` +1. Copy the test vectors to the run output directory: + - [src/sha512/tb/vectors/SHA\*.rsp](src/sha512/tb/vectors/) + * Required for SHA512 UVM unittest +1. Select a test to run from the set of tests in `Caliptra/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src` +1. Provide `+UVM_TESTNAME=` argument to simulation + +### UVM Unit Test Steps:
+ +**Description**:
+The UVM Framework generation tool was used to create the baseline UVM testbench for verification of each IP component inside Caliptra. The following IP blocks have supported UVM testbenches: +- [ECC](src/ecc/uvmf_ecc) +- [HMAC](src/hmac/uvmf_2022) +- [SHA512](src/sha512/uvmf_sha512) +- [KeyVault](src/keyvault/uvmf_kv) +- [PCRVault](src/pcrvault/uvmf_pv) +- [SOC_IFC](src/soc_ifc/uvmf_soc_ifc) + +**Prerequisites**:
+- QVIP 2021.2.1 for Mentor Graphics (provides the AHB/APB VIP) +- UVM 1.1d installation +- Mentor Graphics UVM-Framework installation + +Steps:
+1. Compile UVM 1.1d library +1. Compile the AHB/APB QVIP source +1. Compile the Mentor Graphics UVM-Frameworks base library +1. Compile the UVMF wrapper for APB/AHB in Caliptra/src/libs/uvmf +1. Compile the `verification_ip` provided for the target testbench +1. ALL compilation steps may be completed by using the file-list found at `src//uvmf_/config/.vf` +1. NOTE: `Caliptra/src//uvmf_/uvmf_template_output/project_benches//tb/testbench/hdl_top.sv` is the top-level TB wrapper for the system +1. Copy the test generator scripts to the run output directory: + - [src/ecc/tb/ecdsa_secp384r1.exe](src/ecc/tb/ecdsa_secp384r1.exe) + * Necessary for ECC unittest + - [src/hmac/tb/test_gen.py](src/hmac/tb/test_gen.py) + * Required for uvmf_hmac unittest + - [src/sha512/tb/vectors/SHA\*.rsp](src/sha512/tb/vectors/) + * Required for SHA512 UVM unittest +1. Select a test to run from the set of tests in `Caliptra/src//uvmf_/uvmf_template_output/project_benches//tb/tests/src` +1. Provide `+UVM_TESTNAME=` argument to simulation + ## **Regression Tests** ## -Only tests from the L0 Regression List should be run. +### Standalone SystemVerilog Testbench Regression ### +Only tests from the L0 Regression List should be run. +The list is defined in the file [L0_regression.yml](https://github.com/chipsalliance/caliptra-rtl/blob/main/src/integration/stimulus/L0_regression.yml) + +### UVM Regression ### +The UVM simulation environment for `caliptra_top` uses a special set of validation firmware to generate stimulus as required for the test plan. This firmware suite is found in `src/integration/test_suites` and includes: + - `caliptra_top`: A C-based program that emulates a minimal set of bringup functions similar to the function of the ROM. This C file transitions very early to either a the FMC image or Runtime image based on bringup (reset reason) conditions. + - `caliptra_fmc`: A C-based program that emulates the functionality of the First Mutable Code. In this reduced-functionality validation implementation, the FMC code is a simple intermediary that runs from ICCM and serves to boot the Runtime Firmware. + - `caliptra_rt`: A C-based program that emulates the functionality of the production Runtime code. This program receives and services interrupts, defines a minimal Non-Maskable Interrupt handler, generates FW resets as needed, processes mailbox commands (generated through the UVM validation test plan), and runs some baseline Watchdog Timer testing. + +These three programs are designed to be run within the context of a UVM simulation, and will fail to generate meaningful stimulus in the standalone `caliptra_top_tb` test. + ## **NOTES** ## * The internal registers are auto rendered at the [GitHub page](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs) diff --git a/Release_Notes.md b/Release_Notes.md index 3dc7c388d..d390c9210 100644 --- a/Release_Notes.md +++ b/Release_Notes.md @@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.*_
# **Release Notes** # -_*Last Update: 2023/09/13*_ +_*Last Update: 2023/11/02*_ -## Rev 1p0 ## +## Rev 1p0-rc1 ## -### Rev 1p0 release date: (pending ROM release for official declaration) ### +### Rev 1p0-rc1 release date: 2023/11/03 (1p0 version pending ROM release for official declaration) ### - Caliptra IP Specification: see docs/ folder - Caliptra Integration Specification: see docs/ folder - Caliptra testplan: see docs/ folder diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..a7ac201ef --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,3 @@ +# Caliptra Project Security Incident Response + +Please refer to the security policy at [Caliptra security policy](https://github.com/chipsalliance/caliptra/security/policy). diff --git a/docs/CaliptraHardwareSpecification.md b/docs/CaliptraHardwareSpecification.md new file mode 100644 index 000000000..55f9068bc --- /dev/null +++ b/docs/CaliptraHardwareSpecification.md @@ -0,0 +1,1536 @@ +![OCP Logo](./images/OCP_logo.png) + +

Caliptra Hardware Specification

+ +

Version 0.5

+ +
+ +# Scope + +This document defines technical specifications for a Caliptra RoT for Measurement (RTM)[1] cryptographic subsystem used in the Open Compute Project (OCP). This document, along with [Caliptra: A Datacenter System on a Chip (SoC) Root of Trust (RoT)](https://chipsalliance.github.io/Caliptra/doc/Caliptra.html), shall comprise the Caliptra technical specification. + +# Overview + +This document provides definitions and requirements for a Caliptra cryptographic subsystem. The document then relates these definitions to existing technologies, enabling device and platform vendors to better understand those technologies in trusted computing terms. + +# Caliptra Core + +The following figure shows the Caliptra Core. + +*Figure 1: Caliptra Block Diagram* + +TODO: add figures + +## Boot FSM + +The Boot FSM detects that the SoC is bringing Caliptra out of reset. Part of this flow involves signaling to the SoC that Caliptra is awake and ready for fuses. After fuses are populated and the SoC indicates that it is done downloading fuses, Caliptra can wake up the rest of the IP by de-asserting the internal reset. + +The following figure shows the initial power-on arc of the Mailbox Boot FSM. + +*Figure 2: Mailbox Boot FSM state diagram* + +The Boot FSM first waits for the SoC to assert cptra\_pwrgood and de-assert cptra\_rst\_b. In the BOOT\_FUSE state, Caliptra signals to the SoC that it is ready for fuses. After the SoC is done writing fuses, it sets the fuse done register and the FSM advances to BOOT\_DONE. + +BOOT\_DONE enables Caliptra reset de-assertion through a two flip-flop synchronizer. + +## FW update reset (Impactless FW update) + +Runtime FW updates write to fw\_update\_reset register to trigger the FW update reset. When this register is written, only the RISC-V core is reset using cptra\_uc\_fw\_rst\_b pin and all AHB slaves are still active. All registers within the slaves and ICCM/DCCM memories are intact after the reset. Since ICCM is locked during runtime, it must be unlocked after the RISC-V reset is asserted. Reset is deasserted synchronously after a programmable number of cycles (currently set to 5 clocks) and normal boot flow updates the ICCM with the new FW from the mailbox SRAM. Reset de-assertion is done through a two flip-flop synchronizer. The boot flow is modified as shown in the following figure. + +*Figure 3: Mailbox Boot FSM state diagram for FW update reset* + +After Caliptra comes out of global reset and enters the BOOT\_DONE state, a write to the fw\_update\_reset register triggers the FW update reset flow. In the BOOT\_FWRST state, only the reset to the VeeR core is asserted, ICCM is unlocked and the timer is initialized. After the timer expires, the FSM advances from the BOOT\_WAIT to BOOT\_DONE state where the reset is deasserted. + +| Control register | Start address | Description | +| :------- | :---------- | :--------- | +| FW_UPDATE_RESET | 0x30030418 | Register to trigger the FW update reset flow. Setting it to 1 starts the Boot FSM. The field auto-clears to 0. | +| FW_UPDATE_RESET_WAIT_CYCLES | 0x3003041C | Programmable wait time to keep the microcontroller reset asserted. | + +## RISC-V core + +The RISC-V core is VeeR EL2 from CHIPS Alliance. It is a 32-bit CPU core that contains a 4-stage, scalar, in-order pipeline. The core supports RISC-V’s integer(I), compressed instruction(C), multiplication and division (M), instruction-fetch fence, CSR, and subset of bit manipulation instructions (Z) extensions. A link to the RISC-V VeeR EL2 Programmer’s Reference Manual is provided in the [References](#references) section. + +### Configuration + +The RISC-V core is highly configurable and has the following settings. + +| Parameter | Configuration | +| :---------------------- | :------------ | +| Interface | AHB-Lite | +| DCCM | 128 KiB | +| ICCM | 128 KiB | +| I-Cache | Disabled | +| Reset Vector | 0x00000000 | +| Fast Interrupt Redirect | Enabled | +| External Interrupts | 31 | + +### Embedded memory export + +Internal RISC-V SRAM memory components are exported from the Caliptra subsystem to support adaptation to various fabrication processes. For more information, see the [Caliptra Integration Specification](https://github.com/chipsalliance/caliptra-rtl/blob/main/docs/CaliptraIntegrationSpecification.md). + +#### Memory map address regions + +The 32-bit address region is subdivided into 16 fixed-sized, contiguous 256 MB regions. The following table describes the address mapping for each of the AHB devices that the RISC-V core interfaces with. + +| Subsystem | Address size | Start address | End address | +| :------------------ | :----------- | :------------ | :---------- | +| ROM | 48 KiB | 0x0000_0000 | 0x0000_BFFF | +| Cryptographic | 512 KiB | 0x1000_0000 | 0x1007_FFFF | +| Peripherals | 32 KiB | 0x2000_0000 | 0x2000_7FFF | +| SoC IFC | 256 KiB | 0x3000_0000 | 0x3003_FFFF | +| RISC-V Core ICCM | 128 KiB | 0x4000_0000 | 0x4001_FFFF | +| RISC-V Core DCCM | 128 KiB | 0x5000_0000 | 0x5001_FFFF | +| RISC-V MM CSR (PIC) | 256 MiB | 0x6000_0000 | 0x6FFF_FFFF | + +##### Cryptographic subsystem + +The following table shows the memory map address ranges for each of the IP blocks in the cryptographic subsystem. + +| IP/Peripheral | Slave \# | Address size | Start address | End address | +| :---------------------------------- | :------- | :----------- | :------------ | :---------- | +| Cryptographic Initialization Engine | 0 | 32 KiB | 0x1000_0000 | 0x1000_7FFF | +| ECC Secp384 | 1 | 32 KiB | 0x1000_8000 | 0x1000_FFFF | +| HMAC384 | 2 | 4 KiB | 0x1001_0000 | 0x1001_0FFF | +| Key Vault | 3 | 8 KiB | 0x1001_8000 | 0x1001_9FFF | +| PCR Vault | 4 | 8 KiB | 0x1001_A000 | 0x1001_BFFF | +| Data Vault | 5 | 8 KiB | 0x1001_C000 | 0x1001_DFFF | +| SHA512 | 6 | 32 KiB | 0x1002_0000 | 0x1002_7FFF | +| SHA256 | 13 | 32 KiB | 0x1002_8000 | 0x1002_FFFF | + +##### Peripherals subsystem + +The following table shows the memory map address ranges for each of the IP blocks in the peripherals’ subsystem. + +| IP/Peripheral | Slave \# | Address size | Start address | End address | +| :------------ | :------- | :----------- | :------------ | :---------- | +| QSPI | 7 | 4 KiB | 0x2000_0000 | 0x2000_0FFF | +| UART | 8 | 4 KiB | 0x2000_1000 | 0x2000_1FFF | +| CSRNG | 15 | 4 KiB | 0x2000_2000 | 0x2000_2FFF | +| ENTROPY SRC | 16 | 4 KiB | 0x2000_3000 | 0x2000_3FFF | + +##### SoC interface subsystem + +The following table shows the memory map address ranges for each of the IP blocks in the SoC interface subsystem. + +| IP/Peripheral | Slave \# | Address size | Start address | End address | +| :------------------------- | :------- | :----------- | :------------ | :---------- | +| Mailbox SRAM Direct Access | 10 | 128 KiB | 0x3000_0000 | 0x3001_FFFF | +| Mailbox CSR | 10 | 4 KiB | 0x3002_0000 | 0x3002_0FFF | +| SHA512 Accelerator CSR | 10 | 4 KiB | 0x3002_1000 | 0x3002_1FFF | +| Mailbox | 10 | 64 KiB | 0x3003_0000 | 0x3003_FFFF | + +##### RISC-V core local memory blocks + +The following table shows the memory map address ranges for each of the local memory blocks that interface with RISC-V core. + +| IP/Peripheral | Slave \# | Address size | Start address | End address | +| :-------------- | :------- | :----------- | :------------ | :---------- | +| ICCM0 (via DMA) | 12 | 128 KiB | 0x4000_0000 | 0x4001_FFFF | +| DCCM | 11 | 128 KiB | 0x5000_0000 | 0x5001_FFFF | + +#### Interrupts + +The VeeR-EL2 processor supports multiple types of interrupts, including non-maskable interrupts (NMI), software interrupts, timer interrupts, external interrupts, and local interrupts. Local interrupts are events not specified by the RISC-V standard, such as auxiliary timers and correctable errors. + +Caliptra uses NMI in conjunction with a watchdog timer to support fatal error recovery and system restart. For more information, see the [Watchdog timer](#watchdog-timer) section. + +Software and local interrupts are not implemented in the first generation of Caliptra. Standard RISC-V timer interrupts are implemented using the mtime and mtimecmp registers defined in the RISC-V Privileged Architecture Specification. Both mtime and mtimecmp are included in the soc\_ifc register bank, and are accessible by the internal microprocessor to facilitate precise timing tasks. Frequency for the timers is configured by the SoC using the dedicated timer configuration register, which satisfies the requirement prescribed in the RISC-V specification for such a mechanism. These timer registers drive the timer\_int pin into the internal microprocessor. + +##### Non-maskable interrupts + + 0p8 describe a register bank that may be used to dynamically configure the NMI reset vector. (i.e., where the PC resets to). + +##### External interrupts + +Caliptra uses the external interrupt feature to support event notification from all attached peripheral components in the subsystem. The RISC-V processor supports multiple priority levels (ranging from 1-15), which allows firmware to configure interrupt priority per component. + +Errors and notifications are allocated as interrupt events for each component, with error interrupts assigned a higher priority and expected to be infrequent. + +Notification interrupts are used to alert the processor of normal operation activity, such as completion of requested operations or arrival of SoC requests through the shared interface. + +Vector 0 is reserved by the RISC-V processor and may not be used, so vector assignment begins with Vector 1. Bit 0 of the interrupt port to the processor corresponds with Vector 1. + +| IP/Peripheral | Interrupt vector | Interrupt priority example
(Increasing, Max 15) | +| :-------------------------------------------------- | :--------------- | :---------------------------------------------- | +| Cryptographic Initialization Engine (Errors) | 1 | 8 | +| Cryptographic Initialization Engine (Notifications) | 2 | 7 | +| ECC (Errors) | 3 | 8 | +| ECC (Notifications) | 4 | 7 | +| HMAC (Errors) | 5 | 8 | +| HMAC (Notifications) | 6 | 7 | +| KeyVault (Errors) | 7 | 8 | +| KeyVault (Notifications) | 8 | 7 | +| SHA512 (Errors) | 9 | 8 | +| SHA512 (Notifications) | 10 | 7 | +| SHA256 (Errors) | 11 | 8 | +| SHA256 (Notifications) | 12 | 7 | +| QSPI (Errors) | 13 | 4 | +| QSPI (Notifications) | 14 | 3 | +| UART (Errors) | 15 | 4 | +| UART (Notifications) | 16 | 3 | +| RESERVED | 17 | 4 | +| RESERVED | 18 | 3 | +| Mailbox (Errors) | 19 | 8 | +| Mailbox (Notifications) | 20 | 7 | + +## Watchdog timer + +The primary function of Caliptra Watchdog Timer (WDT) is to reset the microcontroller (Caliptra), in the event of a software malfunction, by resetting the device if it has not been cleared in software. It is a two-stage timer, independent of the RISCV core. + +### Operation + +The WDT consists of two timers. When enabled in cascade mode (done by enabling Timer 1 alone), the WDT increments Timer 1 until the counter rolls over or times out. Typically, the timer is serviced at regular intervals to prevent it from overflowing or rolling over. If Timer 1 has not timed out, Timer 2 is disabled and held at its initial value. However, when Timer 1 does roll over, it triggers an error interrupt to the RISC-V core. In parallel, Timer 2 is enabled and begins counting. If the interrupt is serviced before Timer 2 times out, the timers are reset and continue to operate normally. If Timer 2 times out, it asserts an SoC fatal error and an NMI. The SoC fatal error is also captured in the CPTRA\_HW\_ERROR\_FATAL register, which can be cleared by the SoC by writing a 1. A warm reset is required by the SoC to reset the timers when Timer 2 times out. + +The WDT timers can be configured to operate independent of each other. When the enable register for Timer 2 is set, the default configuration of cascaded timers is disabled and both timers count independently of each other. In this case, a timeout on Timer 2 causes an error interrupt to the RISC-V core similar to Timer 1. Disabling Timer 2 configures the timers back into the default cascaded mode. + +Each timer has an enable bit, a restart bit, and a 64-bit timeout value register that can be programmed as needed. The restart bit is used to service the timers and restart counting. The timeout period registers can be configured to the desired upper bound of timers. + +If the WDT timers are disabled and then re-enabled with a new timeout period, they must be restarted by setting the appropriate control register (restart bit). If the timers are temporarily disabled and re-enabled with the same timeout period, they resume counting and do not restart from 0. + +For more details regarding the register interface to control the WDT, see the [register documentation](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.soc_ifc_reg) published in the RTL GitHub repository. + +The following figure shows the two timers. + +*Figure 4: Caliptra Watchdog Timer* + +### Prescale settings + +Assuming a clock source of 500 MHz, a timeout value of 32’hFFFF\_FFFF results in a timeout period of ~8.5 seconds. Two 32-bit registers are provided for each timer, allowing a 64-bit timeout period to be programmed for each timer. This accommodates a maximum timeout value of over 1000 years for the same 500 Mhz clock source. + +### Microcontroller interface + +The Caliptra microcontroller communicates with the mailbox through its internal AHB-Lite fabric. + +#### AHB-lite interface + +AHB-lite is a subset of the full AHB specification. It is primarily used in single master systems. This interface connects VeeR EL2 Core (LSU master) to the slave devices as shown in Figure 1. + +The interface can be customized to support variable address and data widths, and a variable number of slave devices. Each slave device is assigned an address range within the 32-bit address memory map region. The interface includes address decoding logic to route data to the appropriate AHB slave device based on the address specified. + +The integration parameters for Caliptra’s AHB-lite interface are shown in the following table. + +| Parameter | Value | +| :------------ | :---- | +| ADDRESS_WIDTH | 32 | +| DATA_WIDTH | 64 | +| NUM_OF_SLAVES | 17 | + +Each IP component in the Caliptra system uses a native AHB data width of 32-bits (1 dword). The AHB responder logic in each IP component contains width conversion logic that transforms from the fabric data width of 64-bits to this native 32-bit width. The conversion involves calculating the dword offset (either 0 or 1) relative to the native 64-bit width by evaluating bit [2] of the address line. This information is used to extract the correct 32-bits from the native write data line. If there is a data offset, data is shifted down by 32-bits; otherwise, the upper 32-bits are simply truncated. This new dword-address is passed to the internal register interface along with the dword-sized data. A similar conversion works in reverse to correctly place read data in the response data line from the responder. + +As a result of this implementation, 64-bit data transfers are not supported on the Caliptra AHB fabric. Firmware running on the internal microprocessor may only access memory and registers using a 32-bit or smaller request size, as 64-bit transfer requests will be corrupted. + +### Cryptographic subsystem + +For details, see the [Cryptographic subsystem architecture](#cryptographic-subsystem-architecture) section. + +### Peripherals subsystem + +Caliptra includes QSPI and UART peripherals that are used to facilitate alternative operating modes and debug. In the first generation, Caliptra includes code to enable QSPI in the RTL, but does not support the BMI profile. Therefore, QSPI must not be enabled. Similarly, the UART interface exists to facilitate firmware debug in an FPGA prototype, but should be disabled in final silicon. SystemVerilog defines used to disable these peripherals are described in the [Caliptra Integration Specification](https://github.com/chipsalliance/caliptra-rtl/blob/main/docs/CaliptraIntegrationSpecification.md). Operation of these peripherals is described in the following sections. + +#### QSPI Flash Controller + +Caliptra implements a QSPI block that can communicate with 2 QSPI devices. This QSPI block is accessible to FW over the AHB-lite Interface. + +The QSPI block is composed of the spi\_host implementation. For information, see the [SPI\_HOST HWIP Technical Specification](https://opentitan.org/book/hw/ip/spi_host/index.html). The core code (see [spi\_host](https://github.com/lowRISC/opentitan/tree/master/hw/ip/spi_host)) is reused but the interface to the module is changed to AHB-lite and the number of chip select lines supported is increased to 2. The design provides support for Standard SPI, Dual SPI, or Quad SPI commands. The following figure shows the QSPI flash controller. + +*Figure 5: QSPI flash controller* + +#### Operation + +Transactions flow through the QSPI block starting with AHB-lite writes to the TXDATA FIFO. Commands are then written and processed by the control FSM, orchestrating transmissions from the TXDATA FIFO and receiving data into the RXDATA FIFO. + +The structure of a command depends on the device and the command itself. In the case of a standard SPI device, the host IP always transmits data on qspi\_d\_io[0] and always receives data from the target device on qspi\_d\_io[1]. In Dual or Quad modes, all data lines are bi-directional, thus allowing full bandwidth in transferring data across 4 data lines. + +A typical SPI command consists of different segments that are combined as shown in the following example. Each segment can configure the length, speed, and direction. As an example, the following SPI read transaction consists of 2 segments. + +*Figure 6: SPI read transaction segments* + +| Segment \# | Length (Bytes) | Speed | Direction | TXDATA FIFO | RXDATA FIFO | +| :--------- | :------------- | :------- | :---------------- | :----------- | :----------------- | +| 1 | 4 | standard | TX
qspi_d_io\[0\] | \[0\] 0x3 (ReadData)
\[1\] Addr\[23:16\]
\[2\] Addr\[15:8\]
\[3\] Addr\[7:0\] | | +| 2 | 1 | standard | RX
qspi_d_io\[1\] | | \[0\] Data \[7:0\] | + +In this example, the ReadData (0x3) command was written to the TXDATA FIFO, followed by the 3B address. This maps to a total of 4 bytes that are transmitted out across qspi\_d\_io[0] in the first segment. The second segment consists of a read command that receives 1 byte of data from the target device across qspi\_d\_io[1]. + +QSPI consists of up to four command segments in which the host: + +1. Transmits instructions or data at the standard rate +2. Transmits instructions address or data on 2 or 4 data lines +3. Holds the bus in a high-impedance state for some number of dummy cycles where neither side transmits +4. Receives information from the target device at the specified rate (derived from the original command) + +The following example shows the QSPI segments. + +*Figure 7: QSPI segments* + +| Segment \# | Length (Bytes) | Speed | Direction | TXDATA FIFO | RXDATA FIFO | +| :--------- | :------------- | :------- | :------------------ | :----------- | :---------------- | +| 1 | 1 | standard | TX
qspi_d_io\[3:0\] | \[0\] 0x6B (ReadDataQuad) | | +| 2 | 3\* | quad | TX
qspi_d_io\[3:0\] | \[1\] Addr\[23:16\]
\[2\] Addr\[15:8\]
\[3\] Addr\[7:0\] | | +| 3 | 2 | N/A | None (Dummy) | | | +| 4 | 1 | quad | RX
qspi_d_io\[3:0\] | | \[0\] Data\[7:0\] | + +Note: In the preceding figure, segment 2 doesn’t show bytes 2 and 3 for brevity. + +#### Configuration + +The CONFIGOPTS multi-register has one entry per CSB line and holds clock configuration and timing settings that are specific to each peripheral. After the CONFIGOPTS multi-register is programmed for each SPI peripheral device, the values can be left unchanged. + +The most common differences between target devices are the requirements for a specific SPI clock phase or polarity, CPOL and CPHA. These clock parameters can be set via the CONFIGOPTS.CPOL or CONFIGOPTS.CPHA register fields. + +The SPI clock rate depends on the peripheral clock and a 16b clock divider configured by CONFIGOPTS.CLKDIV. The following equation is used to configure the SPI clock period: + +![](./images/Caliptra_eq_SPI_clk_period.png) + +By default, CLKDIV is set to 0, which means that the maximum frequency that can be achieved is at most half the frequency of the peripheral clock (Fsck = Fclk/2). + +We can rearrange the equation to solve for the CLKDIV: + +![](./images/Caliptra_eq_CLKDIV.png) + +Assuming a 400MHz target peripheral, and a SPI clock target of 100MHz: + +CONFIGOPTS.CLKDIV = (400/(2\*100)) -1 = 1 + +The following figure shows CONFIGOPTS. + +*Figure 8: CONFIGOPTS* + +#### Signal descriptions + +The QSPI block architecture inputs and outputs are described in the following table. + +| Name | Input or output | Description | +| :------------------ | :-------------- | :-------------------------------------------------------- | +| clk_i | input | All signal timings are related to the rising edge of clk. | +| rst_ni | input | The reset signal is active LOW and resets the core. | +| cio_sck_o | output | SPI clock | +| cio_sck_en_o | output | SPI clock enable | +| cio_csb_o\[1:0\] | output | Chip select \# (one hot, active low) | +| cio_csb_en_o\[1:0\] | output | Chip select \# enable (one hot, active low) | +| cio_csb_sd_o\[3:0\] | output | SPI data output | +| cio_csb_sd_en_o | output | SPI data output enable | +| cio_csb_sd_i\[3:0\] | input | SPI data input | + +#### SPI\_HOST IP programming guide + +The operation of the SPI\_HOST IP proceeds in seven general steps. + +To initialize the IP: + +1. Program the CONFIGOPTS multi-register with the appropriate timing and polarity settings for each csb line. +2. Set the desired interrupt parameters. +3. Enable the IP. + +Then for each command: + +4. Load the data to be transmitted into the FIFO using the TXDATA memory window. +5. Specify the target device by programming the CSID. +6. Specify the structure of the command by writing each segment into the COMMAND register. + + For multi-segment transactions, assert COMMAND.CSAAT for all but the last command segment. + +7. For transactions that expect to receive a reply, the data can then be read back from the RXDATA window. + +Steps 4-7 are then repeated for each subsequent command. + +#### UART + +Caliptra implements a UART block that can communicate with a serial device that is accessible to FW over the AHB-lite Interface. This is a configuration that the SoC opts-in by defining CALIPTRA\_INTERNAL\_UART. + +The UART block is composed of the uart implementation. For information, see the [UART HWIP Technical Specification](https://opentitan.org/book/hw/ip/uart/). The design provides support for a programmable baud rate. The UART block is shown in the following figure. + +*Figure 9: UART block* + +#### Operation + +Transactions flow through the UART block starting with an AHB-lite write to WDATA, which triggers the transmit module to start a UART TX serial data transfer. The TX module dequeues the byte from the internal FIFO and shifts it out bit by bit at the baud rate. If TX is not enabled, the output is set high and WDATA in the FIFO is queued up. + +The following figure shows the transmit data on the serial lane, starting with the START bit, which is indicated by a high to low transition, followed by the 8 bits of data. + +*Figure 10: Serial transmission frame* + +On the receive side, after the START bit is detected, the data is sampled at the center of each data bit and stored into a FIFO. A user can monitor the FIFO status and read the data out of RDATA. + +#### Configuration + +The baud rate can be configured using the CTRL.NCO register field. This should be set using the following equation: + +![](./images/Caliptra_eq_NCO.png) + +If the desired baud rate is 115,200bps: + +![](./images/Caliptra_eq_UART.png) + +![](./images/Caliptra_eq_UART2.png) + +#### Signal descriptions + +The UART block architecture inputs and outputs are described in the following table. + +| Name | Input or output | Description | +| :------- | :-------------- | :-------------------------------------------------------- | +| clk_i | input | All signal timings are related to the rising edge of clk. | +| rst_ni | input | The reset signal is active LOW and resets the core. | +| cio_rx_i | input | Serial receive bit | +| cio_tx_o | output | Serial transmit bit | + +### SoC mailbox + +For more information on the mailbox protocol, see [Mailbox](https://github.com/chipsalliance/caliptra-rtl/blob/main/docs/Caliptra_rtl.md#mailbox) in the Caliptra Integration Specification. TODO: Fix this! + +The following table describes the mailbox control registers. + +| Control register | Start address | Description | +| :------------------------ | :---------------- | :----------------- | +| MBOX_LOCK | 0x30020000 | Mailbox lock register for mailbox access. Reading 0 sets the lock. | +| MBOX_USER | 0x30020004 | Stores the user that locked the mailbox.| +| MBOX_CMD | 0x30020008 | Command requested for data in mailbox. | +| MBOX_DLEN | 0x3002000c | Data length for mailbox access. | +| MBOX_DATAIN | 0x30020010 | Data in register. Writes the next data to mailbox. | +| MBOX_DATAOUT | 0x30020010 | Data out register. Reads the next data from mailbox.| +| MBOX_EXECUTE | 0x30020018 | Mailbox execute register indicates to the receiver that the sender is done. | +| MBOX_STATUS | 0x3002001c | Status of the mailbox command:
CMD_BUSY - 2’b00 – Indicates the requested command is still in progress
DATA_READY - 2’b01 – Indicates the return data is in the mailbox for the requested command
CMD_COMPLETE- 2’b10 – Indicates the successful completion of the requested command
CMD_FAILURE- 2’b11 – Indicates the requested command failed | +| HW_ERROR_FATAL | 0x30030000 | Indicates fatal hardware error. | +| HW_ERROR_NON_FATAL | 0x30030004 | Indicates non-fatal hardware error. | +| FW_ERROR_FATAL | 0x30030008 | Indicates fatal firmware error. | +| FW_ERROR_NON_FATAL | 0x3003000c | Indicates non-fatal firmware error. | +| HW_ERROR_ENC | 0x30030010 | Encoded error value for hardware errors. | +| FW_ERROR_ENC | 0x30030014 | Encoded error value for firmware errors. | +| BOOT_STATUS | 0x30030018 | Reports the boot status. | +| FLOW_STATUS | 0x3003001c | Reports the status of the firmware flows. | +| GENERIC_INPUT_WIRES | 0x30030024 | Generic input wires connected to the SoC interface. | +| GENERIC_OUTPUT_WIRES | 0x3003002c | Generic output wires connected to the SoC interface. | +| KEY_MANIFEST_PK_HASH | 0x300302b0 | | +| KEY_MANIFEST_PK_HASH_MASK | 0x30030370 | | +| KEY_MANIFEST_SVN | 0x30030374 | | +| BOOT_LOADER_SVN | 0x30030384 | | +| RUNTIME_SVN | 0x30030388 | | +| ANTI_ROLLBACK_DISABLE | 0x3003038c | | +| IEEE_IDEVID_CERT_CHAIN | 0x30030390 | | +| FUSE_DONE | 0x300303f0 | | + +### Security state + +Caliptra uses the MSB of the security state input to determine whether or not Caliptra is in debug mode. + +When Caliptra is in debug mode: + +* Security state MSB is set to 0. + +* Caliptra JTAG is opened for the microcontroller and HW debug. + +* Device secrets (UDS, FE, key vault, and obfuscation key) are programmed to debug values. + +If a transition to debug mode happens during ROM operation, any values computed from the use of device secrets may not match expected values. + +Transitions to debug mode trigger a hardware clear of all device secrets, and also trigger an interrupt to FW to inform of the transition. FW is responsible for initiating another hardware clear of device secrets utilizing the clear secrets register, in case any derivations were in progress and stored after the transition was detected. FW may open the JTAG after all secrets are cleared. + +Debug mode values may be set by integrators in the Caliptra configuration files. The default values are shown in the following table. + +| Name | Default value | +| :-------------------------- | :------------ | +| Obfuscation Key Debug Value | All 0x1 | +| UDS Debug Value | All 0x1 | +| Field Entropy Debug Value | All 0x1 | +| Key Vault Debug Value 0 | All 0xA | +| Key Vault Debug Value 1 | All 0x5 | + +### Clock gating + +Caliptra provides a clock gating feature that turns off clocks when the microcontroller is halted. Clock gating is disabled by default, but can be globally enabled via the following register. + +| Control register | Start address | Description | +| :------------------- | :---------------- | :------------------------ | +| CPTRA_CLK_GATING_EN | 0x300300bc | Register bit to enable or disable the clock gating feature. | + +When enabled, halting the microcontroller turns off clocks to all of the cryptographic subsystem, the vaults (keyvault, PCR vault, and data vault), mailbox SRAM, SoC interface, and peripherals subsystem. The Watchdog timer and SoC registers run on the gated RDC clock. The RV core implements its own clock gating mechanism. Halting the core automatically turns off its clock. + +There are a total of 4 clocks in Caliptra: ungated clock, gated clock, gated RDC clock, and gated SoC IFC clock. The following table shows the different modules and their designated clocks. + +| Module | Clock | +| :-------------------- | :-------------------------------------- | +| RV core | Clk | +| SOC IFC | Clk; clk_cg; rdc_clk_cg; soc_ifc_clk_cg | +| Crypto subsystem | Clk_cg | +| Vaults | Clk_cg | +| Peripherals subsystem | Clk_cg | +| AHB Lite IF, 2to1 Mux | Clk_cg | +| TRNG | Clk_cg | + +#### Wake up conditions + +For details on halting the core and waking up the core from the halt state, see section 5 of the [RISC-V VeeR EL2 Programmer's Reference Manual](https://github.com/chipsalliance/Cores-VeeR-EL2/blob/main/docs/RISC-V_VeeR_EL2_PRM.pdf). + +When the RV core wakes up, all clocks are enabled. However, when the core is halted, it is possible to wake up Caliptra clocks through: + +* A change in generic\_input\_wires + +* Cptra\_fatal\_error assertion + +* Entry to debug or scan modes + +* JTAG accesses + +* APB transactions + +Activity on the APB interface only wakes up the SoC IFC clock. All other clocks remain off until any other condition is met or the core exits the halt state. + +| Cpu_halt_status | PSEL | Generic input wires
\|\| fatal error
\|\| debug/scan mode
\|\|JTAG access | Expected behavior | +| :-------------- | :--- | :---------- | :-------------- | +| 0 | X | X | All gated clocks active | +| 1 | 0 | 0 | All gated clocks inactive | +| 1 | 0 | 1 | All gated clocks active (as long as condition is true) | +| 1 | 1 | 0 | Soc_ifc_clk_cg active (as long as PSEL = 1)
All other clks inactive | +| 1 | 1 | 1 | Soc_ifc_clk_cg active (as long as condition is true OR PSEL = 1)
All other clks active (as long as condition is true) | + +#### Usage + +The following applies to the clock gating feature: + +* The core should only be halted after all pending vault writes are done and cryptographic operations are complete. +* While the core is halted, any APB transaction wakes up the SoC interface clock and leaves all other clocks disabled. If the core is still halted when the APB transactions are done, the SoC interface clock is returned to a disabled state. . +* The RDC clock is similar to an ungated clock and is only disabled when a reset event occurs. This avoids metastability on flops. The RDC clock operates independently of core halt status. + + +#### Timing information + +The following figure shows the timing information for clock gating. + +*Figure 11: Clock gating timing* + +## Integrated TRNG + +Caliptra implements a true random number generator (TRNG) block for local use models. Firmware is able to read a random number from the TRNG core by accessing its register block over the AHB-lite interface. This is a configuration that SoC integrators enable by defining CALIPTRA\_INTERNAL\_TRNG. + +This TRNG block is a combination of entropy source and CSRNG implementations. For information, see the [ENTROPY\_SRC HWIP Technical Specification](https://opentitan.org/book/hw/ip/entropy_src/index.html) and the [CSRNG HWIP Technical Specification](https://opentitan.org/book/hw/ip/csrng/). The core code (see [entropy source](https://github.com/lowRISC/opentitan/tree/master/hw/ip/entropy_src) and [csrng](https://github.com/lowRISC/opentitan/tree/master/hw/ip/csrng)) is reused from here but the interface to the module is changed to AHB-lite. This design provides an interface to an external physical random noise generator. This is also referred to as a physical true random number generator (PTRNG). The PTRNG external source is a physical true random noise source. A noise source and its relation to an entropy source are defined by [SP 800-90B](https://csrc.nist.gov/publications/detail/sp/800-90b/final). + +The block is instantiated based on a design parameter chosen at integration time. This is to provide options for SoC to reuse an existing TRNG to build an optimized SoC design. For the optimized scenarios, SoC needs to follow the TODO: heading link in markdown. + +The following figure shows the integrated TRNG block. + +*Figure 12: Integrated TRNG block* + +The following figure shows the CSRNG block. + +*Figure 13: CSRNG block* + +The following figure shows the entropy source block. + +*Figure 14: Entropy source block* + +### Operation + +Requests for entropy bits start with [command requests](https://opentitan.org/book/hw/ip/csrng/doc/theory_of_operation.html#general-command-format) over the AHB-lite interface to the csrng [CMD\_REQ](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.csrng_reg.CMD_REQ) register. + +The following describes the fields of the command request header: + +* Application Command: Selects one of five operations to perform. The commands supported are instantiate, reseed, generate, update, and uninstantiate. + +* Command Length: Number of 32-bit words that can optionally be appended to the command. A value of zero will only transfer the command header. A value of 4'hc transfers the header plus an additional twelve 32-bit words of data. + +* Command Flag0: flag0 is associated with the current command. Setting this field to True (4’h6) enables flag0 to be enabled. Note that flag0 is used for the instantiate and reseed commands only; for all other commands, the flag0 value is ignored. + +* Generate Length: Only defined for the generate command, this field is the total number of cryptographic entropy blocks requested. Each unit represents 128 bits of entropy returned. A value of 8 would return a total of 1024 bits. The maximum size supported is 4096. + +First an instantiate command is requested over the SW application interface to initialize an instance in the CSRNG module. Depending on the flag0 and clen fields in the command header, a request to the entropy\_src module over the entropy interface is sent to seed the csrng. This can take a few milliseconds if the seed entropy is not immediately available. + +Example instantiation: + +acmd = 0x1 (Instantiate) + +clen/flag0 = The seed behavior is described in the following table. + +glen = Not used + +| flag0 | clen | Description | +| :---- | :--- | :----------------------------------------------------------- | +| F | 0 | Only entropy source seed is used. | +| F | 1-12 | Entropy source seed is xor'ed with provided additional data. | +| T | 0 | Seed of zero is used (no entropy source seed used). | +| T | 1-12 | Only provided additional data is used as seed. | + +Next a generate command is used to request generation of cryptographic entropy bits. The glen field defines how many 128 bit words are to be returned to the application interface. After the generated bits are ready, they can be read out via the GENBITS register. This register must be read out glen \* 4 times for each request made. + +Example generate command: + +acmd = 0x3 (Generate) + +clen = 0 + +flag0 = false (4’h9) + +glen = 4 (4 \*128 = 512b) + +This requires 16 reads from GENBITS to read out all of the generated entropy. + +### Configuration + +The HW application interfaces are not supported. Only the SW application interface should be used for this design. + +### Physical true random noise source signal descriptions + +These are the top level signals defined in caliptra\_top. + +| Name | Input or output | Description | +| :---------- | :-------------- | :------------ | +| itrng_data | input | Physical true random noise source data | +| itrng_valid | input | Valid is asserted high for one cycle when data is valid. The expected valid output rate is about 50KHz. | + +The following figure shows the top level signals defined in caliptra\_top. + +*Figure 15: caliptra\_top signals* + +### Entropy source signal descriptions + +The following table provides descriptions of the entropy source signals. + +| Name | Input or output | Description | +| :------------------ | :-------------- | :--------------- | +| clk_i | input | All signal timings are related to the rising edge of clk. | +| rst_ni | input | The reset signal is active LOW and resets the core. | +| entropy_src_rng_req | output | Request from the entropy_src module to the physical true random noise source to start generating data. | +| entropy_src_rng_rsp | input | Contains the internal TRNG data and a flag indicating the data is valid. Valid is asserted high for one cycle when data is valid. | +| entropy_src_hw_if_i | input | Downstream block request for entropy bits. | +| entropy_src_hw_if_o | output | 384 bits of entropy data. Valid when es_ack is asserted high. | +| cs_aes_halt_i | input | Response from csrng that all requests to AES block are halted. | +| cs_aes_halt_o | output | Request to csrng to halt requests to the AES block for power leveling purposes. | + +The following figure shows the entropy source signals. + +*Figure 16: Entropy source signals* + +### CSRNG signal descriptions + +The following table provides descriptions for the CSRNG signals. + +| Name | Input or output | Description | +| :------------------------- | :-------------- | :---------------------------------------------------------------------------------------------------- | +| clk_i | input | All signal timings are related to the rising edge of clk. | +| rst_ni | input | The reset signal is active LOW and resets the core. | +| otp_en_csrng_sw_app_read_i | input | Enable firmware to access the ctr_drbg internal state and genbits through registers. | +| lc_hw_debug_en_i | input | Lifecycle that selects which diversification value is used for xoring with the seed from entropy_src. | +| entropy_src_hw_if_i | input | 384 bits of entropy data. Valid when es_ack is asserted high. | +| entropy_src_hw_if_o | output | Downstream block request for entropy bits. | +| cs_aes_halt_i | input | Request from entropy_src to halt requests to the AES block for power leveling purposes. | +| cs_aes_halt_o | output | Response to entropy_src that all requests to AES block are halted. | + +The CSRNG may only be enabled if entropy\_src is enabled. After it is disabled, CSRNG may only be re-enabled after entropy\_src has been disabled and re-enabled. + +## External-TRNG REQ HW API + +For SoCs that choose to not instantiate Caliptra’s integrated TRNG, Caliptra provides a TRNGREQ HW API. + +1. Caliptra asserts TRNG\_REQ wire (FW made the request for a TRNG). +2. SoC writes the TRNG architectural registers. +3. SoC writes a done bit in the TRNG architectural registers. +4. Caliptra desserts TRNG\_REQ. + +The reason to have a separate interface from the SoC mailbox is to ensure that this request is not intercepted by any SoC FW agents that communicate with the SoC mailbox. It is required for FIPS compliance that this TRNG HW API is always handled by a SoC HW gasket logic and not handled by SoC ROM/FW code. + +## SoC-SHA accelerator HW API + +Caliptra provides a SHA accelerator HW API for SoC and Caliptra internal FW to use. It is atomic in nature in that only one of them can use the SHA accelerator HW API at the same time. Details of the SHA accelerator register block may be found in the GitHub repository in [documentation](https://chipsalliance.github.io/caliptra-rtl/main/external-regs/?p=caliptra_top_reg.sha512_acc_csr) generated from the register definition file. + +Using the HW API: + +* A user of the HW API first locks the accelerator by reading the LOCK register. A read that returns the value 0 indicates that the resource was locked for exclusive use by the requesting user. A write of ‘1 clears the lock. +* The USER register captures the APB pauser value of the requestor that locked the SHA accelerator. This is the only user that is allowed to control the SHA accelerator by performing APB register writes. Writes by any other agent on the APB interface are dropped. +* MODE register is written to set the SHA execution mode. + * SHA accelerator supports both SHA384 and SHA512 modes of operation. + * SHA supports **streaming** mode: SHA is computed on a stream of incoming data to the DATAIN register. The EXECUTE register, when set, indicates to the accelerator that streaming is complete. The accelerator can then publish the result into the DIGEST register. When the VALID bit of the STATUS register is set, then the result in the DIGEST register is valid. + * SHA supports **Mailbox** mode: SHA is computed on LENGTH (DLEN) bytes of data stored in the mailbox beginning at START\_ADDRESS. This computation is performed when the EXECUTE register is set by the user. When the operation is completed and the result in the DIGEST register is valid, SHA accelerator sets the VALID bit of the STATUS register. + * The SHA computation engine in the SHA accelerator requires big endian data, but the SHA accelerator can accommodate mailbox input data in either the little endian or big endian format. By default, input data is assumed to be little endian and is swizzled to big endian at the byte level prior to computation. For the big endian format, data is loaded into the SHA engine as-is. Users may configure the SHA accelerator to treat data as big endian by setting the ENDIAN\_TOGGLE bit appropriately. + * See the register definition for the encodings. +* SHA engine also provides a ‘zeroize’ function through its CONTROL register to clear any of the SHA internal state. This can be used when the user wants to conceal previous state for debug or security reasons. + +## JTAG implementation + +For specific debug flows, see the [JTAG/TAP Debug](https://chipsalliance.github.io/Caliptra/doc/Caliptra.html#jtagtap-debug) section in Caliptra: A Datacenter System on a Chip (SoC) Root of Trust (RoT). + +The following figure shows the JTAG implementation within the Caliptra boundary. The output of the existing DMI wrapper is used to find the non-Core (Caliptra uncore) aperture to route the JTAG commands. + +Caliptra’s JTAG/TAP should be implemented as a TAP EP. JTAG is open if the debug mode is set at the time of Caliptra reset deassertion. + +Note: If the debug security state switches to debug mode anytime, the security assets and keys are still flushed even though JTAG is not open. + +*Figure 17: JTAG implementation* + +# Cryptographic subsystem architecture + +The architecture of Caliptra cryptographic subsystem includes the following components: + +* Symmetric cryptographic primitives + * De-obfuscation engine + * SHA512/384 (based on NIST FIPS 180-4 [2]) + * SHA256 (based on NIST FIPS 180-4 [2]) + * HMAC384 (based on [NIST FIPS 198-1](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf) [5] and [RFC 4868](https://tools.ietf.org/html/rfc4868) [6]) +* Public-key cryptography + * NIST Secp384r1 Deterministic Digital Signature Algorithm (based on FIPS-186-4 [11] and RFC 6979 [7]) +* Key vault + * Key slots + * Key slot management + +The high-level architecture of Caliptra cryptographic subsystem is shown in the following figure. + +*Figure 18: Caliptra cryptographic subsystem TODO: fix this image* + +## SHA512/SHA384 + +SHA512 is a function of cryptographic hash algorithm SHA-2. The hardware implementation is based on [Secworks/SHA512](https://github.com/secworks/sha512) [1]. This implementation complies with the functionality in NIST FIPS 180-4 [2]. The implementation supports the SHA512 variants SHA-512/224, SHA-512/256, SHA384 and SHA512. + +The SHA512 algorithm is described as follows: + +* The message is padded by the host and broken into 1024-bit chunks +* For each chunk: + * The message is fed to the SHA512 core + * The core should be triggered by the host + * The SHA512 core status is changed to ready after hash processing +* The result digest can be read after feeding all message chunks + +### Operation + +#### Padding + +The message should be padded before feeding to the hash core. The input message is taken, and some padding bits are appended to it to get it to the desired length. The bits that are used for padding are simply ‘0’ bits with a leading ‘1’ (100000…000). The appended length of the message (before pre-processing), in bits, is a 128-bit big-endian integer. + +The total size should be equal to 128 bits short of a multiple of 1024 since the goal is to have the formatted message size as a multiple of 1024 bits (N x 1024). The following figure shows the SHA512 input formatting. + +*Figure 19: SHA512 input formatting* + +#### Hashing + +The SHA512 core performs 80 iterative operations to process the hash value of the given message. The algorithm processes each block of 1024 bits from the message using the result from the previous block. For the first block, the initial vectors (IV) are used for starting the chain processing of each 1024-bit block. + +### FSM + +The SHA512 architecture has the finite-state machine as shown in the following figure. + +*Figure 20: SHA512 FSM* + +### Signal descriptions + +The SHA512 architecture inputs and outputs are described in the following table. + +| Name | Inputs and outputs | Description | +|-----------------|--------------------|---------------------------------------------------------------------------------------------------| +| clk | input | All signal timings are related to the rising edge of clk. | +| reset_n | input | The reset signal is active LOW and resets the core. This is the only active LOW signal. | +| init | input | The core is initialized and processes the first block of message. | +| next | input | The core processes the rest of the message blocks using the result from the previous blocks. | +| mode\[1:0\] | input | Indicates the hash type of the function. This can be:
- SHA512/224
- SHA512/256
- SHA384
- SHA512 | +| zeroize | input | The core clears all internal registers to avoid any SCA information leakage. | +| block\[1023:0\] | input | The input padded block of message. | +| ready | output | When HIGH, the signal indicates the core is ready. | +| digest\[511:0\] | output | The hashed value of the given block. | +| digest_valid | output | When HIGH, the signal indicates that the result is ready. | + +### Address map + +The SHA512 address map is shown here: [sha512\_reg — clp Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.sha512_reg) + +### Pseudocode + +The following pseudocode demonstrates how the SHA512 interface can be implemented. + +*Figure 21: SHA512 pseudocode* + +### SCA countermeasure + +We do not propose any countermeasure to protect the hash functions. Inherently, hash functions do not work like other cryptographic engines. Hash functions target integrity without requiring a secret key. Hence, the attacker can target only messages. Also, the attacker cannot build a CPA or DPA platform on the hash function because the same message ideally gives the same side-channel behavior. + +If the attacker works on the multi-message mechanism, the attacker then needs to work with single trace attacks, which are very unlikely in ASIC/FPGA implementations. Also, our hash implementation is a noisy platform. As a result, we do not propose any SCA implementation countermeasure on the hash functions. + +### Performance + +The SHA512 core performance is reported considering two different architectures: pure hardware architecture, and hardware/software architecture. These are described next. + +#### Pure hardware architecture + +In this architecture, the SHA512 interface and controller are implemented in hardware. The performance specification of the SHA512 architecture is shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :-------------------- | :------------------ | +| Data_In transmission | | 0.08 | | +| Process | 87 | 0.22 | | +| Data_Out transmission | 16 | 0.04 | | +| Single block | 136 | 0.34 | 2,941,176 | +| Double block | 224 | 0.56 | 1,785,714 | +| 1 KiB message | 840 | 2.10 | 476,190 | +| 128 KiB message | 17,632 | 44.08 | 22,686 | + +#### Hardware/software architecture + +In this architecture, the SHA512 interface and controller are implemented in RISC-V core. The performance specification of the SHA512 architecture is shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\]\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :---------------------- | :------------------ | +| Data_In transmission | 990 | 2.48 | | +| Process | 139 | 0.35 | | +| Data_Out transmission | 387 | 0.97 | | +| Single block | 1,516 | 3.79 | 263,852 | +| Double block | 2,506 | 6.27 | 159,617 | +| 1 KiB message | 9,436 | 23.59 | 42,391 | +| 128 KiB message | 1,015,276 | 2,538.19 | 394 | + +#### Pure software architecture + +In this architecture, the SHA512 algorithm is implemented fully in software. The implementation is derived from the [OpenSSL](https://www.openssl.org/docs/man3.0/man3/SHA512.html) SHA512 implementation [3]. The performance numbers for this architecture are shown in the following table. + +| Data size | Cycle count | +| :------------ | :-------------- | +| 1 KiB | 147,002 | +| 4 KiB | 532,615 | +| 8 KiB | 1,046,727 | +| 12 KiB | 1,560,839 | +| 128 KiB | 16,470,055 | + +## SHA256 + +SHA256 is a function of the SHA-2 cryptographic hash algorithm. The hardware implementation is based on [Secworks/SHA256](https://github.com/secworks/sha256) [1]. The implementation supports the two variants: SHA256/224 and SHA256. + +The SHA256 algorithm is described as follows: + +* The message is padded by the host and broken into 512-bit chunks +* For each chunk: + * The message is fed to the sha256 core + * The core should be triggered by the host + * The sha256 core status is changed to ready after hash processing +* The result digest can be read after feeding all message chunks + + +### Operation + +#### Padding + +The message should be padded before feeding to the hash core. The input message is taken, and some padding bits are appended to the message to get it to the desired length. The bits that are used for padding are simply ‘0’ bits with a leading ‘1’ (100000…000). The appended length of the message (before pre-processing), in bits, is a 64-bit big-endian integer. + +The total size should be equal to 64 bits, short of a multiple of 512 because the goal is to have the formatted message size as a multiple of 512 bits (N x 512). + +The following figure shows SHA256 input formatting. + +*Figure 22: SHA256 input formatting* + +#### Hashing + +The SHA256 core performs 64 iterative operations to process the hash value of the given message. The algorithm processes each block of 512 bits from the message using the result from the previous block. For the first block, the initial vectors (IV) are used to start the chain processing of each 512-bit block. + +### FSM + +The SHA256 architecture has the finite-state machine as shown in the following figure. + +*Figure 23: SHA256 FSM* + +### Signal descriptions + +The SHA256 architecture inputs and outputs are described as follows. + +| Name | Input or output | Description | +| :-------------- | :-------------- | :------------------------------------------------------------------------------------------- | +| clk | input | All signal timings are related to the rising edge of clk. | +| reset_n | input | The reset signal is active LOW and resets the core. This is the only active LOW signal. | +| init | input | The core is initialized and processes the first block of message. | +| next | input | The core processes the rest of the message blocks using the result from the previous blocks. | +| mode | input | Indicates the hash type of the function. This can be:
- SHA256/224
- SHA256 | +| zeroize | input | The core clears all internal registers to avoid any SCA information leakage. | +| block\[511:0\] | input | The input padded block of message. | +| ready | output | When HIGH, the signal indicates the core is ready. | +| digest\[255:0\] | output | The hashed value of the given block. | +| digest_valid | output | When HIGH, the signal indicates the result is ready. | + +### Address map + +The SHA256 address map is shown here: [sha256\_reg — clp Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.sha256_reg). + +### Pseudocode + +The following pseudocode demonstrates how the SHA256 interface can be implemented. + +*Figure 24: SHA256 pseudocode* + +### SCA countermeasure + +We do not propose any countermeasure to protect the hash functions. For more information, see SCA countermeasure in the [SHA512/SHA384](#sha512sha384) section. + +### Performance + +The SHA256 core performance is reported considering two different architectures: pure hardware architecture, and hardware/software architecture. These are described next. + +#### Pure hardware architecture + +In this architecture, the SHA256 interface and controller are implemented in hardware. The performance specification of the SHA256 architecture is reported as shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :-------------------- | :------------------ | +| Data_In transmission | 17 | 0.04 | | +| Process | 66 | 0.17 | | +| Data_Out transmission | 8 | 0.02 | | +| Single block | 91 | 0.23 | 4,395,604 | +| Double block | 158 | 0.40 | 2,531,646 | +| 1 KiB message | 1163 | 2.91 | 343,938 | + +#### Hardware/software architecture + +In this architecture, the SHA256 interface and controller are implemented in RISC-V core. The performance specification of the SHA256 architecture is reported as shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :-------------------- | :------------------ | +| Data_In transmission | 500 | 1.25 | | +| Process | 66 | 0.17 | | +| Data_Out transmission | 195 | 0.49 | | +| Single block | 761 | 1.90 | 525,624 | +| Double block | 1355 | 3.39 | 295,203 | +| 1 KiB message | 8761 | 21.90 | 45,657 | + +## HMAC384 + +Hash-based message authentication code (HMAC) is a cryptographic authentication technique that uses a hash function and a secret key. HMAC involves a cryptographic hash function and a secret cryptographic key. This implementation supports HMAC-SHA-384-192 as specified in [NIST FIPS 198-1](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf) [5]. The implementation is compatible with the HMAC-SHA-384-192 authentication and integrity functions defined in [RFC 4868](https://tools.ietf.org/html/rfc4868) [6]. + +Caliptra HMAC implementation uses SHA384 as the hash function, accepts a 384-bit key, and generates a 384-bit tag. + +The implementation also supports PRF-HMAC-SHA-384. The PRF-HMAC-SHA-384 algorithm is identical to HMAC-SHA-384-192, except that variable-length keys are permitted, and the truncation step is not performed. + +The HMAC algorithm is described as follows: +* The key is fed to the HMAC core to be padded +* The message is broken into 1024-bit chunks by the host +* For each chunk: + * The message is fed to the HMAC core + * The HMAC core should be triggered by the host + * The HMAC core status is changed to ready after hash processing +* The result digest can be read after feeding all message chunks + + +### Operation + +#### Padding + +The message should be padded before feeding to the HMAC core. Internally, the i\_padded key is concatenated with the message. The input message is taken, and some padding bits are appended to the message to get it to the desired length. The bits that are used for padding are simply ‘0’ bits with a leading ‘1’ (100000…000). + +The total size should be equal to 128 bits, short of a multiple of 1024 because the goal is to have the formatted message size as a multiple of 1024 bits (N x 1024). + +*Figure 25: HMAC input formatting* + +The following figures show examples of input formatting for different message lengths. + +*Figure 26: Message length of 1023 bits* + +When the message is 1023 bits long, padding is given in the next block along with message size. + +*Figure 27: 1 bit padding* + +When the message size is 895 bits, a padding of ‘1’ is also considered valid, followed by the message size. + +*Figure 28: Multi block message* + +Messages with a length greater than 1024 bits are broken down into N 1024-bit blocks. The last block contains padding and the size of the message. + + +#### Hashing + +The HMAC core performs the sha2-384 function to process the hash value of the given message. The algorithm processes each block of the 1024 bits from the message, using the result from the previous block. This data flow is shown in the following figure. + +*Figure 29: HMAC-SHA-384-192 data flow* + +### FSM + +The HMAC architecture has the finite-state machine as shown in the following figure. + +*Figure 30: HMAC FSM* + +### Signal descriptions + +The HMAC architecture inputs and outputs are described in the following table. + +| Name | Input or output | Description | +| :----------------- | :-------------- | :----------- | +| clk | input | All signal timings are related to the rising edge of clk. | +| reset_n | input | The reset signal is active LOW and resets the core. This is the only active LOW signal. | +| init | input | The core is initialized and processes the key and the first block of the message. | +| next | input | The core processes the rest of the message blocks using the result from the previous blocks. | +| zeroize | input | The core clears all internal registers to avoid any SCA information leakage. | +| key\[383:0\] | input | The input key. | +| block\[1023:0\] | input | The input padded block of message. | +| LFSR_seed\[159:0\] | Input | The input to seed PRNG to enable the masking countermeasure for SCA protection. | +| ready | output | When HIGH, the signal indicates the core is ready. | +| tag\[383:0\] | output | The HMAC value of the given key or block. For PRF-HMAC-SHA-384, a 384-bit tag is required. For HMAC-SHA-384-192, the host is responsible for reading 192 bits from the MSB. | +| tag_valid | output | When HIGH, the signal indicates the result is ready. | + +### Address map + +The HMAC address map is shown here: [hmac\_reg — clp Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.hmac_reg). + +### Pseudocode + +The following pseudocode demonstrates how the HMAC interface can be implemented. + +*Figure 31: HMAC pseudocode* + +### SCA countermeasure + +In an attack model, an attacker can form hypotheses about the secret key value and compute the corresponding output values by using the Hamming Distance model as an appropriate leakage model. An attacker who has knowledge of the implementation for open-source architecture has an advantage. The attacker can capture the power consumption traces to verify their hypotheses, by partitioning the acquisitions or using Pearson’s correlation coefficient. + +To protect the HMAC algorithm from side-channel attacks, a masking countermeasure is applied. This means that random values are added to the intermediate variables during the algorithm’s execution, so that the side-channel signals do not reveal any information about them. + +The embedded countermeasures are based on "Differential Power Analysis of HMAC Based on SHA-2, and Countermeasures" by McEvoy et. al. To provide the required random values for masking intermediate values, a lightweight 74-bit LFSR is implemented. Based on “Spin Me Right Round Rotational Symmetry for FPGA-specific AES” by Wegener et. al., LFSR is sufficient for masking statistical randomness. + +Each round of SHA512 execution needs 6,432 random bits, while one HMAC operation needs at least 4 rounds of SHA512 operations. However, the proposed architecture requires only 160-bit LFSR seed and provides first-order DPA attack protection at the cost of 10% latency overhead with negligible hardware resource overhead. + +### Performance + +The HMAC core performance is reported considering two different architectures: pure hardware architecture, and hardware/software architecture. These are described next. + +#### Pure hardware architecture + +In this architecture, the HMAC interface and controller are implemented in hardware. The performance specification of the HMAC architecture is reported as shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :-------------------- | :------------------ | +| Data_In transmission | 44 | 0.11 | - | +| Process | 254 | 0.635 | - | +| Data_Out transmission | 12 | 0.03 | - | +| Single block | 310 | 0.775 | 1,290,322 | +| Double block | 513 | 1.282 | 780,031 | +| 1 KiB message | 1,731 | 4.327 | 231,107 | +| 128 KiB message | 207,979 | 519.947 | 1,923 | + +#### Hardware/software architecture + +In this architecture, the HMAC interface and controller are implemented in RISC-V core. The performance specification of the HMAC architecture is reported as shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[us\] @ 400 MHz | Throughput \[op/s\] | +| :-------------------- | :------------------ | :-------------------- | :------------------ | +| Data_In transmission | 1389 | 3.473 | - | +| Process | 253 | 0.633 | - | +| Data_Out transmission | 290 | 0.725 | - | +| Single block | 1932 | 4.83 | 207,039 | +| Double block | 3166 | 7.915 | 136,342 | +| 1 KiB message | 10,570 | 26.425 | 37,842 | +| 128 KiB message | 1,264,314 | 3,160.785 | 316 | + +## HMAC_DRBG + +Hash-based message authentication code (HMAC) deterministic random bit generator (DRBG) is a cryptographic random bit generator that uses a HMAC function. HMAC_DRBG involves a cryptographic HMAC function and a seed. This architecture is designed as specified in section 10.1.2. of NIST SP 800-90A [12]. For ECC signing operation, the implementation is compatible with section 3.1. of RFC 6979 [7]. + +Caliptra HMAC_DRBG implementation uses HMAC384 as the HMAC function, accepts a 384-bit seed, and generates a 384-bit random value. + +The HMAC algorithm is described as follows: + +* The seed is fed to HMAC_DRBG core by the host +* For each 384-bit random value + * The core should be triggered by the host + * The HMAC_DRBG core status is changed to ready after HMAC processing + * The result digest can be read + + +### Operation + +HMAC_DRBG uses a loop of HMAC(K, V) to generate the random bits. In this algorithm, two constant values of K_init and V_init are used as follows: + + 1. Set V_init = 0x01 0x01 0x01 ... 0x01 (V has 384-bit) + 2. Set K_init = 0x00 0x00 0x00 ... 0x00 (K has 384-bit) + 3. K_tmp = HMAC(K_init, V_init || 0x00 || entropy || nonce) + 4. V_tmp = HMAC(K_tmp, V_init) + 5. K_new = HMAC(K_tmp, V_tmp || 0x01 || entropy || nonce) + 6. V_new = HMAC(K_new, V_tmp) + 7. Set T = [] + 8. T = T || HMAC(K_new, V_new) + 9. Return T if T is within the [1,q-1] range, otherwise: + 10. K_new = HMAC(K_new, V_new || 0x00) + 11. V_new = HMAC(K_new, V_new) + 12. Jump to 8 + +For ECC KeyGen operation, HMAC_DRBG is used to generate privkey as follows: + + Privkey = HMAC_DRBG(seed, nonce) + +For ECC SIGNING operation, HMAC_DRBG is used to generate k as follows: + + K = HMAC_DRBG(privkey, hashed_msg) + +### Signal descriptions + +The HMAC_DRBG architecture inputs and outputs are described in the following table. + +| Name | Input or output | Description | +| :------------------- | :-------------- | :-------------------------------------------------------------------------------------- | +| clk | input | All signal timings are related to the rising edge of clk. | +| reset_n | input | The reset signal is active LOW and resets the core. This is the only active LOW signal. | +| init | input | The core is initialized with the given seed and generates a 384-bit random value. | +| next | input | The core generates a new 384-bit random value using the result from the previous run. | +| zeroize | input | The core clears all internal registers to avoid any SCA information leakage. | +| entropy \[383:0\] | input | The input entropy. | +| nonce \[383:0\] | input | The input nonce. | +| LFSR_seed \[147 :0\] | input | The input to seed PRNG to enable masking countermeasure for SCA protection. | +| ready | output | When HIGH, the signal indicates the core is ready. | +| drbg \[383:0\] | output | The hmac_drbg value of the given inputs. | +| valid | output | When HIGH, the signal indicates the result is ready. | + +### Address map + +The HMAC_DRBG is embedded into ECC architecture, since there is no address map to access it from FW. + +### SCA countermeasure + +For information, see SCA countermeasure in the [HMAC384](#hmac384) section. + +## ECC + +The ECC unit includes the ECDSA (Elliptic Curve Digital Signature Algorithm) engine, offering a variant of the cryptographically secure Digital Signature Algorithm (DSA), which uses elliptic curve (ECC). A digital signature is an authentication method in which a public key pair and a digital certificate are used as a signature to verify the identity of a recipient or sender of information. + +The hardware implementation supports deterministic ECDSA, 384 Bits (Prime Field), also known as NIST-Secp384r1, described in RFC6979. + +Secp384r1 parameters are shown in the following figure. + +*Figure 32: Secp384r1 parameters* + +### Operation + +The ECDSA consists of three operations, shown in the following figure. + +*Figure 33: ECDSA operations* + +#### KeyGen + +In the deterministic key generation, the paired key of (privKey, pubKey) is generated by KeyGen(seed, nonce), taking a deterministic seed and nonce. The KeyGen algorithm is as follows: + +* Compute privKey = HMAC_DRBG(seed, nonce) to generate a random integer in the interval [1, n-1] where n is the group order of Secp384 curve. +* Generate pubKey(x,y) as a point on ECC calculated by pubKey=privKey × G, while G is the generator point over the curve. + + +#### Signing + +In the signing algorithm, a signature (r, s) is generated by Sign(privKey, h), taking a privKey and hash of message m, h = hash(m), using a cryptographic hash function, SHA384. The signing algorithm includes: + +* Generate a random number k in the range [1..n-1], while k = HMAC\_DRBG(privKey, h) +* Calculate the random point R = k × G +* Take r = Rx mod n, where Rx is x coordinate of R=(Rx, Ry) +* Calculate the signature proof: s = k-1 × (h + r × privKey) mod n +* Return the signature (r, s), each in the range [1..n-1] + +#### Verifying + +The signature (r, s) can be verified by Verify(pubKey ,h ,r, s) considering the public key pubKey and hash of message m, h=hash(m) using the same cryptographic hash function SHA384. The output is r’ value of verifying a signature. The ECDSA verify algorithm includes: + +* Calculate s1 = s−1 mod n +* Compute R' = (h × s1) × G + (r × s1) × pubKey +* Take r’ = R'x mod n, while R'x is x coordinate of R’=(R'x, R'y) +* Verify the signature by comparing whether r' == r + +### Architecture + +The ECC top-level architecture is shown in the following figure. + +*Figure 34: ECDSA architecture* + +### Signal descriptions + +The ECDSA architecture inputs and outputs are described in the following table. + + +| Name | Input or output | Description | +| :------------------------- | :-------------- | :----------- | +| clk | input | All signal timings are related to the rising edge of clk. | +| reset_n | input | The reset signal is active LOW and resets the core. This is the only active LOW signal. | +| ctrl\[1:0\] | input | Indicates the AES type of the function. This can be:
− 0b00: No Operation
− 0b01: KeyGen
− 0b10: Signing
− 0b11: Verifying | +| zeroize | input | The core clears all internal registers to avoid any SCA information leakage. | +| seed \[383:0\] | input | The deterministic seed for HMAC_DRBG in the KeyGen operation. | +| nonce \[383:0\] | input | The deterministic nonce for HMAC_DRBG in the KeyGen operation. | +| privKey_in\[383:0\] | input | The input private key used in the signing operation. | +| pubKey_in\[1:0\]\[383:0\] | input | The input public key(x,y) used in the verifying operation. | +| hashed_msg\[383:0\] | input | The hash of message using SHA384. | +| ready | output | When HIGH, the signal indicates the core is ready. | +| privKey_out\[383:0\] | output | The generated private key in the KeyGen operation. | +| pubKey_out\[1:0\]\[383:0\] | output | The generated public key(x,y) in the KeyGen operation. | +| r\[383:0\] | output | The signature value of the given priveKey/message. | +| s\[383:0\] | output | The signature value of the given priveKey/message. | +| r’\[383:0\] | Output | The signature verification result. | +| valid | output | When HIGH, the signal indicates the result is ready. | + +### Address map + +The ECDSA address map is shown here: [ecc\_reg — clp Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=clp.ecc_reg). + +### Pseudocode + +The following pseudocode blocks demonstrate example implementations for KeyGen, Signing, and Verifying. + +#### KeyGen + +*Figure 35: KeyGen pseudocode* + +#### Signing + +*Figure 36: Signing pseudocode* + +#### Verifying + +*Figure 37: Verifying pseudocode* + +### SCA countermeasure + +The described ECDSA has three main routines: KeyGen, Signing, and Verifying. Since the Verifying routine requires operation with public values rather than a secret value, our side-channel analysis does not cover this routine. Our evaluation covers the KeyGen and Signing routines where the secret values are processed. + +KeyGen consists of HMAC DRBG and scalar multiplication, while Signing first requires a message hashing and then follows the same operations as KeyGen (HMAC DRBG and scalar multiplication). The last step of Signing is generating “S” as the proof of signature. Since HMAC DRBG and hash operations are evaluated separately in our document, this evaluation covers scalar multiplication and modular arithmetic operations. + +#### Scalar multiplication + +To perform the scalar multiplication, the Montgomery ladder is implemented, which is inherently resistant to timing and single power analysis (SPA) attacks. + +Implementation of complete unified addition formula for the scalar multiplication avoids information leakage and enhances architecture from security and mathematical perspectives. + +To protect the architecture against horizontal power/electromagnetic (EM) and differential power analysis (DPA) attacks, several countermeasures are embedded in the design [9]. Since these countermeasures require random inputs, HMAC-DRBG is fed by IV to generate these random values. + +Since HMAC-DRBG generates random value in a deterministic way, firmware MUST feed different IV to ECC engine for EACH keygen and signing operation. + +#### Base point randomization + +This countermeasure is achieved using the randomized base point in projective coordinates. Hence, the base point G=(Gx, Gy) in affine coordinates is transformed and randomized to projective coordinates as (X, Y, Z) using a random value as follows: + +This approach does not have the performance or area overhead because the architecture is variable-base-point implemented. + +#### Scalar blinding + +This countermeasure is achieved by randomizing the scalar as follows: + +Based on [10], half of the bit size of is required to prevent advanced DPA attacks. Therefore, has 192 bits, and the blinded scalar has 576 bits. Hence, this countermeasure extends the Montgomery ladder iterations due to extended scalar. + +This approach is achieved at the cost of 50% more latency on scalar multiplication and adding one lightweight block, including one 32\*32 multiplier and an accumulator. + +Note: the length of rand is configurable to have a trade-off between the required protection and performance. + +#### Making countermeasures embedded into HMAC\_DRBG + +In the first step of the KeyGen operation, the privkey is generated using HMAC\_DRBG by feeding the following two inputs: seed and nonce. To avoid SCA information leakage during this operation, we embed masking countermeasures into the HMAC\_DRBG architecture. + +Each round of SHA512 execution needs 6,432 random bits, and one HMAC operation needs at least 4 rounds of SHA512 operations. Furthermore, each HMAC\_DRBG round needs at least 5 rounds of HMAC operations. However, the proposed architecture uses a lightweight LFSR and provides first-order DPA attack protection with negligible latency and hardware resource overhead. + +#### ECDSA signing nonce leakage + +Generating “S” as the proof of signature at the steps of the signing operation leaks where the hashed message is signed with private key and ephemeral key as follows: + +Since the given message is known or the signature part r is known, the attacker can perform a known-plaintext attack. The attacker can sign multiple messages with the same key, or the attacker can observe part of the signature that is generated with multiple messages but the same key. + +The evaluation shows that the CPA attack can be performed with a small number of traces, respectively. Thus, an arithmetic masked design for these operations is implemented. + +##### Masking signature + +This countermeasure is achieved by randomizing the privkey as follows: + +Although computation of “S” seems the most vulnerable point in our scheme, the operation does not have a big contribution to overall latency. Hence, masking these operations has low overhead on the cost of the design. + +#### Random number generator for SCA countermeasure + +The ECC countermeasure requires several random vectors to randomize the intermediate values, as described in the preceding section. HMAC\_DRBG is used to take one random vector of 384-bit (i.e., ECC\_IV register) and to generate the required random vectors for different countermeasures. + +The state machine of HMAC\_DRBG utilization is shown in the following figure, including three main states: + +1. SCA random generator: Running HMAC\_DRBG with IV and an internal counter to generate the required random vectors. +2. KEYGEN PRIVKEY: Running HMAC\_DRBG with seed and nonce to generate the privkey in KEYGEN operation. +3. SIGNING NONCE: Running HMAC\_DRBG based on RFC6979 in SIGNING operation with privkey and hashed\_msg. + +*Figure 38: HMAC\_DRBG utilization* + +In SCA random generator state: + +* This state (in KeyGen operation mode) generates 3 384-bit random vectors for the following: LFSR, base point randomization, and scalar blinding randomization. +* This state (in signing operation) generates 4 384-bit random vectors for the following: LFSR, base point randomization, scalar blinding, and masking signature randomization. +* HMAC\_DRBG is initialized with IV and an internal counter. This 64-bit counter enables after reset and zeroization and contains different values depending on when ECC is called. +* HMAC\_DRBG is enabled by the INIT command. To generate all required vectors, HMAC-DRBG is continued by the NEXT command that increments the built-in counter inside the HMAC-DRBG unit. +* To initialize the required seed for LFSR, LFSR\_INIT\_SEED is set as a constant by RTL after reset and zeroization. However, this value is updated before enabling HMAC\_DRBG as follows: + * In the first execution of HMAC\_DRBG after reset and zeroization, hmac\_lfsr\_seed is equal to LFSR\_INIT\_SEED XORed by internal 64-bit counter. + * In the next executions of HMAC\_DRBG, hmac\_lfsr\_seed is equal to HMAC\_DRBG output of the first execution XORed by internal 64-bit counter. + +The data flow of the HMAC\_DRBG operation in keygen operation mode is shown in the following figure. + +*Figure 39: HMAC\_DRBG data flow* + +#### TVLA results + +Test vector leakage assessment (TVLA) provides a robust test using a 𝑡-test. This test evaluates the differences between sets of acquisitions to determine if one set of measurement can be distinguished from the other. This technique can detect different types of leakages, providing a clear indication of leakage or lack thereof. + +In practice, observing a t-value greater than a specific threshold (mainly 4.5) indicates the presence of leakage. However, in ECC, due to its latency, around 5 million samples are required to be captured. This latency leads to many false positives and the TVLA threshold can be considered a higher value than 4.5. Based on the following figure from “Side-Channel Analysis and Countermeasure Design for Implementation of Curve448 on Cortex-M4” by Bisheh-Niasar et. al., the threshold can be considered equal to 7 in our case. + +*Figure 40: TVLA threshold as a function of the number of samples per trace* + +##### Keygen TVLA + +TODO: provide content for this section + + +##### Signing TVLA + +The TVLA results for performing privkey-dependent leakage detection using 20,000 traces is shown in the following figure. Based on this figure, there is no leakage in ECC signing by changing the privkey after 20,000 operations. + +*Figure 41: privkey-dependent leakage detection using TVLA for ECC signing after 20,000 traces* + +The TVLA results for performing message-dependent leakage detection using 64,000 traces is shown in the following figure. Based on this figure, there is no leakage in ECC signing by changing the message after 64,000 operations. + +*Figure 42: Message-dependent leakage detection using TVLA for ECC signing after 64,000 traces* + +The point with t-value equal to -40 is mapped to the Montgomery conversion of the message that is a publicly known value (no secret is there). By ignoring those corresponding samples, there are some sparse samples with a t-value greater than 7, as shown in the following table. + +| Sample | Duration | Cycle | t-value | Operation | +| :-------- | :--------- | :-------- | :------ | :---------------------- | +| 4,746,127 | 214 | 911,381.4 | 11.2 | start of mont_conv(msg) | +| 4,746,341 | | 911,422.5 | -40 | end of mont_conv(msg) | +| 4,757,797 | 1 | 913,622.0 | 7.4 | inv_q | +| 4,768,302 | 1 | 915,639.0 | 7.8 | inv_q | +| 4,779,610 | 1 | 917,810.1 | -9.1 | inv_q | +| 4,788,120 | 1 | 919,444.0 | 7.6 | inv_q | +| 4,813,995 | 1 | 924,412.0 | 7.3 | inv_q | +| 4,822,693 | 1 | 926,082.1 | 7.5 | inv_q | +| 4,858,671 | to the end | 932,989.8 | -7.6 | Ended ECC signing | + +### Performance + +The ECC core performance is reported in the next section. + +### Pure hardware architecture + +In this architecture, the ECC interface and controller are implemented in hardware. The performance specification of the ECC architecture is reported as shown in the following table. + +| Operation | Cycle count \[CCs\] | Time \[ms\] @ 400 MHz | Throughput \[op/s\] | +| :-------- | :------------------ | :-------------------- | :------------------ | +| Keygen | 909,648 | 2.274 | 439 | +| Signing | 932,990 | 2.332 | 428 | +| Verifying | 1,223,938 | 3.060 | 326 | +## PCR vault + +* Platform Configuration Register (PCR) vault is a register file that stores measurements to be used by the microcontroller. +* PCR entries are read-only registers of 384 bits each. +* Control bits allow for entries to be cleared by FW, which sets their values back to 0. +* A lock bit can be set by FW to prevent the entry from being cleared. The lock bit is sticky and only resets on a powergood cycle. + +| PCRV register | Address Offset | Description | +| :---------------------------------| :------------- | :----------------------------- | +| PCR Control\[31:0\] | 0x1001a000 | 32 Control registers, 32 bits each | +| PCR Entry\[31:0\]\[11:0\]\[31:0\] | 0x1001a600 | 32 PCR entries, 384 bits each | + +### PCR vault functional block + +PCR entries are hash extended using a hash extension function. The hash extension function takes the data currently in the PCR entry specified, concatenates data provided by the FW, and performs a SHA384 function on that data, storing the result back into the same PCR entry. + +### PCR hash extend function + +FW provides the PCR entry to use as source and destination of the hash extend. HW copies the PCR into the start of the SHA block and locks those dwords from FW access. FW then provides the new data, and runs the SHA function as usual. After initialization, the locked dwords are unlocked. + +FW must set a last cycle flag before running the last iteration of the SHA engine. This could be the first “init” cycle, or the Nth “next” cycle. This flag allows HW to copy the final resulting hash output back to the source PCR. + +### PCR signing + +* PCR signing uses the key in key slot index 7 for PCR signing +* HW implements a HW function called GEN\_PCR\_HASH + * HW reads all the PCRs from all the PCR slots and hash extends them along with the NONCE that Caliptra FW provides + * PCR Hash = Hash(PCR[0], …, PCR[31], Nonce) +* HW also implements a HW function called SIGN\_PCR. This function takes the PCR digest that was generated by the previous routine and signs it using the key in key slot 7, following the same ECC sign flow defined in the [ECC](#ecc) section. + * The resulting PCR DIGEST is used only once for signing by the HW. If a new PCR signing is required, GEN\_PCR\_HASH needs to be redone. + +## Key vault + +Key Vault (KV) is a register file that stores the keys to be used by the microcontroller, but this register file is not observed by the microcontroller. Each cryptographic function has a control register and functional block designed to read from and write to the KV.  + +| KV register | Description | +| :------------------------------- | :------------------------------------------------------- | +| Key Control\[7:0\] | 8 Control registers, 32 bits each | +| Key Entry\[7:0\]\[15:0\]\[31:0\] | 8 Key entries, 512 bits each
No read or write access | + +### Key vault functional block + +Keys and measurements are stored in 512b register files. These have no read or write path from the microcontroller. The entries are read through a passive read mux driven by each cryptographic block. Locked entries return zeroes.  + +Entries in the KV must be cleared via control register, or by de-assertion of pwrgood.   + +Each entry has a control register that is writable by the microcontroller.  + +The destination valid field is programmed by FW in the cryptographic block generating the key, and it is passed here at generation time. This field cannot be modified after the key is generated and stored in the KV.  + +| KV Entry Ctrl Fields  | Reset  | Description  | +|---------------------------|-------------------|------------------------| +| Lock wr\[0\]  | core_only_rst_b   | Setting the lock wr field prevents the entry from being written by the microcontroller. Keys are always locked. After a lock is set, it cannot be reset until cptra_rst_b is de-asserted.  | +| Lock use\[1\]  | core_only_rst_b   | Setting the lock use field prevents the entry from being used in any cryptographic blocks. After the lock is set, it cannot be reset until cptra_rst_b is de-asserted. | +| Clear\[2\]  | cptra_rst_b  | If unlocked, setting the clear bit causes KV to clear the associated entry. The clear bit is reset after entry is cleared.  | +| Copy\[3\]  | cptra_rst_b  | ENHANCEMENT: Setting the copy bit causes KV to copy the key to the entry written to Copy Dest field.  | +| Copy Dest\[8:4\]  | cptra_rst_b  | ENHANCEMENT: Destination entry for the copy function.  | +| Dest_valid\[16:9\]  | hard_reset_b | KV entry can be used with the associated cryptographic block if the appropriate index is set.
\[0\] - HMAC KEY
\[1\] - HMAC BLOCK
\[2\] - SHA BLOCK
\[2\] - ECC PRIVKEY
\[3\] - ECC SEED
\[7:5\] - RSVD | +| last_dword\[20:19\] | hard_reset_b | Store the offset of the last valid dword, used to indicate the last cycle for read operations. | + +### Key vault cryptographic functional block  + +A generic block is instantiated in each cryptographic block to enable access to KV.  + +Each input to a cryptographic engine can have a key vault read block associated with it. The KV read block takes in a keyvault read control register that drives an FSM to copy an entry from the keyvault into the appropriate input register of the cryptographic engine. + +Each output generated by a cryptographic engine can have its result copied to a slot in the keyvault. The KV write block takes in a keyvault write control register. This register drives an FSM to copy the result from the cryptographic engine into the appropriate keyvault entry. It also programs a control field for that entry to indicate where that entry can be used. + +After programming the key vault read control, FW needs to query the associated key vault read status to confirm that the requested key was copied successfully. After valid is set and the error field reports success, the key is ready to be used. + +Similarly, after programming the key vault write control and initiating the cryptographic function that generates the key to be written, FW needs to query the associated key vault write status to confirm that the requested key was generated and written successfully. + +The following tables describe read, write, and status values for key vault blocks. + +| KV Read Ctrl Reg | Description | +| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| read_en\[0\] | Indicates that the read data is to come from the key vault. Setting this bit to 1 initiates copying of data from the key vault. | +| read_entry\[5:1\] | Key vault entry to retrieve the read data from the engine. | +| pcr_hash_extend\[6\] | Requested entry is a PCR. This is used only for the SHA engine to hash extend. It is not functional in any other cryptographic engine. | +| rsvd\[31:7\] | Reserved field | + +| KV Write Ctrl Reg | Description | +| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| write_en\[0\] | Indicates that the result is to be stored in the key vault. Setting this bit to 1 copies the result to the key vault when it is ready. | +| write_entry\[5:1\] | Key vault entry to store the result. | +| hmac_key_dest_valid\[6\] | HMAC KEY is a valid destination. | +| hmac_block_dest_valid\[7\] | HMAC BLOCK is a valid destination. | +| sha_block_dest_valid\[8\] | SHA BLOCK is a valid destination. | +| ecc_pkey_dest_valid\[9\] | ECC PKEY is a valid destination. | +| ecc_seed_dest_valid\[10\] | ECC SEED is a valid destination. | +| rsvd\[31:11\] | Reserved field | + +| KV Status Reg | Description | +| :------------ | :---------------------------------------------------------------------------------------------------------------------------------------------- | +| ready\[0\] | Key vault control is idle and ready for a command. | +| valid\[1\] | Requested flow is done. | +| error\[9:2\] | SUCCESS - 0x0 - Key Vault flow was successful
KV_READ_FAIL - 0x1 - Key Vault Read flow failed
KV_WRITE_FAIL - 0x2 - Key Vault Write flow failed | + +### De-obfuscation engine + +To protect software intellectual property from different attacks and, particularly, for thwarting an array of supply chain threats, code obfuscation is employed. Hence, the de-obfuscation engine is implemented to decrypt the code. + +Advanced Encryption Standard (AES) is used as a de-obfuscation function to encrypt and decrypt data [4]. The hardware implementation is based on[ Secworks/aes](https://github.com/secworks/aes) [1]. The implementation supports the two variants: 128- and 256-bit keys with a block/chunk size of 128 bits. + +The AES algorithm is described as follows: + +* The key is fed to an AES core to compute and initialize the round key +* The message is broken into 128-bit chunks by the host +* For each chunk: + * The message is fed to the AES core + * The AES core and its working mode (enc/dec) are triggered by the host + * The AES core status is changed to ready after encryption or decryption processing +* The result digest can be read before processing the next message chunks + + +### Key vault de-obfuscation block operation + +A de-obfuscation engine (DOE) is used in conjunction with AES cryptography to de-obfuscate the UDS and field entropy.   + +1. The obfuscation key is driven to the AES key. The data to be decrypted (either obfuscated UDS or obfuscated field entropy) is fed into the AES data.  +2. An FSM manually drives the AES engine and writes the decrypted data back to the key vault.  +3. FW programs the DOE with the requested function (UDS or field entropy de-obfuscation), and the destination for the result.  +4. After de-obfuscation is complete, FW can clear out the UDS and field entropy values from any flops until cptra\_pwrgood de-assertion.   + +The following tables describe DOE register and control fields. + +| DOE Register | Address | Description  | +| :----------- | :--------- | :----------------------------------------------------------------------------------------------------------------------------- | +| IV | 0x10000000 | 128 bit IV for DOE flow. Stored in big-endian representation. | +| CTRL | 0x10000010 | Controls for DOE flows. | +| STATUS | 0x10000014 | Valid indicates the command is done and results are stored in keyvault. Ready indicates the core is ready for another command. | + +| DOE Ctrl Fields  | Reset  | Description  | +| :--------------- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------- | +| COMMAND\[1:0\]  | Cptra_rst_b  | 2’b00 Idle 
2’b01 Run UDS flow 
2’b10 Run FE flow 
2’b11 Clear Obf Secrets | +| DEST\[4:2\]  | Cptra_rst_b  | Destination register for the result of the de-obfuscation flow. Field entropy writes into DEST and DEST+1 
Key entry only, can’t go to PCR . | + +### Key vault de-obfuscation flow  + +1. ROM loads IV into DOE. ROM writes to the DOE control register the destination for the de-obfuscated result and sets the appropriate bit to run UDS and/or the field entropy flow.  +2. DOE state machine takes over and loads the Caliptra obfuscation key into the key register.  +3. Next, either the obfuscated UDS or field entropy are loaded into the block register 4 DWORDS at a time.  +4. Results are written to the KV entry specified in the DEST field of the DOE control register.  +5. State machine resets the appropriate RUN bit when the de-obfuscated key is written to KV. FW can poll this register to know when the flow is complete. +6. The clear obf secrets command flushes the obfuscation key, the obfuscated UDS, and the field entropy from the internal flops. This should be done by ROM after both de-obfuscation flows are complete. + +## Data vault + +Data vault is a set of generic scratch pad registers with specific lock functionality and clearable on cold and warm resets. + +* 48B scratchpad registers that are lockable but cleared on cold reset (10 registers) +* 48B scratchpad registers that are lockable but cleared on warm reset (10 registers) +* 4B scratchpad registers that are lockable but cleared on cold reset (8 registers) +* 4B scratchpad registers that are lockable but cleared on warm reset (10 registers) +* 4B scratchpad registers that are cleared on warm reset (8 registers) + +## Cryptographic blocks fatal and non-fatal errors + +The following table describes cryptographic errors. + +| Errors | Error type | Description | +| :--------- | :----------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ECC_R_ZERO | HW_ERROR_NON_FATAL | Indicates a non-fatal error in ECC signing if the computed signature R is equal to 0. FW should change the message or privkey to perform a valid signing. | + +# Terminology + +The following terminology is used in this document. + +| Abbreviation | Description | +| :----------- | :--------------------------------------------- | +| AES | Advanced Encryption Standard | +| BMC | Baseboard Management Controller | +| CA | Certificate Authority | +| CDI | Composite Device Identifier | +| CPU | Central Processing Unit | +| CRL | Certificate Revocation List | +| CSR | Certificate Signing Request | +| CSP | Critical Security Parameter | +| DICE | Device Identifier Composition Engine | +| DME | Device Manufacturer Endorsement | +| DPA | Differential Power Analysis | +| DRBG | Deterministic Random Bit Generator | +| DWORD | 32-bit (4-byte) data element | +| ECDSA | Elliptic Curve Digital Signature Algorithm | +| FMC | FW First Mutable Code | +| FSM | Finite State Machine | +| GPU | Graphics Processing Unit | +| HMAC | Hash-based message authentication code | +| IDevId | Initial Device Identifier | +| iRoT | Internal RoT | +| IV | Initial Vector | +| KAT | Known Answer Test | +| KDF | Key Derivation Function | +| LDevId | Locally Significant Device Identifier | +| MCTP | Management Component Transport Protocol | +| NIC | Network Interface Card | +| NIST | National Institute of Standards and technology | +| OCP | Open Compute Project | +| OTP | One-time programmable | +| PCR | Platform Configuration Register | +| PKI | Public Key infrastructure | +| PUF | Physically unclonable function | +| RNG | Random Number Generator | +| RoT | Root of Trust | +| RTI | RoT for Identity | +| RTM | RoT for Measurement | +| RTR | RoT for Reporting | +| SCA | Side-Channel Analysis | +| SHA | Secure Hash Algorithm | +| SoC | System on Chip | +| SPA | Simple Power Analysis | +| SPDM | Security Protocol and Data Model | +| SSD | Solid State Drive | +| TCB | Trusted Computing Base | +| TCI | TCB Component Identifier | +| TCG | Trusted Computing Group | +| TEE | Trusted Execution Environment | +| TRNG | True Random Number Generator | +| UECC | Uncorrectable Error Correction Code | + +# References + +1. J. Strömbergson, "Secworks," \[Online\]. Available at https://github.com/secworks. +2. NIST, Federal Information Processing Standards Publication (FIPS PUB) 180-4 Secure Hash Standard (SHS). +3. OpenSSL \[Online\]. Available at https://www.openssl.org/docs/man3.0/man3/SHA512.html. +4. N. W. Group, RFC 3394, Advanced Encryption Standard (AES) Key Wrap Algorithm, 2002. +5. NIST, Federal Information Processing Standards Publication (FIPS) 198-1, The Keyed-Hash Message Authentication Code, 2008. +6. N. W. Group, RFC 4868, Using HMAC-SHA256, HMAC-SHA384, and HMAC-SHA512 with IPsec, 2007. +7. RFC 6979, Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA), 2013. +8. TCG, Hardware Requirements for a Device Identifier Composition Engine, 2018. +9. Coron, J.-S.: Resistance against differential power analysis for elliptic curve cryptosystems. In: Ko¸c, C¸ .K., Paar, C. (eds.) CHES 1999. LNCS, vol. 1717, pp. 292–302. +10. Schindler, W., Wiemers, A.: Efficient side-channel attacks on scalar blinding on elliptic curves with special structure. In: NISTWorkshop on ECC Standards (2015). +11. National Institute of Standards and Technology, "Digital Signature Standard (DSS)", Federal Information Processing Standards Publication (FIPS PUB) 186-4, July 2013. +12. NIST SP 800-90A, Rev 1: "Recommendation for Random Number Generation Using Deterministic Random Bit Generators", 2012. | +13. CHIPS Alliance, “RISC-V VeeR EL2 Programmer’s Reference Manual” \[Online\] Available at https://github.com/chipsalliance/Cores-VeeR-EL2/blob/main/docs/RISC-V_VeeR_EL2_PRM.pdf. +14. “The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document Version 20191213”, Editors Andrew Waterman and Krste Asanovi ́c, RISC-V Foundation, December 2019. Available at https://riscv.org/technical/specifications/. +15. “The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 20211203”, Editors Andrew Waterman, Krste Asanovi ́c, and John Hauser, RISC-V International, December 2021. Available at https://riscv.org/technical/specifications/. + +[1] _Caliptra.** **Spanish for “root cap” and describes the deepest part of the root_ diff --git a/docs/CaliptraIntegrationSpecification.md b/docs/CaliptraIntegrationSpecification.md new file mode 100644 index 000000000..e270db4e3 --- /dev/null +++ b/docs/CaliptraIntegrationSpecification.md @@ -0,0 +1,898 @@ +![OCP Logo](./images/OCP_logo.png) + +

Caliptra Integration Specification

+ +

Version 1.0-rc1

+ +
+ +# Scope + +This document describes the Caliptra hardware implementation requirements, details, and release notes. This document is intended for a high-level overview of the IP used in Caliptra. + +This document is not intended for any micro-architectural design specifications. Detailed information on each of the IP components are shared in individual documents, where applicable. + +# Overview + +This document contains high level information on the Caliptra hardware design. The details include open-source IP information, configuration settings for open-source IP (if applicable), and IP written specifically for Caliptra. + +For more information, see[ Caliptra: A Datacenter System on a Chip (SoC) Root of Trust (RoT)](https://chipsalliance.github.io/Caliptra/doc/Caliptra.html). + +## References and related specifications + +The blocks described in this document are either obtained from open-source GitHub repositories, developed from scratch, or modification of open-source implementations. Links to relevant documentation and GitHub sources are shared in the following table. + +*Table 1: Related specifications* + +| IP/Block | GitHub URL | Documentation | Link | +| :--------- | :--------- | :--------- |:--------- | +| Cores-VeeR | [GitHub - chipsalliance/Cores-VeeR-EL2](https://github.com/chipsalliance/Cores-VeeR-EL2) | VeeR EL2 Programmer’s Reference Manual | [chipsalliance/Cores-VeeR-EL2 · GitHubPDF](http://cores-swerv-el2/RISC-V_SweRV_EL2_PRM.pdf%20at%20master%20%C2%B7) | +| AHB Lite Bus | [aignacio/ahb_lite_bus: AHB Bus lite v3.0 (github.com)](https://github.com/aignacio/ahb_lite_bus) | AHB Lite Protocol
[Figure 2: SoC interface block diagram](#soc-interface-definition) | [ahb_lite_bus/docs at master · aignacio/ahb_lite_bus (github.com)](https://github.com/aignacio/ahb_lite_bus/tree/master/docs)
[ahb_lite_bus/diagram_ahb_bus.png at master · aignacio/ahb_lite_bus (github.com)](https://github.com/aignacio/ahb_lite_bus/blob/master/diagram_ahb_bus.png) | +| SHA 256 | [secworks/sha256: Hardware implementation of the SHA-256 cryptographic hash function (github.com)](https://github.com/secworks/sha256) | | | +| SHA 512 | | | | +| SPI Controller | | | | + +# Caliptra Core + +The following figure shows the Caliptra Core. + +*Figure 1: Caliptra block diagram* + +![](./images/Caliptra_HW_diagram.png) + +## Boot Media Dependent (passive) vs Boot Media Integrated (active) profile + +In the BMD profile, QSPI and I3C IO peripherals are disabled using integration-time defines passed to the hardware, which are also exposed to ROM. Peripheral IOs can be tied off appropriately for the BMD profile at SoC integration time. For more information on the BMD vs. BMI profile differences, see the boot flows in [Caliptra profiles](https://chipsalliance.github.io/Caliptra/doc/Caliptra.html#caliptra-profiles). Only the BMD profile is supported for the first generation release of Caliptra. + +# SoC interface definition + +The following figure shows the SoC interface definition. + +*Figure 2: SoC Interface Block Diagram* + +![](./images/Caliptra_soc_interface_block.png) + +## Integration parameters + +The following table describes integration parameters. + +*Table 2: Integration parameters* + +| **Parameter name** | **Width** | **Defines file** | **Description** | +| :--------- | :--------- | :--------- | :--------- | +| CPTRA_SET_MBOX_PAUSER_INTEG | 5 | soc_ifc_pkg.sv | Each bit hardcodes the valid PAUSER for mailbox at integration time. | +| CPTRA_MBOX_VALID_PAUSER | \[4:0\]\[31:0\] | soc_ifc_pkg.sv | Each parameter corresponds to a hardcoded valid PAUSER value for mailbox, set at integration time. Must set corresponding bit in the CPTRA_SET_MBOX_PAUSER_INTEG parameter for this valid pauser override to be used. | +| CPTRA_DEF_MBOX_VALID_PAUSER | 32 | soc_ifc_pkg.sv | Sets the default valid PAUSER for mailbox accesses. This PAUSER is valid when any VALID_PAUSER is unlocked or not set by INTEG parameter. | +| CPTRA_SET_FUSE_PAUSER_INTEG | 1 | soc_ifc_pkg.sv | Sets the valid PAUSER for fuse accesses at integration time. | +| CPTRA_FUSE_VALID_PAUSER | 32 | soc_ifc_pkg.sv | Overrides the programmable valid PAUSER for fuse accesses when CPTRA_SET_FUSE_PAUSER_INTEG is set to 1. | + +*Table 3: Integration Defines* + +| **Defines** | **Defines file** | **Description** | +| :--------- | :--------- | :--------- | +| CALIPTRA_APB_ADDR_WIDTH | config_defines.svh | Width of the APB Address field. Default to 32. | +| CALIPTRA_APB_DATA_WIDTH | config_defines.svh | Width of the APB Data field. Default to 32. | +| CALIPTRA_APB_USER_WIDTH | config_defines.svh | Width of the APB PAUSER field. | +| CALIPTRA_INTERNAL_TRNG | config_defines.svh | Defining this enables the internal TRNG source. | +| CALIPTRA_INTERNAL_UART | config_defines.svh | Defining this enables the internal UART. | +| CALIPTRA_INTERNAL_QSPI | config_defines.svh | Defining this enables the internal QSPI. | + +## Interface + +The following tables describe the interface signals. + +*Table 4: Clocks and resets* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description| +| :--------- | :--------- | :--------- | :--------- | :--------- | +| cptra_pwrgood | 1 | Input | Asynchronous Assertion
Synchronous deassertion to clk | Active high power good indicator.
Deassertion hard resets Caliptra. | +| cptra_rst_b | 1 | Input | Asynchronous Assertion
Synchronous deassertion to clk | Active low asynchronous reset. | +| clk | 1 | Input | | Convergence and validation done at 400MHz. All other frequencies are up to the user. | + +*Table 5: APB Interface* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| PADDR | 32 | Input | Synchronous to clk | Address bus | +| PPROT | 3 | Input | Synchronous to clk | Protection level | +| PSEL | 1 | Input | Synchronous to clk | Select line | +| PENABLE | 1 | Input | Synchronous to clk | Indicates the second and subsequent cycles. | +| PWRITE | 1 | Input | Synchronous to clk | Indicates transfer is a write when high or a read when low. | +| PWDATA | 32 | Input | Synchronous to clk | Write data bus | +| PAUSER | APB_USER_REQ_WIDTH | Input | Synchronous to clk | Sideband signal indicating requestor ID for transfer. | +| PREADY | 1 | Output | Synchronous to clk | Used to extend an APB transfer by completer. | +| PRDATA | 32 | Output | Synchronous to clk | Read data bus | +| PSLVERR | 1 | Output | Synchronous to clk | Transfer error | + +*Table 6: QSPI signals* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| qspi_clk_o | 1 | Output | | QSPI clock | +| qspi_cs_no | 2 | Output | Synchronous to qspi_clk_o | QSPI chip select | +| qspi_d_i | 4 | Input | Synchronous to qspi_clk_o | QSPI data lanes for receiving data. | +| qspi_d_o | 4 | Output | Synchronous to qspi_clk_o | QSPI data output lanes for sending opcode and address. | +| qspi_d_en_o | 4 | Output | Synchronous to qspi_clk_o | QSPI enable pins to control data direction. | + +*Table 7: Mailbox notifications* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| ready_for_fuses | 1 | Output | Synchronous to clk | Indicates that Caliptra is ready for fuse programming. | +| ready_for_fw_push | 1 | Output | Synchronous to clk | Indicates that Caliptra is ready for firmware. | +| ready_for_runtime | 1 | Output | Synchronous to clk | Indicates that Caliptra firmware is ready for RT flow. | +| mailbox_data_avail | 1 | Output | Synchronous to clk | Indicates that the mailbox has data for SoC to read (reflects the value of the register). | +| mailbox_flow_done | 1 | Output | Synchronous to clk | Indicates that the mailbox flow is complete (reflects the value of the register). | + +*Table 8: SRAM interface* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| mbox_sram_cs | 1 | Output | Synchronous to clk | Chip select for mbox SRAM | +| mbox_sram_we | 1 | Output | Synchronous to clk | Write enable for mbox SRAM | +| mbox_sram_addr | MBOX_ADDR_W | Output | Synchronous to clk | Addr lines for mbox SRAM | +| mbox_sram_wdata | MBOX_DATA_W | Output | Synchronous to clk | Write data for mbox SRAM | +| mbox_sram_rdata | MBOX_DATA_W | Input | Synchronous to clk | Read data for mbox SRAM | +| imem_cs | 1 | Output | Synchronous to clk | Chip select for imem SROM | +| imem_addr | IMEM_ADDR_WIDTH | Output | Synchronous to clk | Addr lines for imem SROM | +| imem_rdata | IMEM_DATA_WIDTH | Input | Synchronous to clk | Read data for imem SROM | +| iccm_clken | ICCM_NUM_BANKS | Input | Synchronous to clk | Per-bank clock enable | +| iccm_wren_bank | ICCM_NUM_BANKS | Input | Synchronous to clk | Per-bank write enable | +| iccm_addr_bank | ICCM_NUM_BANKS x (ICCM_BITS-4) | Input | Synchronous to clk | Per-bank address | +| iccm_bank_wr_data | ICCM_NUM_BANKS x 39 | Input | Synchronous to clk | Per-bank input data | +| iccm_bank_dout | ICCM_NUM_BANKS x 39 | Output | Synchronous to clk | Per-bank output data | +| dccm_clken | DCCM_NUM_BANKS | Input | Synchronous to clk | Per-bank clock enable | +| dccm_wren_bank | DCCM_NUM_BANKS | Input | Synchronous to clk | Per-bank write enable | +| dccm_addr_bank | DCCM_NUM_BANKS x (DCCM_BITS-4) | Input | Synchronous to clk | Per-bank address | +| dccm_wr_data_bank | DCCM_NUM_BANKS x DCCM_FDATA_WIDTH | Input | Synchronous to clk | Per-bank input data | +| dccm_bank_dout | DCCM_NUM_BANKS x DCCM_FDATA_WIDTH | Output | Synchronous to clk | Per-bank output data | + +*Table 9: JTAG interface* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| jtag_tck | 1 | input | | | +| jtag_tms | 1 | input | Synchronous to tck | | +| jtag_tdi | 1 | input | Synchronous to tck | | +| jtag_trst_n | 1 | input | Async Deassertion
Assertion Synchronous to tck | | +| jtag_tdo | 1 | output | Synchronous to tck | | + +*Table 10: UART interface* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| uart_tx | 1 | output | | UART transmit pin | +| uart_rx | 1 | input | | UART receive pin | + +*Table 11: Security and miscellaneous* + +| Signal name | Width | Driver | Synchronous (as viewed from Caliptra’s boundary) | Description | +| :--------- | :--------- | :--------- | :--------- | :--------- | +| CPTRA_OBF_KEY | 256 | Input Strap | Asynchronous | Obfuscation key is driven by SoC at integration time. Ideally this occurs just before tape-in and the knowledge of this key must be protected unless PUF is driving this. The key is latched by Caliptra on caliptra powergood deassertion. It is cleared after its use and can only re-latched on a power cycle (powergood deassertion to assertion). | +| SECURITY_STATE | 3 | Input Strap | Synchronous to clk | Security state that Caliptra should take (for example, manufacturing, secure, unsecure, etc.). The key is latched by Caliptra on cptra_noncore_rst_b deassertion. Any time the state changes to debug mode, all keys, assets, and secrets stored in fuses or key vault are cleared. Cryptography core states are also flushed if they were being used. | +| scan_mode | 1 | Input Strap | Synchronous to clk | Must be set before entering scan mode. This is a separate signal than the scan chain enable signal that goes into scan cells. This allows Caliptra to flush any assets or secrets present in key vault and flops if the transition is happening from a secure state. | +| GENERIC_INPUT_WIRES | 64 | Input | Synchronous to clk | Placeholder of input wires for late binding features. These values are reflected into registers that are exposed to firmware. | +| GENERIC_OUTPUT_WIRES | 64 | Output | Synchronous to clk | Placeholder of output wires for late binding features. Firmware can set the wires appropriately via register writes. | +| CALIPTRA_ERROR_FATAL | 1 | Output | Synchronous to clk | Indicates a fatal error from Caliptra. | +| CALIPTRA_ERROR_NON_FATAL | 1 | Output | Synchronous to clk | Indicates a non fatal error from Caliptra. | +| BootFSM_BrkPoint | 1 | Input Strap | Asynchronous | Stops the BootFSM to allow TAP writes set up behavior. Examples of these behaviors are skipping or running ROM flows, or stepping through BootFSM. | +| eTRNG_REQ | 1 | Output | Synchronous to clk | External source mode: TRNG_REQ to SoC. SoC writes to TRNG architectural registers with a NIST-compliant entropy.
Internal source mode: TRNG_REQ to SoC. SoC enables external RNG digital bitstream input into iTRNG_DATA/iTRNG_VALID. | +| iTRNG_DATA | 4 | Input | Synchronous to clk | External source mode: Not used.
Internal source mode only: RNG digital bit stream from SoC, which is sampled when iTRNG_VALID is high. | +| iTRNG_VALID | 1 | Input | Synchronous to clk | External source mode: Not used.
Internal source mode only: RNG bit valid. This is valid per transaction. TRNG_DATA can be sampled whenever this bit is high. The expected iTRNG_VALID output rate is about 50KHz. | + +## Architectural registers and fuses + +Control registers and fuses are documented on GitHub. + +* External Registers: [caliptra\_top\_reg — caliptra\_top\_reg Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/external-regs/?p=) +* Internal Registers - [clp — clp Reference (chipsalliance.github.io)](https://chipsalliance.github.io/caliptra-rtl/main/internal-regs/?p=) + +## Fuses + +Fuses are writable only one time and require a cptra\_pwrgood to be recycled to be written again. + +After all fuses are written, the fuse done register at the end of the fuse address space must be set to 1 to lock the fuse writes and to proceed with the boot flow. + +Although fuse values (and the fuse done register) persist across a warm reset, SoC is still required to perform a write to the fuse done register while in the BOOT\_FUSE state in order to complete the bringup from reset. See 6.1 Boot FSM for further details. + +## Interface rules + +The following figure shows the reset rules and timing. + +*Figure 3: Reset rules and timing diagram* + +![](./images/Caliptra_reset_timing.png) + +Deassertion of cptra\_pwrgood indicates a power cycle that results in returning Caliptra to its default state. All resettable flops are reset. + +De-assertion of cptra\_rst\_b indicates a warm reset cycle that resets all but the “sticky” registers (fuses, error logging, etc.). + +### APB arbitration + +Caliptra is a client on the APB bus, incapable of initiating transfers. If SoCs have multiple APBs or other proprietary-fabric protocols that require any special fabric arbitration, that arbitration is done at SoC level. + +### Undefined address accesses + +All accesses that are outside of the defined address space of Caliptra are responded to by Caliptra’s SoC interface: +* All reads to undefined addresses get completions with zero data. +* All writes to undefined addresses are dropped. +* All other undefined opcodes are silently dropped. +* Access to mailbox memory region with invalid PAUSER are dropped. +* Access to a fuse with invalid PAUSER are dropped. +* PSLVERR is asserted for any of the above conditions. + +All accesses must be 32-bit aligned. Misaligned writes are dropped and reads return 0x0. + +### Undefined mailbox usages + +A trusted/valid requester that locks the mailbox and never releases the lock will cause the mailbox to be locked indefinitely. + +Caliptra firmware internally has the capability to force release the mailbox based on various timers but there is no architectural requirement to use this capability. + +### Straps + +Straps are signal inputs to Caliptra that are sampled once on reset exit, and the latched value persists throughout the remaining uptime of the system. Straps are sampled on either caliptra pwrgood signal deassertion or cptra\_noncore\_rst\_b deassertion – refer to interface table for list of straps. + +### Deobfuscation key + +SoC drives the key at the tape-in time of the SoC using an Engineering Change Order (ECO) and must be protected from common knowledge. For a given SoC construction, this can be driven using a PUF too. + +The key must follow the security rules defined in the[ Caliptra architectural specification](https://chipsalliance.github.io/Caliptra/doc/Caliptra.html). + +SoC must ensure that there are no SCAN cells on the flops that latch this key internally to Caliptra. + +## Late binding interface signals + +The interface signals GENERIC\_INPUT\_WIRES and GENERIC\_OUTPUT\_WIRES are placeholders on the SoC interface reserved for late binding features. This may include any feature that is required for correct operation of the design in the final integrated SoC and that may not be accommodated through existing interface signaling (such as the mailbox). + +While these late binding interface pins are generic in nature until assigned a function, integrators must not define non-standard use cases for these pins. Defining standard use cases ensures that the security posture of Caliptra in the final implementation is not degraded relative to the consortium design intent. + +Each wire connects to a register in the SoC Interface register bank through which communication to the internal microprocessor may be facilitated. Each signal is 64 bits in size. + +Activity on any bit of the GENERIC\_INPUT\_WIRES triggers a notification interrupt to the microcontroller indicating a bit toggle. + +The following table describes the allocation of functionality on GENERIC\_INPUT\_WIRES. + +*Table 12: GENERIC\_INPUT\_WIRES function binding* + +| Bit | Name | Description | +| :--------- | :--------- | :--------- | +| 0 | Zeroization status | Used by SoC to provide zeroization status of fuses. | +| 63:1 | RESERVED | No allocated function. | + +# SoC interface operation + +The Caliptra mailbox is the primary communication method between Caliptra and the SoC that Caliptra is integrated into. + +The Caliptra mailbox uses an APB interface to communicate with the SoC. The SoC can write to and read from various memory mapped register locations over the APB interface in order to pass information to Caliptra. + +Caliptra in turn also uses the mailbox to pass information back to the SoC. The interface does not author any transaction on the APB interface. The interface only signals to the SoC that data is available in the mailbox and it is the responsibility of the SoC to read that data from the mailbox. + +## Boot FSM + +The Boot FSM detects that the SoC is bringing Caliptra out of reset. Part of this flow involves signaling to the SoC that Caliptra is ready for fuses. After fuses are populated and the SoC indicates that it is done downloading fuses, Caliptra can wake up the rest of the IP by deasserting the internal reset. The following figure shows the boot FSM state. + +*Figure 4: Mailbox Boot FSM state diagram* + +![](./images/Caliptra_mbox_boot_FSM.png) + +The boot FSM first waits for the SoC to assert cptra\_pwrgood and de-assert cptra\_rst\_b. In the BOOT\_FUSE state, Caliptra signals to the SoC that it is ready for fuses. After the SoC is done writing fuses, it sets the fuse done register and the FSM advances to BOOT\_DONE. + +BOOT\_DONE enables Caliptra reset deassertion through a two flip-flop synchronizer. + +## SoC access mechanism + +The SoC communicates with the mailbox through an APB Interface. The SoC acts as the requester with the Caliptra mailbox as the receiver. + +The PAUSER bits are used by the SoC to identify which device is accessing the mailbox. + +## Mailbox + +The Caliptra mailbox is a 128 KiB buffer used for exchanging data between the SoC and the Caliptra microcontroller. + +When a mailbox is populated by the SoC, initiation of the operation by writing the execute bit triggers an interrupt to the microcontroller. This interrupt indicates that a command is available in the mailbox. The microcontroller is responsible for reading from and responding to the command. + +When a mailbox is populated by the microcontroller, an output wire to the SoC indicates that a command is available in the mailbox. The SoC is responsible for reading from and responding to the command. + +Mailboxes are generic data-passing structures with a specific protocol that defines legal operations. This protocol for writing to and reading from the mailbox is enforced in hardware as described in the [Caliptra mailbox errors](#caliptra-mailbox-errors) section. How the command and data are interpreted by the microcontroller and SoC are not enforced in this specification. \ + +## Sender Protocol + +**Sending data to the mailbox:** + +1. Requester queries the mailbox by reading the LOCK control register. + 1. If LOCK returns 0, LOCK is granted and will be set to 1. + 2. If LOCK returns 1, MBOX is locked for another device. +2. Requester writes the command to the COMMAND register. +3. Requester writes the data length in bytes to the DLEN register. +4. Requester writes data packets to the MBOX DATAIN register. +5. Requester writes to the EXECUTE register. +6. Requester reads the STATUS register. Status can return: + 1. CMD\_BUSY - 2’b00 – Indicates the requested command is still in progress + 2. DATA\_READY - 2’b01 – Indicates the return data is in the mailbox for requested command + 3. CMD\_COMPLETE- 2’b10 – Indicates the successful completion of the requested command + 4. CMD\_FAILURE- 2’b11 – Indicates the requested command failed +7. Requester reads the response if DATA\_READY was the status. +8. Requester resets the EXECUTE register to release the lock. + +**Notes on behavior:** + +Once LOCK is granted, the mailbox is locked until that device has concluded its operation. Caliptra has access to an internal mechanism to terminate a lock early or release the lock if the device does not proceed to use it or to recover from deadlock scenarios. The following figure shows the sender protocol flow. + +*Figure 5: Sender protocol flow chart* + +![](./images/Caliptra_mbox-sender.png) + +## Receiver Protocol + +Upon receiving indication that mailbox has been populated, the appropriate device can read the mailbox. This is indicated by a dedicated wire that is asserted when Caliptra populates the mailbox for SoC consumption. + +Caliptra will not initiate any mailbox commands that require a response from the SoC. Caliptra initiated mailbox commands are “broadcast” and available to any user on the SoC. SoC will not be able to write the DLEN or DATAIN register while processing a Caliptra initiated mailbox command. + +**Receiving data from the mailbox:** +1. On mailbox\_data\_avail assertion, the receiver reads the COMMAND register. +2. Receiver reads the DLEN register. +3. Receiver reads the CMD register. +4. Receiver reads the MBOX DATAOUT register. + * Continue reading MBOX DATAOUT register until DLEN bytes are read. +5. If a response is required, the receiver can populate the mailbox with the response by updating the DLEN register and writing to DATAIN with the response. (NOTE: The new DLEN value will not take effect until control is returned to the sender via write to the status register). +6. Set the mailbox status register appropriately to hand control back to the sender. +7. The sender will reset the EXECUTE register. + * This releases the LOCK on the mailbox. + +The following figure shows the receiver protocol flow. + +*Figure 6: Receiver protocol flowchart* + +![](./images/Caliptra_mbox_receiver.png) + +## Mailbox arbitration + +From a mailbox protocol perspective, as long as CPTRA\_VALID\_PAUSER registers carry valid requestors, mailbox lock can be obtained by any of those valid requestors but only one of them at any given time. While the mailbox flow is happening, all other requestors will not get a grant. + +A request for lock that is denied due to firmware having the lock results in an interrupt to the firmware. Firmware can optionally use this interrupt to release the lock. + +There is no fair arbitration scheme between SoC and microcontroller. It is first come, first served. When the mailbox is locked for microcontroller use and SoC has unsuccessfully requested the mailbox (due to mailbox actively being used), the mailbox generates an interrupt to the microcontroller as a notification. + +Further, there is no arbitration between various PAUSER attributes. PAUSER attributes exist for security and filtering reasons only. + +## MAILBOX PAUSER attribute register + +It is strongly recommended that these PAUSER registers are either set at integration time through integration parameters or be programmed by the SoC ROM before any mutable firmware or ROM patches are applied. + +### Programmable registers + +Caliptra provides 5 programmable registers that SoC can set at boot time to limit access to the mailbox peripheral. The default PAUSER set by the integration parameter CPTRA\_DEF\_MBOX\_VALID\_PAUSER is valid until all programmable registers are consumed. CPTRA\_MBOX\_VALID\_PAUSER registers become valid once the corresponding lock bit CPTRA\_MBOX\_PAUSER\_LOCK is set. + +*Table 13: PAUSER register definition* + +| Register | Description | +| :--------- | :--------- | +| CPTRA_MBOX_VALID_PAUSER\[4:0\]\[31:0\] | 5 registers for programming PAUSER values that are considered valid for accessing the mailbox protocol. Requests with PAUSER attributes that are not in this list will be ignored. | +| CPTRA_MBOX_PAUSER_LOCK\[4:0\] | 5 registers, bit 0 of each will lock and mark VALID for the corresponding VALID_PAUSER register. | + +### Parameter override + +Another option for limiting access to the mailbox peripheral are the integration time parameters that override the programmable PAUSER registers. At integration time, the CPTRA\_SET\_MBOX\_PAUSER\_INTEG parameters can be set to 1 which enables the corresponding CPTRA\_MBOX\_VALID\_PAUSER parameters to override the programmable register. + +*Table 14: PAUSER Parameter definition* + +| Parameter | Description | +| :--------- | :--------- | +| CPTRA_SET_MBOX_PAUSER_INTEG\[4:0\] | Setting to 1 enables the corresponding CPTRA_MBOX_VALID_PAUSER parameter. | +| CPTRA_MBOX_VALID_PAUSER\[4:0\] | Value to override programmable PAUSER register at integration time if corresponding CPTRA_SET_MBOX_PAUSER_INTEG parameter is set to 1. | + +## Caliptra mailbox protocol + +After the SoC side has written the EXECUTE register, the mailbox sends an interrupt to the microcontroller. + +The microcontroller reads the COMMAND and DLEN registers, as well as the data populated in the mailbox. + +The microcontroller can signal back to SoC through functional registers, and populate COMMAND, DLEN, and MAILBOX as well. + +## Caliptra mailbox errors + +Mailbox is responsible for only accepting writes from the device that requested and locked the mailbox. + +If the SoC violates this protocol, the mailbox flags a protocol violation and enters an error state. Two protocol violations are detected: +1. Access without lock: Writes to any mailbox register by SoC or reads from the dataout register, without having first acquired the lock, are a violation. + 1. If any agent currently has the lock, accesses by agents other than the one holding the lock are ignored. + 2. If no agent currently has the lock, the violation results in a flagged error. +2. Out of order access: SoC must follow the rules for the sender and receiver protocol that define access ordering and progression for a mailbox command. + 1. If, after acquiring the lock, an SoC agent performs any register write (or read from the dataout register) outside of the prescribed ordering, this is a flagged violation. + 2. Such access by any SoC agent that does not have the lock is ignored. + +After a mailbox protocol violation is flagged, it is reported to the system in several ways: +* The mailbox FSM enters the ERROR state in response to an out of order access violation, and the new FSM state is readable via the mailbox status register. The LOCK value is preserved on entry to the ERROR state. The access without lock violation does not result in a state change. After entering the ERROR state, the mailbox may only be restored to the IDLE state by: + * System reset + * Write to the force unlock register by firmware inside Caliptra (via internal bus) + + Either of these mechanisms will also clear the mailbox LOCK. +* Mailbox protocol violations are reported as fields in the HW ERROR non-fatal register. These events also cause assertion of the cptra\_error\_non\_fatal interrupt signal to SoC. Upon detection, SoC may acknowledge the error by clearing the error field in this register via bus write. +* Mailbox protocol violations generate an internal interrupt to the Caliptra microcontroller. Caliptra firmware is aware of the protocol violation. + +The following table describes APB transactions that cause the Mailbox FSM to enter the ERROR state, given that the register “mbox\_user” contains the value of the APB PAUSER that was used to originally acquire the mailbox lock. + +*Table 15: Mailbox protocol error trigger conditions* + +| FSM state | SOC HAS LOCK | APB PAUSER eq mbox_user | Error state trigger condition | +| :--------- | :--------- | :--------- | :--------- | +| MBOX_RDY_FOR_CMD | 1 | true | Read from mbox_dataout. Write to any register other than mbox_cmd. | +| MBOX_RDY_FOR_CMD | 1 | false | \- | +| MBOX_RDY_FOR_CMD | 0 | \- | \- | +| MBOX_RDY_FOR_DLEN | 1 | true | Read from mbox_dataout. Write to any register other than mbox_dlen. | +| MBOX_RDY_FOR_DLEN | 1 | false | \- | +| MBOX_RDY_FOR_DLEN | 0 | \- | \- | +| MBOX_RDY_FOR_DATA | 1 | true | Read from mbox_dataout. Write to any register other than mbox_datain or mbox_execute. | +| MBOX_RDY_FOR_DATA | 1 | false | \- | +| MBOX_RDY_FOR_DATA | 0 | \- | \- | +| MBOX_EXECUTE_UC | 1 | true | Read from mbox_dataout. Write to any register. | +| MBOX_EXECUTE_UC | 1 | false | \- | +| MBOX_EXECUTE_UC | 0 | \- | \- | +| MBOX_EXECUTE_SOC | 1 | true | Write to any register other than mbox_execute. | +| MBOX_EXECUTE_SOC | 1 | false | \- | +| MBOX_EXECUTE_SOC | 0 | true/false\* | Write to any register other than mbox_status. | + +\* mbox\_user value is not used when Caliptra has lock and is sending a Caliptra to SoC mailbox operation. + +# SoC SHA acceleration block + +## Overview + +The SHA acceleration block is in the SoC interface. The SoC can access the accelerator’s hardware API and stream data to be hashed over the APB interface. + +SHA acceleration block uses a similar protocol to the mailbox, but has its own dedicated registers. + +SHA\_LOCK register is set on read. A read of 0 indicates the SHA was unlocked and will now be locked for the requesting user. + +SHA\_MODE register sets the mode of operation for the SHA. + +See the Hardware specification for additional details. +* 2’b00 - SHA384 streaming mode +* 2’b01 - SHA512 streaming mode +* 2’b10 - SHA384 mailbox mode (Caliptra only, invalid for SoC requests) +* 2’b11 - SHA512 mailbox mode (Caliptra only, invalid for SoC requests) + +## SoC Sender Protocol + +**Sending data to the SHA accelerator:** +1. Requester queries the accelerator by reading the SHA\_LOCK control register. + * If SHA\_LOCK returns 0, SHA\_LOCK is granted and is set to 1. + * If SHA\_LOCK returns 1, it is locked for another device. +2. Requester writes the SHA\_MODE register to the appropriate mode of operation. +3. Requester writes the data length in bytes to the SHA\_DLEN register. +4. Requester writes data packets to the SHA\_DATAIN register until SHA\_DLEN bytes are written. +5. Requester writes the SHA\_EXECUTE register, this indicates that it is done streaming data. +6. Requesters can poll the SHA\_STATUS register for the VALID field to be asserted. +7. Once VALID is asserted, the completed hash can be read from the SHA\_DIGEST register. +8. Requester must write 1 to the LOCK register to release the lock. + +# TRNG REQ HW API + +For SoCs that choose to not instantiate Caliptra’s embedded TRNG, we provide a TRNQ REQ HW API. + +**While the use of this API is convenient for early enablement, the current +Caliptra hardware is unable to provide the same security guarantees with an +external TRNG. In particular, it is highly advisable to instantiate an internal +TRNG if ROM glitch protection is important.** + +1. Caliptra asserts TRNG\_REQ wire (this may be because Caliptra’s internal hardware or firmware made the request for a TRNG). +2. SoC writes the TRNG architectural registers. +3. SoC write a done bit in the TRNG architectural registers. +4. Caliptra deasserts TRNG\_REQ. + +Having an interface that is separate from the SoC mailbox ensures that this request is not intercepted by any SoC firmware agents (which communicate with SoC mailbox). It is a requirement for FIPS compliance that this TRNG HW API is always handled by SoC hardware gasket logic (and not some SoC ROM or firmware code). + +TRNG DATA register is tied to TRNG VALID PAUSER. SoC can program the TRNG VALID PAUSER and lock the register using TRNG\_PAUSER\_LOCK[LOCK]. This ensures that TRNG DATA register is read-writeable by only the PAUSER programmed into the TRNG\_VALID\_PAUSER register. If the CPTRA\_TNRG\_PAUSER\_LOCK.LOCK is set to ‘0, then any agent can write to the TRNG DATA register. If the lock is set, only an agent with a specific TRNG\_VALID\_PAUSER can write. + +# SRAM implementation + +## Overview + +SRAMs are instantiated at the SoC level. Caliptra provides the interface to export SRAMs from internal components. + +SRAM repair logic (for example, BIST) and its associated fuses, which are proprietary to companies and their methodologies, is implemented external to the Caliptra boundary. + +SRAMs must NOT go through BIST or repair flows across a “warm reset”. + +Mailbox SRAM is implemented with ECC protection. Data width for the mailbox is 32-bits, with 7 parity bits for a Hamming-based SECDED (single-bit error correction and double-bit error detection). + +## RISC-V internal memory export + +To support synthesis flexibility and ease memory integration to various fabrication processes, all SRAM blocks inside the RISC-V core are exported to an external location in the testbench. A single unified interface connects these memory blocks to their parent logic within the RISC-V core. Any memory implementation may be used to provide SRAM functionality in the external location in the testbench, provided the implementation adheres to the interface requirements connected to control logic inside the processor. Memories behind the interface are expected to be implemented as multiple banks of SRAM, from which the RISC-V processor selects the target using an enable vector. The I-Cache has multiple ways, each containing multiple banks of memory, but I-Cache is disabled in Caliptra and this may be removed for synthesis. + +The following memories are exported: +* Instruction Closely-Coupled Memory (ICCM) +* Data Closely Coupled Memory (DCCM) + +Table 4 indicates the signals contained in the memory interface. Direction is relative to the exported memory wrapper that is instantiated outside of the Caliptra subsystem (that is, from the testbench perspective). + +## SRAM timing behavior +* [Writes] Input wren signal is asserted simultaneously with input data and address. Input data is stored at the input address 1 clock cycle later. +* [Reads] Input clock enable signal is asserted simultaneously with input address. Output data is available 1 clock cycle later from a flip-flop register stage. +* [Writes] Input wren signal is asserted simultaneously with input data and address. Data is stored at the input address 1 clock cycle later. + +The following figure shows the SRAM interface timing. + +*Figure 7: SRAM interface timing* + +![](./images/Caliptra_SRAM_interface_timing.png) + +## SRAM parameterization + +Parameterization for ICCM/DCCM memories is derived from the configuration of the VeeR RISC-V core that has been selected for Caliptra integration. Parameters defined in the VeeR core determine signal dimensions at the Caliptra top-level interface and drive requirements for SRAM layout. For details about interface parameterization, see the [Interface](#interface) section. The following configuration options from the RISC-V Core dictate this behavior: + +*Table 16: SRAM parameterization* + +| Parameter | Value | Description | +| :--------- | :--------- | :--------- | +| ICCM_ENABLE | 1 | Configures ICCM to be present in VeeR core. | +| ICCM_NUM_BANKS | 4 | Determines the number of physical 39-bit (32-bit data + 7-bit ECC) SRAM blocks that are instantiated in the ICCM. | +| ICCM_INDEX_BITS | 13 | Address bit width for each ICCM Bank that is instantiated. | +| ICCM_SIZE | 128 | Capacity of the ICCM in KiB. Total ICCM capacity in bytes is given by 4 \* ICCM_NUM_BANKS \* 2ICCM_INDEX_BITS. | +| DCCM_ENABLE | 1 | Configures DCCM to be present in VeeR core. | +| DCCM_NUM_BANKS | 4 | Determines the number of physical 39-bit (32-bit data + 7-bit ECC) SRAM blocks that are instantiated in the DCCM. | +| DCCM_INDEX_BITS | 13 | Address bit width for each DCCM Bank that is instantiated. | +| DCCM_SIZE | 128 | Capacity of the DCCM in KiB. Total DCCM capacity in bytes is given by 4 \* DCCM_NUM_BANKS \* 2DCCM_INDEX_BITS. | + +## Example SRAM machine check reliability integration + +This section describes an example implementation of integrator machine check reliability. + +This example is applicable to scenarios where an integrator may need control of or visibility into SRAM errors for purposes of reliability or functional safety. In such cases, integrators may introduce additional layers of error injection, detection, and correction logic surrounding SRAMs. The addition of such logic is transparent to the correct function of Caliptra, and removes integrator dependency on Caliptra for error logging or injection. + +Note that the example assumes that data and ECC codes are in non-deterministic bit-position in the exposed SRAM interface bus. Accordingly, redundant correction coding is shown in the integrator level logic (i.e., integrator\_ecc(calitpra\_data, caliptra\_ecc)). If the Caliptra data and ECC are deterministically separable at the Caliptra interface, the integrator would have discretion to store the ECC codes directly and calculate integrator ECC codes for the data alone. + +*Figure 8: Example machine check reliability implementation* + +![](./images/Caliptra_machine_reliability.png) + +### Error detection and logging + +1. Caliptra IP shall interface to ECC protected memories. +2. Caliptra IP calculates and applies its own ECC code, which produces a total of 39-bit data written to external or INTEGRATOR instantiated SRAMs. +3. Each 39-bit bank memory internally calculates 8-bit ECC on a write and stores 47 bits of data with ECC into SRAM. +4. On read access syndrome is calculated based on 39-bit data. +5. If parity error is detected and syndrome is valid, then the error is deemed single-bit and correctable. +6. If no parity error is detected but syndrome == 0 or the syndrome is invalid, the error is deemed uncorrectable. +7. On both single and double errors, the read data is modified before being returned to Caliptra. +8. Since single-bit errors shall be corrected through INTEGRATOR instantiated logic, Caliptra never sees single-bit errors from SRAM. +9. Double-bit or uncorrectable errors would cause unpredictable data to be returned to Caliptra. Since this condition shall be detected and reported to MCRIP, there is no concern or expectation that Caliptra will operate correctly after a double error. +10. On detection, single errors are reported as transparent to MCRIP, double errors are reported as fatal. +11. Along with error severity, MCRIP logs physical location of the error. +12. After MCRIP logs an error, it has a choice to send out in-band notification to an external agent. +13. MCRIP logs can be queried by SoC software. + +### Error injection + +1. MCRIP supports two error injection modes: intrusive and non-intrusive. +2. Intrusive error injection: + 1. Can force a single or double error to be injected, which would result in incorrect data to be returned on read access. + 2. The intrusive error injection mode is disabled in Production fused parts via Security State signal. +3. Non-intrusive error injection: + 1. Allows external software to write into MCRIP error log registers. + 2. The non-intrusive error injection does not interfere with the operation of memories. + 3. The non-intrusive error injection is functional in Production fused parts. + +### Caliptra error and recovery flow + +1. Caliptra Stuck: + 1. SoC BC timeout mechanism with 300us timeout. +2. Caliptra reports non-fatal error during boot flow: + 1. cptra\_error\_non\_fatal is an output Caliptra signal, which shall be routed to SoC interrupt controller. + 2. SoC can look at the Caliptra non-fatal error register for error source. + 3. Assume Caliptra can report a non-fatal error at any time. + 4. SoC should monitor the error interrupt or check it before sending any mailbox command. + 5. In the event of a non-fatal error during boot (that is, prior to a ready for RT signal), SoC should enter recovery flow and attempt to boot again using alternate boot part/partition. + 6. If SoC sees that a non-fatal error has occurred AFTER receiving the ready for RT signal, SoC may attempt to recover Caliptra by executing the “Run Self-Test” mailbox command (not yet defined). + 7. If this command completes successfully, SoC may continue using Caliptra as before. + 8. If this command is unsuccessful, Caliptra is in an error state for the remainder of the current boot. + 9. Non-fatal ECC errors are never reported by Caliptra; SoC needs to monitor MCRIP for non-fatal Caliptra ECC errors. +3. Caliptra reports fatal error during boot flow: + 1. cptra\_error\_fatal is an output Caliptra signal, which shall be routed to SoC interrupt controller. + 2. SoC can look at the Caliptra fatal error register for error source. + 3. Assume Caliptra can report a fatal error at any time. + 4. Fatal errors are generally hardware in nature. SoC may attempt to recover by full reset of the entire SoC, or can move on and know that Caliptra will be unavailable for the remainder of the current boot. + 5. We cannot assume that uncorrectable errors will be correctly detected by Caliptra, ECC fatal errors shall be reported by SOC MCRIP. + +# SoC integration requirements + +The following table describes SoC integration requirements. + +*Table 17: SoC integration requirements* + +| Category | Requirement | Definition of done | Rationale | +| :--------- | :--------- | :--------- | :--------- | +| Deobfuscation Key | SoC backend flows shall generate deobfuscation key with appropriate NIST compliance as dictated in the Caliptra RoT specification. | Statement of conformance | Required by UDS and Field Entropy threat model | +| Deobfuscation Key | If not driven through PUF, SoC backend flows shall ECO the deobfuscation key before tapeout. | Statement of conformance | Required by UDS and Field Entropy threat model | +| Deobfuscation Key | Rotation of the deobfuscation key (if not driven through PUF) between silicon steppings of a given product (for example, A0 vs. B0 vs. PRQ stepping) is dependent on company-specific policies. | Statement of conformance | Required by UDS and Field Entropy threat model | +| Deobfuscation Key | SoC backend flows should not insert deobfuscation key flops into the scan chain. | Synthesis report | Required by UDS and Field Entropy threat model | +| Deobfuscation Key | For defense in depth, it is strongly recommended that debofuscation key flops are not on the scan chain.
Remove the following signals from the scan chain:
cptra_scan_mode_Latched_d
cptra_scan_mode_Latched_f
field_storage.internal_obf_key | Statement of conformance | Caliptra HW threat model | +| DFT | Before scan is enabled (separate signal that SoC implements on scan insertion), SoC shall set Caliptra's scan_mode indication to '1 to allow secrets/assets to be flushed. | Statement of conformance | Required by Caliptra threat model | +| DFT | Caliptra’s TAP should be a TAP endpoint. | Statement of conformance | Functional requirement | +| Mailbox | SoC shall provide an access path between the mailbox and the application CPU complex on SoCs with such complexes (for example, Host CPUs and Smart NICs). See the [Sender Protocol](#sender-protocol) section for details about error conditions. | Statement of conformance | Required for Project Kirkland and TDISP TSM | +| Fuses | SoC shall burn non-field fuses during manufacturing. Required vs. optional fuses are listed in the architectural specification. | Test on silicon | Required for UDS threat model | +| Fuses | SoC shall expose an interface for burning field fuses. Protection of this interface is the SoC vendor’s responsibility. | Test on silicon | Required for Field Entropy | +| Fuses | SoC shall write fuse registers and fuse done via immutable logic or ROM code. | Statement of conformance | Required for Caliptra threat model | +| Security State | SoC shall drive security state wires in accordance with the SoC's security state. | Statement of conformance | Required for Caliptra threat model | +| Security State | If SoC is under debug, then SoC shall drive debug security state to Caliptra. | Statement of conformance | Required for Caliptra threat model | +| Resets and Clocks | SoC shall start input clock before caliptra_pwrgood assertion. | Statement of conformance | Functional | +| Resets and Clocks | SoC reset logic shall assume reset assertions are asynchronous and deassertions are synchronous. | Statement of conformance | Functional | +| Resets and Clocks | SoC shall ensure Caliptra's powergood is the SoC's own powergood. | Statement of conformance | Required for Caliptra threat model | +| TRNG | SoC shall either provision Caliptra with a dedicated TRNG or shared TRNG. | Statement of conformance | Required for Caliptra threat model and Functional | +| TRNG | SoC shall provision the Caliptra embedded TRNG with an entropy source if that is used (vs. SoC-shared TRNG API support). | Statement of conformance | Functional | +| TRNG | If the TRNG is shared, then upon TRNG_REQ, SoC shall use immutable logic or code to program Caliptra's TRNG registers. | Statement of conformance | Required for Caliptra threat model and Functional | +| SRAMs | SoC shall ensure timing convergence with 1-cycle read path for SRAMs. | Synthesis report | Functional | +| SRAMs | SoC shall size SRAMs to account for SECDED. | Statement of conformance | Functional | +| SRAMs | SoC shall write-protect fuses that characterize the SRAM. | Statement of conformance | Required for Caliptra threat model | +| SRAMs | SoC shall ensure SRAM content is only destroyed on powergood cycling. | Statement of conformance | Functional (Warm Reset, Hitless Update) | +| SRAMs | SoC shall only perform SRAM repair on powergood events and prior to caliptra_rst_b deassertion. | Statement of conformance | Functional (Warm Reset, Hitless Update) | +| Backend convergence | Caliptra is validated and backend converged at 400MHz and at process nodes - TSMC 5nm, -- \ | | Functional | +| Power saving | Caliptra clock gating shall be controlled by Caliptra firmware alone. SoC is provided a global clock gating enable signal (and a register) to control. | | Required for Caliptra threat model | +| Power saving | SoC shall not power-gate Caliptra independently of the entire SoC. | Statement of conformance | Required for Caliptra threat model | +| PAUSER | SoC shall drive PAUSER input in accordance with the IP integration spec. | Statement of conformance | ? | +| Error reporting | SoC shall report Caliptra error outputs. | Statement of conformance | Telemetry and monitoring | +| Error reporting | SoC shall only recover Caliptra fatal errors via SoC power-good reset. | Statement of conformance | Required for Caliptra threat model | +| TRNG PAUSER Programming rules | If SoC doesn’t program the CPTRA_TRNG_PAUSER_LOCK\[LOCK\], then Caliptra HW will not accept TRNG data from any SoC entity. | Security | Required for Caliptra threat model | +| TRNG PAUSER Programming rules | If SoC programs CPTRA_TRNG_VALID_PAUSER and sets CPTRA_TRNG_PAUSER_LOCK\[LOCK\], then Caliptra HW will accept TRNG data only from the entity that is programmed into the PAUSER register. | Security | Required for Caliptra threat model | +| TRNG PAUSER Programming rules | It is strongly recommended that these PAUSER registers are either set at integration time through integration parameters or be programmed by the SoC ROM before any mutable FW or ROM patches are absorbed. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | 5 PAUSER attribute registers are implemented at SoC interface. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | At boot time, a default SoC or PAUSER can access the mailbox. The value of this PAUSER is an integration parameter, CPTRA_DEF_MBOX_VALID_PAUSER. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | The value of CPTRA_MBOX_VALID_PAUSER\[4:0\] register can be programmed by SoC. After it is locked, it becomes a valid PAUSER for accessing the mailbox. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | Alternatively, CPTRA_SET_MBOX_PAUSER_INTEG parameter can be set along with the corresponding CPTRA_MBOX_VALID_PAUSER parameter at integration time. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | SoC logic (ROM, HW) that is using the Caliptra mailbox right out of cold reset, without first configuring the programmable mailbox PAUSER registers, must send the mailbox accesses with the default PAUSER, CPTRA_DEF_MBOX_VALID_PAUSER. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | For CPTRA_MBOX_VALID_PAUSER\[4:0\], the corresponding lock bits MUST be programmed to ‘1. This enables the mailbox to accept transactions from non-default PAUSERS. | Security | Required for Caliptra threat model | +| MAILBOX PAUSER programming rules | It is strongly recommended that these PAUSER registers are either set at integration time through integration parameters or be programmed by the SoC ROM before any mutable FW or ROM patches are applied. | Security | Required for Caliptra threat model | +| FUSE PAUSER programming rules | 1 PAUSER attribute register is implemented at SoC interface: CPTRA_FUSE_VALID_PAUSER. | | | +| FUSE PAUSER programming rules | CPTRA_FUSE_PAUSER_LOCK locks the programmable valid pauser register, and marks the programmed value as valid. | | | +| FUSE PAUSER programming rules | Integrators can choose to harden the valid pauser for fuse access by setting the integration parameter, CPTRA_FUSE_VALID_PAUSER, to the desired value in RTL, and by setting CPTRA_SET_FUSE_PAUSER_INTEG to 1. | | | +| GLS FEV | GLS FEV must be run to make sure netlist and RTL match and none of the countermeasures are optimized away. See the following table for example warnings from synthesis runs to resolve through FEV | GLS simulations pass | Functional requirement | + +*Table 18: Caliptra synthesis warnings for FEV evaluation* + +| Module | Warning | Line No. | Description | +| :--------- | :--------- | :--------- | :--------- | +| sha512_acc_top | Empty netlist for always_comb | 417 |Unused logic (no load)| +| ecc_scalar_blinding | Netlist for always_ff block does not contain flip flop | 301 |Output width is smaller than internal signals, synthesis optimizes away the extra internal flops with no loads| +| sha512_masked_core | "masked_carry" is read before being assigned. Synthesized result may not match simulation | 295, 312 || +| ecc_montgomerymultiplier | Netlist for always_ff block does not contain flip flop | 274, 326 |Output width is smaller than internal signals, synthesis optimizes away the extra internal flops with no loads| +| Multiple modules | Signed to unsigned conversion occurs | || + +# CDC analysis and constraints + +Clock Domain Crossing (CDC) analysis is performed on the Caliptra core IP. The following are the results and recommended constraints for Caliptra integrators using standard CDC analysis EDA tools. + +In an unconstrained environment, several CDC violations are anticipated. CDC analysis requires the addition of constraints to identify valid synchronization mechanisms and/or static/pseudo-static signals. + +## Analysis of missing synchronizers +* All of the signals, whether single-bit or multi-bit, originate from the rvjtag\_tap module internal register on TCK clock, and the Sink/Endpoint is the rvdff register, which is in CalitpraClockDomain clock. +* JTAG does a series of “jtag writes” for each single “register write”. +* We only need to synchronize the controlling signal for this interface. +* Inside the dmi\_wrapper, the dmi\_reg\_en and dmi\_reg\_wr\_en comes from dmi\_jtag\_to\_core\_sync, which is a 2FF synchronizer. + +The following code snippet and schematic diagram illustrate JTAG originating CDC violations. + +*Figure 9: Schematic diagram and code snippet showing JTAG-originating CDC violations* + +![](./images/Caliptra_CDC_JTAG_code_snippet.png) + +![](./images/Caliptra_schematic_jtag.png) + +## CDC analysis conclusions +* Missing synchronizers appear to be the result of “inferred” and/or only 2-FF instantiated synchronizers. + * dmi\_jtag\_to\_core\_sync.v contains inferred 2FF synchronizers on the control signals “dmi\_reg\_wr\_en” and “dmi\_reg\_rd\_en”. + * 2FF synchronizer inferences are considered non-compliant and should be replaced by an explicitly instantiated synchronization module, which is intended to be substituted on a per-integrator basis. + * cdc report scheme two\_dff -severity violation +* Multi-bit signals are effectively pseudo-static and are qualified by synchronized control qualifiers. + * Pseudo-static: wr\_data, wr\_addr + * cdc signal reg\_wr\_data -module dmi\_wrapper -stable + * cdc signal reg\_wr\_addr -module dmi\_wrapper -stable +* The core clock frequency must be at least twice the TCK clock frequency for the JTAG data to pass correctly through the synchronizers. + +## CDC constraints +* cdc report scheme two\_dff -severity violation +* cdc signal reg\_wr\_data -module dmi\_wrapper -stable +* cdc signal reg\_wr\_addr -module dmi\_wrapper -stable + +# Synthesis findings + +Synthesis experiments have so far found the following: +* Design converges at 400MHz 0.72V using a cutting edge TSMC process. +* Design converges at 100MHz using TSMC 40nm process. + +Note: Any synthesis warnings of logic optimization must be reviewed and accounted for. + +# Netlist synthesis data + +The following table illustrates representative netlist synthesis results using industry standard EDA synthesis tools and tool configurations. + +These metrics are inclusive of VeeR core, Caliptra logic, imem/dmem RAM, ROM. + +The area is expressed in units of square microns. + +The target foundry technology node is an industry standard, moderately advanced technology node as of 2023 September. + +*Table 19: Netlist synthesis data* + +| **IP Name** | **Date** | **Path Group** | **Target Freq** | **QoR WNS** | **QoR Achieveable Freq** | +| :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | +| CALIPTRA_WRAPPER | 6/15/2023 | CALIPTRACLK | 500MHz | -15.93 | 496MHz | +| CALIPTRA_WRAPPER | 6/15/2023 | JTAG_TCK | 100MHz | 4606.5 | 100MHz | +| CALIPTRA_WRAPPER | 6/15/2023 | clock_gating_default | 500MHz | 26.56 | 500MHz | +| CALIPTRA_WRAPPER | 6/15/2023 | io_to_io | 500MHz | -599.82 | 385MHz | +| CALIPTRA_WRAPPER | 6/15/2023 | io_to_flop | 500MHz | 0.25 | 500MHz | +| CALIPTRA_WRAPPER | 6/15/2023 | flop_to_io | 500MHz | -627.58 | 381MHz | + +| **IP Name** | **Date** | **Stdcell Area** | **Macro Area** | **Memory Area** | **Total Area** | **Flop Count** | **No Clock Regs/Pins Count** | **FM Status** | **FM Eqv Pts** | **FM Non-Eqv Pts** | **FM Abort Pts** | **FM FM**
**Non-Comp** **Pts** | +| :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | :--------- | +| CALIPTRA_WRAPPER | 10/4/2023 | 89279 | 7872 | 239937 | 337088 | 45601 | 31 | SUCCEEDED | 156211 | 0 | 0 | 0 | + +# LINT rules + +TODO 0p5: This is a WIP list + +## Recommended LINT rules + +The following LINT rules are the recommended minimum set for standalone analysis of Caliptra IP. The same set is recommended as a minimum subset that may be applied by Caliptra integrators. + +Error: "x" in casez statements not allowed + +Error: All instance inputs must be driven + +Error: An event variable is declared but never triggered + +Error: Bit truncation hazard; LHS/RHS truncation of extra bits + +Error: Blocking and non-blocking assignment to a signal/variable detected + +Error: Case expression width mismatch; case expression width does not match case select expression width + +Error: Combinational loops detected + +Error: Constant value clock pin of sequential instance + +Error: Detected a logical/scalar operation on a vector + +Error: Detected that a tristate is used below top-level of design + +Error: Detected always or process constructs that do not have an event control + +Error: Detected arithmetic comparison operator with unequal length + +Error: Detected conversion of unsigned (reg type) to integer + +Error: Detected floating or unconnected inout port of an instance + +Error: Detected loop step statement variables incorrectly incremented or decremented + +Error: Detected nonblocking assignment in a combinational always block + +Error: Detected reset or set used both synchronously and asynchronously + +Error: Detected signal read inside combinational always block missing from sensitivity list + +Error: Detected tri-state 'Z' or '?' value used in assign or comparison + +Error: Detected two state data type signals; must support 4 state data type + +Error: Detected undriven but loaded input of an instance + +Error: Detected undriven but loaded net is detected + +Error: Detected undriven but loaded output port of module + +Error: Detected undriven output pins connected to instance input + +Error: Detected unequal length operands in the bit-wise logical, arithmetic, and ternary operators + +Error: Detected unpacked structure declaration outside the package + +Error: Duplicate conditions of a case, unique-case, or priority-case + +Error: Function return does not set all bits of return variable + +Error: Inout port is not read or assigned + +Error: Instance pin connections must use named-association rather than positional association + +Error: LHS or RHS mismatch hazard; multi-bit expression assigned to single bit signal + +Error: Latch inference not permitted + +Error: Must declare enum base type explicitly as sized logic type + +Error: Negative or enum array index detected + +Error: Non-synthesizable construct; functions of type real detected + +Error: Non-synthesizable construct; repeat statement + +Error: Non-synthesizable construct; delays ignored by synthesis tools + +Error: Non-synthesizable construct; modelling style where clock and reset cannot be inferred in sequential inference + +Error: Non-synthesizable construct; states are not updated on the same clock phase in sequential inference + +Error: Null Ports detected + +Error: Port referred before definition + +Error: Range index or slice of an array discrepancy + +Error: Read before set hazard in blocking assignment signal + +Error: Recursive task hazard + +Error: Redeclaration of a port range + +Error: Text Macro Redefinition TMR + +Error: Variable is too short for array index + +Error: Identified case constructs without the default or `OTHERS` clause + +Fatal: Asynchronous reset inference must have "if" statement as first statement in the block + +Fatal: Blocking assignment detected in sequential always block + +Fatal: Detected a function or a sub-program sets a global signal or variable + +Fatal: Detected a function or a sub-program uses a global signal or variable + +Fatal: Detected assignment to input ports + +Fatal: Detected edge and non-edge conditions in block sensitivity list + +Fatal: Detected variable in which both the edges are used in an event control list + +Fatal: Event control detected in RHS of assignment statement + +Fatal: Illegal case construct label detected + +Fatal: Module instance port connection mismatch width compared to the port definition + +Fatal: Non-synthesizable construct; case equal operators (===) (!==) operators may not be synthesizable + +Fatal: Non-synthesizable construct; detected real operands that are used in logical comparisons + +Fatal: Non-synthesizable construct; detected real variables that are unsynthesizable + +Fatal: Non-synthesizable construct; MOS switches, such as cmos, pmos, and nmos + +Fatal: Non-synthesizable construct; disable statements detected + +Fatal: Non-synthesizable construct; event control expressions have multiple edges in sequential inference + +Fatal: Non-synthesizable construct; event variables + +Fatal: Non-synthesizable construct; the tri0 net declarations + +Fatal: Non-synthesizable construct; time declarations + +Fatal: Non-synthesizable construct; tri1 net declarations + +Fatal: Non-synthesizable construct; trireg declarations + +Fatal: The 'default' or 'others' must be last case in a case statement + +# Terminology + +The following terminology is used in this document. + +*Table 20: Terminology* + + +| Abbreviation | Description | +| :--------- | :--------- | +| AHB | AMBA Advanced High-Performance Bus | +| APB | AMBA Advanced Peripheral Bus | +| AES | Advanced Encryption Standard | +| BMD | Boot Media Dependent | +| BMI | Boot Media Integrated | +| ECC | Elliptic Curve Cryptography | +| ECO | Engineering Change Order (used to implement logic changes to a hardware design post-synthesis) | +| QSPI | Quad Serial Peripheral Interface | +| RISC | Reduced Instruction Set Computer | +| SHA | Secure Hashing Algorithm | +| SPI | Serial Peripheral Interface | +| UART | Universal Asynchronous Receiver Transmitter | diff --git a/docs/Caliptra_Integration_Specification.pdf b/docs/Caliptra_Integration_Specification.pdf deleted file mode 100755 index 0cc3f9ebe..000000000 Binary files a/docs/Caliptra_Integration_Specification.pdf and /dev/null differ diff --git a/docs/images/Caliptra_CDC_JTAG_code_snippet.png b/docs/images/Caliptra_CDC_JTAG_code_snippet.png new file mode 100644 index 000000000..fc1ff828f Binary files /dev/null and b/docs/images/Caliptra_CDC_JTAG_code_snippet.png differ diff --git a/docs/images/Caliptra_HW_diagram.png b/docs/images/Caliptra_HW_diagram.png new file mode 100644 index 000000000..901368f98 Binary files /dev/null and b/docs/images/Caliptra_HW_diagram.png differ diff --git a/docs/images/Caliptra_SRAM_interface_timing.png b/docs/images/Caliptra_SRAM_interface_timing.png new file mode 100644 index 000000000..f1e196018 Binary files /dev/null and b/docs/images/Caliptra_SRAM_interface_timing.png differ diff --git a/docs/images/Caliptra_eq_CLKDIV.png b/docs/images/Caliptra_eq_CLKDIV.png new file mode 100644 index 000000000..275ece4b5 Binary files /dev/null and b/docs/images/Caliptra_eq_CLKDIV.png differ diff --git a/docs/images/Caliptra_eq_NCO.png b/docs/images/Caliptra_eq_NCO.png new file mode 100644 index 000000000..601d4ad3d Binary files /dev/null and b/docs/images/Caliptra_eq_NCO.png differ diff --git a/docs/images/Caliptra_eq_SPI_clk_period.png b/docs/images/Caliptra_eq_SPI_clk_period.png new file mode 100644 index 000000000..c8b5b0b22 Binary files /dev/null and b/docs/images/Caliptra_eq_SPI_clk_period.png differ diff --git a/docs/images/Caliptra_eq_UART.png b/docs/images/Caliptra_eq_UART.png new file mode 100644 index 000000000..47277cc16 Binary files /dev/null and b/docs/images/Caliptra_eq_UART.png differ diff --git a/docs/images/Caliptra_eq_UART2.png b/docs/images/Caliptra_eq_UART2.png new file mode 100644 index 000000000..dd9dde5d2 Binary files /dev/null and b/docs/images/Caliptra_eq_UART2.png differ diff --git a/docs/images/Caliptra_machine_reliability.png b/docs/images/Caliptra_machine_reliability.png new file mode 100644 index 000000000..fa25c5e0e Binary files /dev/null and b/docs/images/Caliptra_machine_reliability.png differ diff --git a/docs/images/Caliptra_mbox-sender.png b/docs/images/Caliptra_mbox-sender.png new file mode 100644 index 000000000..4c43e8ea0 Binary files /dev/null and b/docs/images/Caliptra_mbox-sender.png differ diff --git a/docs/images/Caliptra_mbox_boot_FSM.png b/docs/images/Caliptra_mbox_boot_FSM.png new file mode 100644 index 000000000..dd575d531 Binary files /dev/null and b/docs/images/Caliptra_mbox_boot_FSM.png differ diff --git a/docs/images/Caliptra_mbox_receiver.png b/docs/images/Caliptra_mbox_receiver.png new file mode 100644 index 000000000..c86502e5a Binary files /dev/null and b/docs/images/Caliptra_mbox_receiver.png differ diff --git a/docs/images/Caliptra_reset_timing.png b/docs/images/Caliptra_reset_timing.png new file mode 100644 index 000000000..fc131247e Binary files /dev/null and b/docs/images/Caliptra_reset_timing.png differ diff --git a/docs/images/Caliptra_schematic_jtag.png b/docs/images/Caliptra_schematic_jtag.png new file mode 100644 index 000000000..2efad2873 Binary files /dev/null and b/docs/images/Caliptra_schematic_jtag.png differ diff --git a/docs/images/Caliptra_soc_interface_block.png b/docs/images/Caliptra_soc_interface_block.png new file mode 100644 index 000000000..a2f9985c2 Binary files /dev/null and b/docs/images/Caliptra_soc_interface_block.png differ diff --git a/docs/images/OCP_logo.png b/docs/images/OCP_logo.png new file mode 100644 index 000000000..c7a1dfd86 Binary files /dev/null and b/docs/images/OCP_logo.png differ diff --git a/src/ahb_lite_bus/rtl/ahb_lite_bus.sv b/src/ahb_lite_bus/rtl/ahb_lite_bus.sv index 4cc2cc372..b6a088d9e 100644 --- a/src/ahb_lite_bus/rtl/ahb_lite_bus.sv +++ b/src/ahb_lite_bus/rtl/ahb_lite_bus.sv @@ -36,7 +36,7 @@ module ahb_lite_bus #( // -------------------------------------- // Responder Interface Port // -------------------------------------- - CALIPTRA_AHB_LITE_BUS_INF.Responder_Interface_Ports ahb_lite_responders[NUM_RESPONDERS-1:0], + CALIPTRA_AHB_LITE_BUS_INF.Responder_Interface_Ports ahb_lite_responders[0:NUM_RESPONDERS-1], // ---------------------------------------------- // Respnder Disable diff --git a/src/caliptra_prim/rtl/caliptra_prim_assert.sv b/src/caliptra_prim/rtl/caliptra_prim_assert.sv index 7a91601a9..7ab0e3bc7 100644 --- a/src/caliptra_prim/rtl/caliptra_prim_assert.sv +++ b/src/caliptra_prim/rtl/caliptra_prim_assert.sv @@ -49,8 +49,8 @@ // Static assertions for checks inside SV packages. If the conditions is not true, this will // trigger an error during elaboration. `define CALIPTRA_ASSERT_STATIC_IN_PACKAGE(__name, __prop) \ - function automatic bit assert_static_in_package_``__name(); \ - bit unused_bit [((__prop) ? 1 : -1)]; \ + function automatic logic assert_static_in_package_``__name(); \ + logic unused_bit [((__prop) ? 1 : -1)]; \ unused_bit = '{default: 1'b0}; \ return unused_bit[0]; \ endfunction diff --git a/src/csrng/config/csrng.vf b/src/csrng/config/csrng.vf index ef06dd886..0a1c5d165 100644 --- a/src/csrng/config/csrng.vf +++ b/src/csrng/config/csrng.vf @@ -102,4 +102,3 @@ ${CALIPTRA_ROOT}/src/csrng/rtl/csrng_block_encrypt.sv ${CALIPTRA_ROOT}/src/csrng/rtl/csrng_state_db.sv ${CALIPTRA_ROOT}/src/csrng/rtl/csrng_cmd_stage.sv ${CALIPTRA_ROOT}/src/csrng/rtl/csrng.sv -${CALIPTRA_ROOT}/src/csrng/tb/csrng_tb.sv diff --git a/src/doe/rtl/doe_reg.rdl b/src/doe/rtl/doe_reg.rdl index b969aaa0f..392822d5a 100644 --- a/src/doe/rtl/doe_reg.rdl +++ b/src/doe/rtl/doe_reg.rdl @@ -204,8 +204,10 @@ addrmap doe_reg { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -223,8 +225,10 @@ addrmap doe_reg { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/ecc/coverage/ecc_top_cov_if.sv b/src/ecc/coverage/ecc_top_cov_if.sv index 97f1a8cac..345964c64 100644 --- a/src/ecc/coverage/ecc_top_cov_if.sv +++ b/src/ecc/coverage/ecc_top_cov_if.sv @@ -34,6 +34,7 @@ interface ecc_top_cov_if logic error_flag; logic privkey_input_outofrange; logic r_output_outofrange; + logic s_output_outofrange; logic r_input_outofrange; logic s_input_outofrange; logic pubkeyx_input_outofrange; @@ -93,6 +94,7 @@ interface ecc_top_cov_if assign error_flag = ecc_top.ecc_dsa_ctrl_i.error_flag; assign privkey_input_outofrange = ecc_top.ecc_dsa_ctrl_i.privkey_input_outofrange; assign r_output_outofrange = ecc_top.ecc_dsa_ctrl_i.r_output_outofrange; + assign s_output_outofrange = ecc_top.ecc_dsa_ctrl_i.s_output_outofrange; assign r_input_outofrange = ecc_top.ecc_dsa_ctrl_i.r_input_outofrange; assign s_input_outofrange = ecc_top.ecc_dsa_ctrl_i.s_input_outofrange; assign pubkeyx_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyx_input_outofrange; @@ -118,6 +120,7 @@ interface ecc_top_cov_if error_flag_cp: coverpoint error_flag; privkey_input_outofrange_cp: coverpoint privkey_input_outofrange; r_output_outofrange_cp: coverpoint r_output_outofrange; + s_output_outofrange_cp: coverpoint s_output_outofrange; r_input_outofrange_cp: coverpoint r_input_outofrange; s_input_outofrange_cp: coverpoint s_input_outofrange; pubkeyx_input_outofrange_cp: coverpoint pubkeyx_input_outofrange; diff --git a/src/ecc/rtl/ecc_dsa_ctrl.sv b/src/ecc/rtl/ecc_dsa_ctrl.sv index 48eb05af2..405c7fa4e 100644 --- a/src/ecc/rtl/ecc_dsa_ctrl.sv +++ b/src/ecc/rtl/ecc_dsa_ctrl.sv @@ -129,6 +129,7 @@ module ecc_dsa_ctrl logic [1 : 0] cmd_reg; logic [2 : 0] pm_cmd_reg; logic [REG_NUM_DWORDS-1 : 0][RADIX-1:0] msg_reg; + logic [REG_NUM_DWORDS-1 : 0][RADIX-1:0] msg_reduced_reg; logic [REG_NUM_DWORDS-1 : 0][RADIX-1:0] privkey_reg; logic [REG_NUM_DWORDS-1 : 0][RADIX-1:0] kv_reg; logic [REG_NUM_DWORDS-1 : 0][RADIX-1:0] pubkeyx_reg; @@ -196,6 +197,7 @@ module ecc_dsa_ctrl logic privkey_input_outofrange; logic r_output_outofrange; + logic s_output_outofrange; logic r_input_outofrange; logic s_input_outofrange; logic pubkeyx_input_outofrange; @@ -263,7 +265,7 @@ module ecc_dsa_ctrl .keygen_seed(seed_reg), .keygen_nonce(nonce_reg), .privKey(privkey_reg), - .hashed_msg(msg_reg), + .hashed_msg(msg_reduced_reg), .IV(IV_reg), .lambda(lambda), .scalar_rnd(scalar_rnd_reg), @@ -435,6 +437,21 @@ module ecc_dsa_ctrl hwif_in.ECC_IV[dword].IV.hwclr = zeroize_reg; end end + + //transformed msg into modulo q + always_ff @(posedge clk or negedge reset_n) + begin : reduced_msg + if (!reset_n) + msg_reduced_reg <= '0; + else if (zeroize_reg) + msg_reduced_reg <= '0; + else begin + if (msg_reg >= GROUP_ORDER) + msg_reduced_reg <= msg_reg - GROUP_ORDER; + else + msg_reduced_reg <= msg_reg; + end + end always_comb hwif_in.ECC_CTRL.CTRL.hwclr = |hwif_out.ECC_CTRL.CTRL.value; @@ -564,7 +581,7 @@ module ecc_dsa_ctrl CONST_G_Y_MONT_ID : write_reg = {zero_pad, G_Y_MONT}; CONST_R2_q_MONT_ID : write_reg = {zero_pad, R2_q_MONT}; CONST_ONE_q_MONT_ID : write_reg = {zero_pad, ONE_q_MONT}; - MSG_ID : write_reg = {zero_pad, msg_reg}; + MSG_ID : write_reg = {zero_pad, msg_reduced_reg}; PRIVKEY_ID : write_reg = {zero_pad, privkey_reg}; PUBKEYX_ID : write_reg = {zero_pad, pubkeyx_reg}; PUBKEYY_ID : write_reg = {zero_pad, pubkeyy_reg}; @@ -643,6 +660,7 @@ module ecc_dsa_ctrl assign privkey_input_outofrange = signing_process & ((privkey_reg == 0) | (privkey_reg >= GROUP_ORDER)); assign r_output_outofrange = signing_process & (hw_r_we & (read_reg == 0)); + assign s_output_outofrange = signing_process & (hw_s_we & (read_reg == 0)); assign r_input_outofrange = verifying_process & ((r_reg == 0) | (r_reg >= GROUP_ORDER)); assign s_input_outofrange = verifying_process & ((s_reg == 0) | (s_reg >= GROUP_ORDER)); @@ -652,7 +670,7 @@ module ecc_dsa_ctrl assign pcr_sign_input_invalid = ((cmd_reg == KEYGEN) | (cmd_reg == VERIFY)) & pcr_sign_mode; - assign error_flag = privkey_input_outofrange | r_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid | pcr_sign_input_invalid; + assign error_flag = privkey_input_outofrange | r_output_outofrange | s_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid | pcr_sign_input_invalid; //---------------------------------------------------------------- // ECDSA_FSM_flow diff --git a/src/ecc/rtl/ecc_hmac_drbg_interface.sv b/src/ecc/rtl/ecc_hmac_drbg_interface.sv index 4df95d7a3..aff0288f6 100644 --- a/src/ecc/rtl/ecc_hmac_drbg_interface.sv +++ b/src/ecc/rtl/ecc_hmac_drbg_interface.sv @@ -209,7 +209,6 @@ module ecc_hmac_drbg_interface#( end else if (hmac_done_edge) begin - /* verilator lint_off CASEINCOMPLETE */ unique case (state_reg) inside LFSR_ST: lfsr_seed_reg <= hmac_drbg_result[147 : 0]; LAMBDA_ST: lambda_reg <= hmac_drbg_result; @@ -217,8 +216,14 @@ module ecc_hmac_drbg_interface#( MASKING_RND_ST: masking_rnd_reg <= hmac_drbg_result; KEYGEN_ST: drbg_reg <= hmac_drbg_result; SIGN_ST: drbg_reg <= hmac_drbg_result; + default: begin + lambda_reg <= '0; + scalar_rnd_reg <= '0; + masking_rnd_reg <= '0; + drbg_reg <= '0; + lfsr_seed_reg <= LFSR_INIT_SEED; + end endcase - /* verilator lint_on CASEINCOMPLETE */ end end //reg_update diff --git a/src/ecc/rtl/ecc_reg.rdl b/src/ecc/rtl/ecc_reg.rdl index 4446bf8fa..12239e82f 100644 --- a/src/ecc/rtl/ecc_reg.rdl +++ b/src/ecc/rtl/ecc_reg.rdl @@ -455,8 +455,10 @@ addrmap ecc_reg { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -471,8 +473,10 @@ addrmap ecc_reg { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/ecc/tb/test_vectors/ecc_drbg_mbedtls.hex b/src/ecc/tb/test_vectors/ecc_drbg_mbedtls.hex index 03bb042c5..03e50bb56 100644 --- a/src/ecc/tb/test_vectors/ecc_drbg_mbedtls.hex +++ b/src/ecc/tb/test_vectors/ecc_drbg_mbedtls.hex @@ -8,15 +8,15 @@ BB9C3A2F061E8D7014278DD51E66A918A6B6F9F1C1937312D4E7A921B18EF0F41FDD401D9E771850 E548E535A1CC600E133B5591AEBAAD78054006D752D0E1DF94FBFA95D78F0B3F8E81B9119C2BE008BF6D6F4E4185F87D 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 -C8F518D4F3AA1BD46ED56C1C3C9E16FB800AF504DB98843548C5F623EE115F73D4C62ABC06D303B5D90D9A175087290D -F274F69D163B0C9F1FC3EBF4292AD1C4EB3CEC1C5A7DDE6F80C14292934C2055E087748D0A169C772483ADEE5EE70E17 -D79C6D972B34A1DFC916A7B6E0A99B6B5387B34DA2187607C1AD0A4D1A8C2E4172AB5FA5D9AB58FE45E43F56BBB66BA4 -5A7363932B06B4F223BEF0B60A6390265112DBBD0AAE67FEF26B465BE935B48E451E68D16F1118F2B32B4C28608749ED -8FA8541C82A392CA74F23ED1DBFD73541C5966391B97EA73D744B0E34B9DF59ED0158063E39C09A5A055371EDF7A5441 -1B7EC5E548E8AAA92EC77097CA9551C9783CE682CA18FB1EDBD9F1E50BC382DB8AB39496C8EE423F8CA105CBBA7B6588 -871E6EA4DDC5432CDDAA60FD7F055472D3C4DD41A5BFB26709E88C311A97093599A7C8F55B3974C19E4F5A7BFC1DD2AC -3E5552DE6403350EE70AD74E4B854D2DC4126BBF9C153A5D7A07BD4B85D06E45F850920E898FB7D34F80796DAE29365C -3401CEFAE20A737649073AC1A351E32926DB9ED0DB6B1CFFAB0493DAAFB93DDDD83EDEA28A803D0D003B2633B9D0F1BF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +7F68A6D896EA5DA62E78DEDB46F6662BC141F2F0B9E641ACC7342663FD51444E380FEA1DABBCA55F18987C0CFC10DF77 +787D82654607CD1D5A1B11F25C7DF90541380E497CB0560E1489BF7F71B6596300CC9D19335C4827A9BC6148B342F5EC +A321B7C112EEE7227631066CDB556F0D6C66CA87AE912EB4DC412F2F108B27E2BECCBA94F0D844BD7872106EF25C9F25 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3132CF17D965F02E7BF2FDA8755BF54B31B72053D3C35031AA28AB7689C046AF863DB63D04D4810CD042F3B07A860FC +01A6FDB4EFC82CC544B06FE7741CF9C6E8D8189C14A250FBAFCB3FDC5290F30E5E7092FCD1B1A54E60E4F37750BBFE7D +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 1 5F1C0F632D10524D84F4BD20C9ADDAD795CDF5DAA60EA1217A00DD7B1ECAD268C23CC6D7F258E3747A5E4299893F8C37 C9DA896F656439AE83BCA037496DC001CB1F8F0FC9AB9C3C1723768352399E4BF5F44A60E84C2567B88C32569342B706 diff --git a/src/ecc/uvmf_ecc/config/uvmf_ecc.vf b/src/ecc/uvmf_ecc/config/uvmf_ecc.vf new file mode 100644 index 000000000..f53355d1a --- /dev/null +++ b/src/ecc/uvmf_ecc/config/uvmf_ecc.vf @@ -0,0 +1,173 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/coverage ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/../rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/../../libs/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/src ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/src ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/environment_packages/ECC_env_pkg ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/tests ++incdir+${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512_masked/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac_drbg/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_if.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_bind.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/ECC_in_pkg_hdl.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/ECC_in_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/src/ECC_in_driver_bfm.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/src/ECC_in_if.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_in_pkg/src/ECC_in_monitor_bfm.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/ECC_out_pkg_hdl.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/ECC_out_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/src/ECC_out_driver_bfm.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/src/ECC_out_if.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/interface_packages/ECC_out_pkg/src/ECC_out_monitor_bfm.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/verification_ip/environment_packages/ECC_env_pkg/ECC_env_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/parameters/ECC_parameters_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/sequences/ECC_sequences_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/tests/ECC_tests_pkg.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_defines_pkg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_core.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_lfsr.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_param_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_ctrl.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_core.v +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg_lfsr.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_defines_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_params_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_top.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_scalar_blinding.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_hmac_drbg_interface.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_arith_unit.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_ram_tdp_file.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_fau.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_montgomerymultiplier.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_first.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_final.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_mult_dsp.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_add_sub_mod_alter.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_adder.sv \ No newline at end of file diff --git a/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv b/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv index d9d9209bb..01fffdedb 100644 --- a/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv +++ b/src/ecc/uvmf_ecc/uvmf_template_output/project_benches/ECC/tb/testbench/hdl_top.sv @@ -120,6 +120,7 @@ import uvmf_base_pkg_hdl::*; .debugUnlock_or_scan_mode_switch('0) ); + ecc_top_cov_bind i_ecc_top_cov_bind(); // pragma uvmf custom dut_instantiation end initial begin // tbx vif_binding_block diff --git a/src/hmac/formal/model/hmac_core.h b/src/hmac/formal/model/hmac_core.h new file mode 100644 index 000000000..b534e3046 --- /dev/null +++ b/src/hmac/formal/model/hmac_core.h @@ -0,0 +1,201 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef HMAC_H_ +#define HMAC_H_ + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include +#include + +using namespace std; + +#define MSG_WIDTH 1024 // b bits +#define PAD_WIDTH 640 +#define DIGEST_WIDTH 512 +#define KEY_WIDTH 384 // n bits +#define MASK_WIDTH 512 + +const sc_biguint IPAD = sc_biguint("0x3636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636"); +const sc_biguint OPAD = "0x5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c"; +const sc_biguint FINAL_PAD = "0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580"; +const sc_biguint garbage_vector = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000"; + +enum state +{ + state_IPAD, + state_OPAD, + state_HMAC +}; + +struct sha_block +{ + sc_biguint block_msg; + bool init; + bool next; + sc_biguint<74> lfsr_rnd; +}; + +struct sha_splitter +{ + sha_block sha1; + sha_block sha2; +}; + +struct block +{ + sc_biguint key; + sc_biguint block_msg; + bool init, next; +}; + +sc_biguint key_ipadded(sc_biguint key) +{ + return (static_cast>((static_cast>(key << (PAD_WIDTH))) ^ IPAD)); +} + +sc_biguint key_opadded(sc_biguint key) +{ + return (static_cast>(static_cast>(key << (PAD_WIDTH))) ^ OPAD); +} + +sc_biguint hmac_padded(sc_biguint hmac_digest) +{ + return (static_cast>(static_cast>(hmac_digest << (PAD_WIDTH))) | FINAL_PAD); +} + +SC_MODULE(HMAC) +{ +public: + SC_CTOR(HMAC) + { + + SC_THREAD(fsm); + } + +#ifndef LUBIS + blocking_out sha_msg_1 , sha_msg_2; +#else + master_out sha_msg /*, sha_msg_2*/; +#endif + + blocking_in> H1_digest, H2_digest, H1_setup_digest; + blocking_in hmac_msg; + +#ifndef LUBIS + blocking_out> tag; + +#else + master_out> tag; +#endif + +private: + sc_biguint sha_msg_input_ipad; + sc_biguint sha_digest_out_ipad, sha_digest_out_ipad_2, sha_digest_out_opad; + sc_biguint S1, S2; + sc_biguint temp; + bool first_round; + block hmac; + sc_biguint hmac_blk_msg; + sha_splitter sha_inst; + sc_biguint key_i; + sc_biguint block_msg_i; + bool init_i, next_i; + + void fsm() + { + + while (true) + { + + sha_msg_input_ipad = hmac_padded(sc_biguint(0)); + + hmac_msg->read(hmac, "idle"); + cout<<"INIT"<write(sha_inst); +#else + + sha_msg->master_write(sha_inst); +#endif + cout<<"IPAD"<read(sha_digest_out_ipad, "ctrl_ipad"); + } + + sha_inst.sha2.block_msg = key_opadded(hmac.key); + sha_inst.sha2.next = false; + sha_inst.sha2.init = true; + sha_inst.sha1.block_msg = hmac.block_msg; + sha_inst.sha1.init = false; + sha_inst.sha1.next = true; +#ifndef LUBIS + sha_msg_1->write(sha_inst); +#else + sha_msg->master_write(sha_inst); +#endif + cout<<"OPAD"<read(sha_digest_out_ipad, "ctrl_opad"); + + temp = static_cast>(sha_digest_out_ipad >> 128); + + sha_msg_input_ipad = hmac_padded(temp); + + sha_inst.sha1.block_msg = key_ipadded(hmac.key); + sha_inst.sha1.init = false; + sha_inst.sha1.next = false; + sha_inst.sha2.block_msg = sha_msg_input_ipad; + sha_inst.sha2.init = false; + sha_inst.sha2.next = true; + + +#ifndef LUBIS + sha_msg_2->write(sha_inst); +#else + sha_msg->master_write(sha_inst); +#endif + cout<<"ctrl_hmac"<read(sha_digest_out_opad, "ctrl_hmac"); + insert_state("done_tag"); + + cout<<"done"<write((sha_digest_out_opad >> 128)); +#else + tag->master_write((sha_digest_out_opad >> 128)); +#endif + } + } +}; + +#endif diff --git a/src/hmac/formal/model/simulation_model/hmac_sha_join.h b/src/hmac/formal/model/simulation_model/hmac_sha_join.h new file mode 100644 index 000000000..775adac21 --- /dev/null +++ b/src/hmac/formal/model/simulation_model/hmac_sha_join.h @@ -0,0 +1,180 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef HMAC_SHA_ +#define HMAC_SHA_ + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include +#include +#include +#include "../hmac_core.h" + +using namespace std; + +#define MSG_WIDTH 1024 // b bits +#define PAD_WIDTH 640 +#define DIGEST_WIDTH 512 +#define KEY_WIDTH 384 // n bits +#define MASK_WIDTH 512 + +SC_MODULE(hmac_sha) +{ +public: + SC_CTOR(hmac_sha) + { + SC_THREAD(fsm); + } + + blocking_in sha_msg_split_1 ,sha_msg_split_2; + blocking_out> hmac_setup_digest, hmac_1_digest, hmac_2_digest; + + blocking_out h_sha_msg_1, h_sha_msg_2; + blocking_in> sha_1_digest, sha_2_digest; + +private: + sha_splitter chunk1, chunk2, chunk3; + sha_block shablock1, shablock2; + sc_biguint<1024> MSG_raw_1, MSG_raw_2, block_msg_reg; + sc_biguint<2048> msg_comb; + sc_biguint<104000> MSG_padded, shift_pad; + sc_biguint sha_digest_out_ipad, sha_digest_out_ipad_2, sha_digest_out_opad; + sc_uint<32> MSG_Length; + sc_biguint<384> expected_result; + sc_biguint garabage_digest; + bool init_reg, next_reg; + + int num = 1; + int zero_pad_len, MSG_chnks, i, j; + + void fsm() + { + std::random_device seed; + std::default_random_engine generator(seed()); + std::uniform_int_distribution distribution(0,0xFFFFFFFFFFFFFFFF); + while (true) + { + + // cout << "sha_hmac_read_start" << endl; + sha_msg_split_1->read(chunk1, "ipad_state1"); + if (chunk1.sha1.init) + { + shablock1.block_msg = chunk1.sha1.block_msg; + shablock1.init = chunk1.sha1.init; + + shablock1.next = chunk1.sha1.next; + shablock2.block_msg = chunk1.sha1.block_msg; + shablock2.init = chunk1.sha2.init; + shablock2.next = chunk1.sha2.next; + + h_sha_msg_1->write(shablock1, "send_sha1_key"); + + sha_1_digest->read(garabage_digest, "sha1_digest_out"); + hmac_setup_digest->write(garabage_digest, "read_garbage_digest"); + sha_msg_split_1->read(chunk2, "ipad_state2"); + + MSG_Length = 1024; + MSG_chnks = 2; + // cout << "sha_hmac_read_block" << endl; + + MSG_raw_1 = chunk2.sha1.block_msg; + + init_reg = chunk2.sha2.init; + block_msg_reg = chunk2.sha2.block_msg; + next_reg = chunk2.sha2.next; + + shablock1.init = chunk2.sha1.init; + shablock1.next = chunk2.sha1.next; + } + else + { + MSG_Length = 1024; + MSG_chnks = 2; + // cout << "sha_hmac_read_block" << endl; + + MSG_raw_1 = chunk1.sha1.block_msg; + + init_reg = chunk1.sha2.init; + block_msg_reg = chunk1.sha2.block_msg; + next_reg = chunk1.sha2.next; + + shablock1.init = chunk1.sha1.init; + shablock1.next = chunk1.sha1.next; + } + + MSG_padded = static_cast>(static_cast>(MSG_raw_1 << (1024)) + (static_cast>(8) << static_cast>(1020)) + static_cast>(2048)); + //cout << "MSG_padded::" << MSG_padded << endl; + for (i = 0; i < MSG_chnks; ++i) + { + shablock1.lfsr_rnd= static_cast>(distribution(generator))*sc_biguint<74>(1024) + static_cast>(distribution(generator)); + shablock1.block_msg = static_cast>(MSG_padded >> (1024 * (MSG_chnks - 1))); + if (i > 0) + { + shablock1.next = chunk2.sha1.next; + } + + h_sha_msg_1->write(shablock1, "send_ipad_msg"); + MSG_padded = static_cast>(MSG_padded << 1024); + shablock1.init = chunk2.sha1.init; + + sha_1_digest->read(sha_digest_out_ipad_2, "sha1_digest_out"); + } + hmac_1_digest->write(sha_digest_out_ipad_2, "shaop_IPAD_DIGEST_HMAC"); + ////////////////////////////////////// + + MSG_Length = 1024; + MSG_chnks = 2; + // cout << "sha_hmac_read_digest" << endl; + + sha_msg_split_2->read(chunk3, "ipad_state2"); + shablock1.block_msg = chunk3.sha1.block_msg; + shablock1.init = chunk3.sha1.init; + shablock1.next = chunk3.sha1.next; + MSG_raw_2 = chunk3.sha2.block_msg; + + MSG_padded = ((static_cast>(block_msg_reg)) << 1024) | (MSG_raw_2); + // cout << "MSG_padded_sha2::" << MSG_padded << endl; + + shablock2.init = init_reg; + shablock2.next = next_reg; + + for (j = 0; j < MSG_chnks; j++) + { + shablock2.lfsr_rnd= static_cast>(distribution(generator))*sc_biguint<74>(1024) + static_cast>(distribution(generator)); + shablock2.block_msg = static_cast>(MSG_padded >> (1024 * (MSG_chnks - 1))); + if (j > 0) + { + shablock2.next = chunk3.sha1.next; + } + h_sha_msg_2->write(shablock2, "send_ipad_msg"); + MSG_padded = static_cast>(MSG_padded << 1024); + shablock2.init = chunk3.sha1.init; + sha_2_digest->read(sha_digest_out_opad, "sha1_digest_out"); + } + hmac_2_digest->write(sha_digest_out_opad, "shaop_IPAD_DIGEST_HMAC"); + + chunk1.sha1.init = chunk3.sha1.init; + } + } +}; + +#endif \ No newline at end of file diff --git a/src/hmac/formal/model/simulation_model/sha_algo.h b/src/hmac/formal/model/simulation_model/sha_algo.h new file mode 100644 index 000000000..498359e54 --- /dev/null +++ b/src/hmac/formal/model/simulation_model/sha_algo.h @@ -0,0 +1,428 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef SHA +#define SHA + +#include +#include "systemc.h" +#include "string.h" +#include "Interfaces.h" +#include "../hmac_core.h" + +using namespace std; +#define NUM_ROUNDS 80 + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + + sc_biguint<64> slicer(sc_biguint<1024> block, int index) { + switch (index){ + case 0: + return static_cast> (block >> sc_biguint<1024>(64 * 0)); + break; + case 1: + return static_cast> (block >> sc_biguint<1024>(64 * 1)); + break; + case 2: + return static_cast> (block >> sc_biguint<1024>(64 * 2)); + break; + case 3: + return static_cast> (block >> sc_biguint<1024>(64 * 3)); + break; + case 4: + return static_cast> (block >> sc_biguint<1024>(64 * 4)); + break; + case 5: + return static_cast> (block >> sc_biguint<1024>(64 * 5)); + break; + case 6: + return static_cast> (block >> sc_biguint<1024>(64 * 6)); + break; + case 7: + return static_cast> (block >> sc_biguint<1024>(64 * 7)); + break; + case 8: + return static_cast> (block >> sc_biguint<1024>(64 * 8)); + break; + case 9: + return static_cast> (block >> sc_biguint<1024>(64 * 9)); + break; + case 10: + return static_cast> (block >> sc_biguint<1024>(64 * 10)); + break; + case 11: + return static_cast> (block >> sc_biguint<1024>(64 * 11)); + break; + case 12: + return static_cast> (block >> sc_biguint<1024>(64 * 12)); + break; + case 13: + return static_cast> (block >> sc_biguint<1024>(64 * 13)); + break; + case 14: + return static_cast> (block >> sc_biguint<1024>(64 * 14)); + break; + case 15: + return static_cast> (block >> sc_biguint<1024>(64 * 15)); + break; + default: + return static_cast> (block >> sc_biguint<1024>(64 * 15)); + break; + } +} + +sc_biguint<64> Ch(sc_biguint<64> a, sc_biguint<64> b, sc_biguint<64> c) { + return static_cast>((a & b) ^ (~a & c)); +} + +sc_biguint<64> Maj(sc_biguint<64> x, sc_biguint<64> y, sc_biguint<64> z) { + return static_cast>((x & y) ^ (x & z) ^ (y & z)); +} + +sc_biguint<64> shr6(sc_biguint<64> n) { + return static_cast>(n >> sc_biguint<64>(6)); +} + +sc_biguint<64> shr7(sc_biguint<64> n) { + return static_cast>(n >> sc_biguint<64>(7)); +} + +sc_biguint<64> rotr1(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(1))) | (n << (sc_biguint<64>(63)))); +} + +sc_biguint<64> rotr8(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(8))) | (n << (sc_biguint<64>(56)))); +} + +sc_biguint<64> rotr14(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(14))) | (n << (sc_biguint<64>(50)))); +} + +sc_biguint<64> rotr18(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(18))) | (n << (sc_biguint<64>(46)))); +} + +sc_biguint<64> rotr19(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(19))) | (n << (sc_biguint<64>(45)))); +} + +sc_biguint<64> rotr28(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(28))) | (n << (sc_biguint<64>(36)))); +} + +sc_biguint<64> rotr34(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(34))) | (n << (sc_biguint<64>(30)))); +} + +sc_biguint<64> rotr39(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(39))) | (n << (sc_biguint<64>(25)))); +} + +sc_biguint<64> rotr41(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(41))) | (n << (sc_biguint<64>(23)))); +} + +sc_biguint<64> rotr61(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(61))) | (n << (sc_biguint<64>(3)))); +} + +sc_biguint<64> sigma0(sc_biguint<64> x){ + return static_cast> (rotr28(x) ^ rotr34(x) ^ rotr39(x)); +} + +sc_biguint<64> sigma1(sc_biguint<64> x) { + return static_cast> (rotr14(x) ^ rotr18(x) ^ rotr41(x)); +} + +sc_biguint<64> delta0(sc_biguint<64> x) { + return static_cast> (rotr1(x) ^ rotr8(x) ^ shr7(x)); +} + +sc_biguint<64> delta1(sc_biguint<64> x) { + return static_cast> (rotr19(x) ^ rotr61(x) ^ shr6(x)); +} + +sc_biguint<64> T1(sc_biguint<64> e, sc_biguint<64> f, sc_biguint<64> g, sc_biguint<64> h, sc_biguint<64> k, sc_biguint<64> w) { + return static_cast>(h + sigma1(e) + Ch(e, f, g) + k + w); +} + +sc_biguint<64> T2(sc_biguint<64> a, sc_biguint<64> b, sc_biguint<64> c) { + return static_cast>(sigma0(a) + Maj(a, b, c)); +} +sc_biguint<64> compute_e(sc_biguint<64> d,sc_biguint<64> e, sc_biguint<64> f, sc_biguint<64> g, sc_biguint<64> h, sc_biguint<64> k, sc_biguint<64> w) { + return static_cast>(d+ h + sigma1(e) + Ch(e, f, g) + k + w); +} +sc_biguint<64> compute_a(sc_biguint<64> e, sc_biguint<64> f, sc_biguint<64> g, sc_biguint<64> h, sc_biguint<64> k, sc_biguint<64> w,sc_biguint<64> a, sc_biguint<64> b, sc_biguint<64> c) { + return static_cast>((static_cast>(h + sigma1(e) + Ch(e, f, g) + k + w))+(static_cast>(sigma0(a) + Maj(a, b, c)))); +} + +sc_biguint<64> compute_w(sc_biguint<64> w14, sc_biguint<64> w9, sc_biguint<64> w1, sc_biguint<64> w0) { + return static_cast>(delta1(w14) + w9 + delta0(w1) + w0); +} + +sc_biguint<512> compute_dig (sc_biguint<512> dig,sc_biguint<64> h7, sc_biguint<64> h6, sc_biguint<64> h5, sc_biguint<64> h4,sc_biguint<64> h3,sc_biguint<64> h2, sc_biguint<64> h1, sc_biguint<64> h0){ + dig += static_cast> (h6 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h6 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h5 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h4 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h3 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h2 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h1 << sc_biguint<64>(448)); + dig = static_cast> (dig >> sc_biguint<512>(64)); + dig += static_cast> (h0 << sc_biguint<64>(448)); + + return(dig); + +} +// struct SHA_Args{ +// sc_biguint<1024> in; +// bool init; +// bool next; +// }; + +/*struct sha_block{ + sc_biguint block_msg; + bool init; + bool next; +};*/ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + const array , 80> K = + {sc_biguint<64>(0x428a2f98d728ae22), sc_biguint<64>(0x7137449123ef65cd), sc_biguint<64>(0xb5c0fbcfec4d3b2f),\ + sc_biguint<64>(0xe9b5dba58189dbbc), sc_biguint<64>(0x3956c25bf348b538), sc_biguint<64>(0x59f111f1b605d019),\ + sc_biguint<64>(0x923f82a4af194f9b), sc_biguint<64>(0xab1c5ed5da6d8118), sc_biguint<64>(0xd807aa98a3030242),\ + sc_biguint<64>(0x12835b0145706fbe), sc_biguint<64>(0x243185be4ee4b28c), sc_biguint<64>(0x550c7dc3d5ffb4e2),\ + sc_biguint<64>(0x72be5d74f27b896f), sc_biguint<64>(0x80deb1fe3b1696b1), sc_biguint<64>(0x9bdc06a725c71235),\ + sc_biguint<64>(0xc19bf174cf692694), sc_biguint<64>(0xe49b69c19ef14ad2), sc_biguint<64>(0xefbe4786384f25e3),\ + sc_biguint<64>(0x0fc19dc68b8cd5b5), sc_biguint<64>(0x240ca1cc77ac9c65), sc_biguint<64>(0x2de92c6f592b0275),\ + sc_biguint<64>(0x4a7484aa6ea6e483), sc_biguint<64>(0x5cb0a9dcbd41fbd4), sc_biguint<64>(0x76f988da831153b5),\ + sc_biguint<64>(0x983e5152ee66dfab), sc_biguint<64>(0xa831c66d2db43210), sc_biguint<64>(0xb00327c898fb213f),\ + sc_biguint<64>(0xbf597fc7beef0ee4), sc_biguint<64>(0xc6e00bf33da88fc2), sc_biguint<64>(0xd5a79147930aa725),\ + sc_biguint<64>(0x06ca6351e003826f), sc_biguint<64>(0x142929670a0e6e70), sc_biguint<64>(0x27b70a8546d22ffc),\ + sc_biguint<64>(0x2e1b21385c26c926), sc_biguint<64>(0x4d2c6dfc5ac42aed), sc_biguint<64>(0x53380d139d95b3df),\ + sc_biguint<64>(0x650a73548baf63de), sc_biguint<64>(0x766a0abb3c77b2a8), sc_biguint<64>(0x81c2c92e47edaee6),\ + sc_biguint<64>(0x92722c851482353b), sc_biguint<64>(0xa2bfe8a14cf10364), sc_biguint<64>(0xa81a664bbc423001),\ + sc_biguint<64>(0xc24b8b70d0f89791), sc_biguint<64>(0xc76c51a30654be30), sc_biguint<64>(0xd192e819d6ef5218),\ + sc_biguint<64>(0xd69906245565a910), sc_biguint<64>(0xf40e35855771202a), sc_biguint<64>(0x106aa07032bbd1b8),\ + sc_biguint<64>(0x19a4c116b8d2d0c8), sc_biguint<64>(0x1e376c085141ab53), sc_biguint<64>(0x2748774cdf8eeb99),\ + sc_biguint<64>(0x34b0bcb5e19b48a8), sc_biguint<64>(0x391c0cb3c5c95a63), sc_biguint<64>(0x4ed8aa4ae3418acb),\ + sc_biguint<64>(0x5b9cca4f7763e373), sc_biguint<64>(0x682e6ff3d6b2b8a3), sc_biguint<64>(0x748f82ee5defb2fc),\ + sc_biguint<64>(0x78a5636f43172f60), sc_biguint<64>(0x84c87814a1f0ab72), sc_biguint<64>(0x8cc702081a6439ec),\ + sc_biguint<64>(0x90befffa23631e28), sc_biguint<64>(0xa4506cebde82bde9), sc_biguint<64>(0xbef9a3f7b2c67915),\ + sc_biguint<64>(0xc67178f2e372532b), sc_biguint<64>(0xca273eceea26619c), sc_biguint<64>(0xd186b8c721c0c207),\ + sc_biguint<64>(0xeada7dd6cde0eb1e), sc_biguint<64>(0xf57d4f7fee6ed178), sc_biguint<64>(0x06f067aa72176fba),\ + sc_biguint<64>(0x0a637dc5a2c898a6), sc_biguint<64>(0x113f9804bef90dae), sc_biguint<64>(0x1b710b35131c471b),\ + sc_biguint<64>(0x28db77f523047d84), sc_biguint<64>(0x32caab7b40c72493), sc_biguint<64>(0x3c9ebe0a15c9bebc),\ + sc_biguint<64>(0x431d67c49c100d4c), sc_biguint<64>(0x4cc5d4becb3e42b6), sc_biguint<64>(0x597f299cfc657e2a),\ + sc_biguint<64>(0x5fcb6fab3ad6faec), sc_biguint<64>(0x6c44198c4a475817)};; + +SC_MODULE(SHA512) { + + blocking_in SHA_Input; + blocking_out > out; + + array , 16> W; + array , 8> H; + + sc_biguint<64> t1 = sc_biguint<64> (0), t2 = sc_biguint<64> (0), + a = sc_biguint<64> (0), b = sc_biguint<64> (0), + c = sc_biguint<64> (0), d = sc_biguint<64> (0), + e = sc_biguint<64> (0), f = sc_biguint<64> (0), + g = sc_biguint<64> (0), h = sc_biguint<64> (0), + w = sc_biguint<64> (0), k = sc_biguint<64> (0); + sc_biguint<64> tmp_w; + + sc_biguint<1024> block_in; + sc_biguint<1024> block_copy; + sc_biguint<512> MSG_digest; + + sha_block SHA_in; + int SHA_Mode_in; + bool init, next, success, zeroize; + + int i, j, m=0; + + void fsm(); + + SC_CTOR(SHA512){ + SC_THREAD(fsm); + } +}; + +void SHA512::fsm(){ + +while(true){ + + SHA_Input->read(SHA_in, "IDLE"); + + block_in = SHA_in.block_msg; + SHA_Mode_in = 384; + init = SHA_in.init; + next = SHA_in.next; + //zeroize = SHA_in.zeroize; + cout<<"sha_called"<(0x8c3d37c819544da2), sc_biguint<64>(0x73e1996689dcd4d6),\ + sc_biguint<64>(0x1dfab7ae32ff9c82), sc_biguint<64>(0x679dd514582f9fcf),\ + sc_biguint<64>(0x0f6d2b697bd44da8), sc_biguint<64>(0x77e36f7304c48942),\ + sc_biguint<64>(0x3f9d85a86a1d36c8), sc_biguint<64>(0x1112e6ad91d692a1)}; + break; + case 256: + H ={sc_biguint<64>(0x22312194fc2bf72c), sc_biguint<64>(0x9f555fa3c84c64c2),\ + sc_biguint<64>(0x2393b86b6f53b151), sc_biguint<64>(0x963877195940eabd),\ + sc_biguint<64>(0x96283ee2a88effe3), sc_biguint<64>(0xbe5e1e2553863992),\ + sc_biguint<64>(0x2b0199fc2c85b8aa), sc_biguint<64>(0x0eb72ddc81c52ca2)}; + break; + case 384: + H ={sc_biguint<64>(0xcbbb9d5dc1059ed8), sc_biguint<64>(0x629a292a367cd507),\ + sc_biguint<64>(0x9159015a3070dd17), sc_biguint<64>(0x152fecd8f70e5939),\ + sc_biguint<64>(0x67332667ffc00b31), sc_biguint<64>(0x8eb44a8768581511),\ + sc_biguint<64>(0xdb0c2e0d64f98fa7), sc_biguint<64>(0x47b5481dbefa4fa4)}; + break; + case 512: + H ={sc_biguint<64>(0x6a09e667f3bcc908), sc_biguint<64>(0xbb67ae8584caa73b),\ + sc_biguint<64>(0x3c6ef372fe94f82b), sc_biguint<64>(0xa54ff53a5f1d36f1),\ + sc_biguint<64>(0x510e527fade682d1), sc_biguint<64>(0x9b05688c2b3e6c1f),\ + sc_biguint<64>(0x1f83d9abfb41bd6b), sc_biguint<64>(0x5be0cd19137e2179)}; + + break; + default: + H ={sc_biguint<64>(0xcbbb9d5dc1059ed8), sc_biguint<64>(0x629a292a367cd507),\ + sc_biguint<64>(0x9159015a3070dd17), sc_biguint<64>(0x152fecd8f70e5939),\ + sc_biguint<64>(0x67332667ffc00b31), sc_biguint<64>(0x8eb44a8768581511),\ + sc_biguint<64>(0xdb0c2e0d64f98fa7), sc_biguint<64>(0x47b5481dbefa4fa4)}; + break; + } + + t1 = sc_biguint<64> (0); t2 = sc_biguint<64> (0); + a = sc_biguint<64> (0); b = sc_biguint<64> (0); + c = sc_biguint<64> (0); d = sc_biguint<64> (0); + e = sc_biguint<64> (0); f = sc_biguint<64> (0); + g = sc_biguint<64> (0); h = sc_biguint<64> (0); + w = sc_biguint<64> (0); k = sc_biguint<64> (0); + W = {sc_biguint<64>(0)}; + } + + std::cout << "*****************"<< std::endl; + std::cout << "H[0] registers: "<< std::hex<> (H[7] << (sc_biguint<64>(448))); + for (j=6; j > -1; --j) { + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(64)); + MSG_digest += static_cast> (H[j] << sc_biguint<64>(448)); + } + //MSG_digest = compute_dig(static_cast>(0),H[7],H[6],H[5],H[4],H[3],H[2],H[1],H[0]); + //MSG_digest = concati(MSG_digest, H, j); + /* BYME: to comply with rtl + switch (SHA_Mode_in){ + case 224: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(288)); + break; + case 256: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(256)); + break; + case 384: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(128)); + break; + default: + MSG_digest = static_cast> (MSG_digest); + break; + }*/ + + out->write(static_cast> (MSG_digest)); + + + //}; + + //out->write(static_cast> (MSG_digest >> static_cast>(512-SHA_Mode_in))); + } +}; +#endif \ No newline at end of file diff --git a/src/hmac/formal/model/simulation_model/sha_algo_masked.h b/src/hmac/formal/model/simulation_model/sha_algo_masked.h new file mode 100644 index 000000000..6187434a9 --- /dev/null +++ b/src/hmac/formal/model/simulation_model/sha_algo_masked.h @@ -0,0 +1,506 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef SHA +#define SHA + +#include +#include +#include "systemc.h" +#include "string.h" +#include "Interfaces.h" +#include "../hmac_core.h" +using namespace std; + +#define NUM_ROUNDS 80 +#define SHA512_RNDs 9 +const sc_biguint<74> LFSR_INIT_SEED = sc_biguint<74>(0xA79D0EC11E389277); + +std::random_device seed; +std::default_random_engine generator(seed()); +std::uniform_int_distribution distribution(0,0xFFFFFFFFFFFFFFFF); + +//0x079D0EC11E389277); // a random value, copied from RTL: +//BYME: check latest versin of code, Luref, functions23A +//ASK: I don't want some stuff in luref +//BYME: changed fv_constraints to fix block_msg +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +/* struct sha_block +{ + sc_biguint block_msg; + bool init; + bool next; + sc_biguint<74> lfsr_rnd; +}; */ +struct masked_reg_t { + sc_biguint<64> masked, random; +}; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + + sc_biguint<64> slicer(sc_biguint<1024> block, int index) { + switch (index){ + case 0: + return static_cast> (block >> sc_biguint<1024>(64 * 0)); + break; + case 1: + return static_cast> (block >> sc_biguint<1024>(64 * 1)); + break; + case 2: + return static_cast> (block >> sc_biguint<1024>(64 * 2)); + break; + case 3: + return static_cast> (block >> sc_biguint<1024>(64 * 3)); + break; + case 4: + return static_cast> (block >> sc_biguint<1024>(64 * 4)); + break; + case 5: + return static_cast> (block >> sc_biguint<1024>(64 * 5)); + break; + case 6: + return static_cast> (block >> sc_biguint<1024>(64 * 6)); + break; + case 7: + return static_cast> (block >> sc_biguint<1024>(64 * 7)); + break; + case 8: + return static_cast> (block >> sc_biguint<1024>(64 * 8)); + break; + case 9: + return static_cast> (block >> sc_biguint<1024>(64 * 9)); + break; + case 10: + return static_cast> (block >> sc_biguint<1024>(64 * 10)); + break; + case 11: + return static_cast> (block >> sc_biguint<1024>(64 * 11)); + break; + case 12: + return static_cast> (block >> sc_biguint<1024>(64 * 12)); + break; + case 13: + return static_cast> (block >> sc_biguint<1024>(64 * 13)); + break; + case 14: + return static_cast> (block >> sc_biguint<1024>(64 * 14)); + break; + case 15: + return static_cast> (block >> sc_biguint<1024>(64 * 15)); + break; + default: + return static_cast> (block >> sc_biguint<1024>(64 * 15)); + break; + } +} + +sc_biguint<512> concati(sc_biguint<512> MSG_digest, array , 8> H, int j) { + MSG_digest = static_cast> (H[7] << (sc_biguint<64>(448))); + for (j=6; j > -1; --j) { + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(64)); + MSG_digest += static_cast> (H[j] << sc_biguint<64>(448)); + }; + return MSG_digest; +} + +sc_biguint<64> shr6(sc_biguint<64> n) { + return static_cast>(n >> sc_biguint<64>(6)); +} + +sc_biguint<64> shr7(sc_biguint<64> n) { + return static_cast>(n >> sc_biguint<64>(7)); +} + +sc_biguint<64> rotr1(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(1))) | (n << (sc_biguint<64>(63)))); +} + +sc_biguint<64> rotr8(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(8))) | (n << (sc_biguint<64>(56)))); +} + +sc_biguint<64> rotr14(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(14))) | (n << (sc_biguint<64>(50)))); +} + +sc_biguint<64> rotr18(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(18))) | (n << (sc_biguint<64>(46)))); +} + +sc_biguint<64> rotr19(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(19))) | (n << (sc_biguint<64>(45)))); +} + +sc_biguint<64> rotr28(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(28))) | (n << (sc_biguint<64>(36)))); +} + +sc_biguint<64> rotr34(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(34))) | (n << (sc_biguint<64>(30)))); +} + +sc_biguint<64> rotr39(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(39))) | (n << (sc_biguint<64>(25)))); +} + +sc_biguint<64> rotr41(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(41))) | (n << (sc_biguint<64>(23)))); +} + +sc_biguint<64> rotr61(sc_biguint<64> n) { + return static_cast>((n >> (sc_biguint<64>(61))) | (n << (sc_biguint<64>(3)))); +} + +sc_biguint<64> sigma0(sc_biguint<64> x){ + return static_cast> (rotr28(x) ^ rotr34(x) ^ rotr39(x)); +} + +sc_biguint<64> sigma1(sc_biguint<64> x) { + return static_cast> (rotr14(x) ^ rotr18(x) ^ rotr41(x)); +} + +sc_biguint<64> delta0(sc_biguint<64> x) { + return static_cast> (rotr1(x) ^ rotr8(x) ^ shr7(x)); +} + +sc_biguint<64> delta1(sc_biguint<64> x) { + return static_cast> (rotr19(x) ^ rotr61(x) ^ shr6(x)); +} + +sc_biguint<64> masked_and(sc_biguint<64> x_masked, sc_biguint<64> x_random, sc_biguint<64> y_masked, sc_biguint<64> y_random) { + return (~y_masked & ((~y_random & x_random) | (y_random & x_masked))) | (y_masked & ((y_random & x_random) | (~y_random & x_masked))); //x & y; +} + +sc_biguint<64> masked_Maj(sc_biguint<64> a_masked, sc_biguint<64> a_random, sc_biguint<64> b_masked, sc_biguint<64> b_random, sc_biguint<64> c_masked, sc_biguint<64> c_random) { + return masked_and(a_masked, a_random, b_masked, b_random) ^ masked_and(a_masked, a_random, c_masked, c_random) ^ masked_and(b_masked, b_random, c_masked, c_random); +} + +sc_biguint<64> masked_Ch_m(sc_biguint<64> e_masked, sc_biguint<64> e_random, sc_biguint<64> f_masked, sc_biguint<64> f_random, sc_biguint<64> g_masked, sc_biguint<64> g_random) { + return masked_and(e_masked, e_random, f_masked, f_random) ^ masked_and(g_masked, g_random, ~e_masked, e_random); +} + +sc_biguint<64> masked_Ch_r(sc_biguint<64> e_masked, sc_biguint<64> e_random, sc_biguint<64> f_masked, sc_biguint<64> f_random, sc_biguint<64> g_masked, sc_biguint<64> g_random) { + return e_random ^ g_random; +} + +sc_biguint<64> B2A_conv(sc_biguint<64> x_masked, sc_biguint<64> x_random, bool q, bool masked_carry, sc_biguint<128> x_prime, sc_biguint<64> mask, int j) { // convert x_masked = x ^ rnd to x_prime = x + rand + // masked_carry[j] = c[j] ^ qs + mask = sc_biguint<64>(0x01); + x_prime = sc_biguint<128>(0); + masked_carry = q; //used this initial value to avoid the separate case of 0 + + for (j = 0; j < 64; ++j) { //BYME: change next line + x_prime += ((x_masked & mask) == mask) != masked_carry != q ? sc_biguint<128>(16) * sc_biguint<128>(0x01000000000000000) : sc_biguint<128>(0); + masked_carry = (!((x_masked & mask) == mask) and (((x_random & mask) == mask) != q)) or (((x_masked & mask) == mask) and masked_carry); + + x_prime = x_prime >> sc_biguint<128>(1); + mask = mask << sc_biguint<64>(1); + } + + return static_cast>(x_prime);//x_prime +} + +sc_biguint<64> A2B_conv(sc_biguint<64> x_masked, sc_biguint<64> x_random, bool q, bool masked_carry, sc_biguint<128> x_m, sc_biguint<64> mask, int j) { // convert x_prime = x + rand to x_masked = x ^ rnd + // masked_carry[j] = c[j] ^ q + mask = sc_biguint<64>(0x01); + x_m = static_cast>((x_masked & mask) << (sc_biguint<128>(64))); + masked_carry = (not((x_masked & mask) == mask) and ((x_random & mask) == mask)) != q;//used this initial value to avoid separate case of 0 + + for (j = 1; j < 64; ++j) { + mask = mask << sc_biguint<64>(1); + + x_m = (x_m >> 1);//BYME: change next line + x_m += ((x_masked & mask) == mask) != masked_carry != q ? sc_biguint<128>(16) * sc_biguint<128>(0x01000000000000000) : sc_biguint<128>(0); + + masked_carry = ((((x_masked & mask) == mask) != ((x_random & mask) == mask)) and (((x_random & mask) == mask) != q)) or ((!((x_masked & mask) == mask) != ((x_random & mask) == mask)) and masked_carry); + + } + x_m = (x_m >> 1); + + + return static_cast>(x_m);//x_m +} + +sc_biguint<64> T1_m(sc_biguint<64> e_masked, sc_biguint<64> e_random, sc_biguint<64> f_masked, sc_biguint<64> f_random, sc_biguint<64> g_masked, sc_biguint<64> g_random, sc_biguint<64> h_masked, sc_biguint<64> h_random, sc_biguint<64> k, sc_biguint<64> w_masked, sc_biguint<64> w_random, bool masked_carry, sc_biguint<128> x_prime, sc_biguint<64> mask, bool q_masking_rnd_0, bool q_masking_rnd_1, bool q_masking_rnd_2, bool q_masking_rnd_3, bool q_masking_rnd_4, int j) { + + return static_cast>(B2A_conv(h_masked, h_random, q_masking_rnd_0, masked_carry, x_prime, mask, j) + + B2A_conv(sigma1(e_masked), sigma1(e_random), q_masking_rnd_1, masked_carry, x_prime, mask, j)+ + B2A_conv(masked_Ch_m(e_masked, e_random, f_masked, f_random, g_masked, g_random), e_random ^ g_random, q_masking_rnd_2, masked_carry, x_prime, mask, j) + + B2A_conv(k, sc_biguint<64>(0x0), q_masking_rnd_3, masked_carry, x_prime, mask, j) + + B2A_conv(w_masked, w_random, q_masking_rnd_4, masked_carry, x_prime, mask, j)); +} + +sc_biguint<64> T1_r(sc_biguint<64> e_random, sc_biguint<64> g_random, sc_biguint<64> h_random, sc_biguint<64> w_random) { + return static_cast>(h_random + sigma1(e_random) + (e_random ^ g_random) + w_random); +} + +sc_biguint<64> T2_m(sc_biguint<64> a_masked, sc_biguint<64> a_random, sc_biguint<64> b_masked, sc_biguint<64> b_random, sc_biguint<64> c_masked, sc_biguint<64> c_random, bool masked_carry, sc_biguint<128> x_prime, sc_biguint<64> mask, bool q_masking_rnd_5, bool q_masking_rnd_6, int j) { + return static_cast>(B2A_conv(sigma0(a_masked), sigma0(a_random), q_masking_rnd_5, masked_carry, x_prime, mask, j) + + B2A_conv(masked_Maj(a_masked, a_random, b_masked, b_random, c_masked, c_random), b_random, q_masking_rnd_6, masked_carry, x_prime, mask, j)); +} + +sc_biguint<64> T2_r(sc_biguint<64> a_random, sc_biguint<64> b_random) { + return static_cast>(sigma0(a_random) + b_random); +} + +sc_biguint<74> lfsr(sc_biguint<74> a) { + return static_cast>((a * 2) + (a[73] ^ a[72] ^ a[58] ^ a[57])); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +const array , 80> K = + {sc_biguint<64>(0x428a2f98d728ae22), sc_biguint<64>(0x7137449123ef65cd), sc_biguint<64>(0xb5c0fbcfec4d3b2f),\ + sc_biguint<64>(0xe9b5dba58189dbbc), sc_biguint<64>(0x3956c25bf348b538), sc_biguint<64>(0x59f111f1b605d019),\ + sc_biguint<64>(0x923f82a4af194f9b), sc_biguint<64>(0xab1c5ed5da6d8118), sc_biguint<64>(0xd807aa98a3030242),\ + sc_biguint<64>(0x12835b0145706fbe), sc_biguint<64>(0x243185be4ee4b28c), sc_biguint<64>(0x550c7dc3d5ffb4e2),\ + sc_biguint<64>(0x72be5d74f27b896f), sc_biguint<64>(0x80deb1fe3b1696b1), sc_biguint<64>(0x9bdc06a725c71235),\ + sc_biguint<64>(0xc19bf174cf692694), sc_biguint<64>(0xe49b69c19ef14ad2), sc_biguint<64>(0xefbe4786384f25e3),\ + sc_biguint<64>(0x0fc19dc68b8cd5b5), sc_biguint<64>(0x240ca1cc77ac9c65), sc_biguint<64>(0x2de92c6f592b0275),\ + sc_biguint<64>(0x4a7484aa6ea6e483), sc_biguint<64>(0x5cb0a9dcbd41fbd4), sc_biguint<64>(0x76f988da831153b5),\ + sc_biguint<64>(0x983e5152ee66dfab), sc_biguint<64>(0xa831c66d2db43210), sc_biguint<64>(0xb00327c898fb213f),\ + sc_biguint<64>(0xbf597fc7beef0ee4), sc_biguint<64>(0xc6e00bf33da88fc2), sc_biguint<64>(0xd5a79147930aa725),\ + sc_biguint<64>(0x06ca6351e003826f), sc_biguint<64>(0x142929670a0e6e70), sc_biguint<64>(0x27b70a8546d22ffc),\ + sc_biguint<64>(0x2e1b21385c26c926), sc_biguint<64>(0x4d2c6dfc5ac42aed), sc_biguint<64>(0x53380d139d95b3df),\ + sc_biguint<64>(0x650a73548baf63de), sc_biguint<64>(0x766a0abb3c77b2a8), sc_biguint<64>(0x81c2c92e47edaee6),\ + sc_biguint<64>(0x92722c851482353b), sc_biguint<64>(0xa2bfe8a14cf10364), sc_biguint<64>(0xa81a664bbc423001),\ + sc_biguint<64>(0xc24b8b70d0f89791), sc_biguint<64>(0xc76c51a30654be30), sc_biguint<64>(0xd192e819d6ef5218),\ + sc_biguint<64>(0xd69906245565a910), sc_biguint<64>(0xf40e35855771202a), sc_biguint<64>(0x106aa07032bbd1b8),\ + sc_biguint<64>(0x19a4c116b8d2d0c8), sc_biguint<64>(0x1e376c085141ab53), sc_biguint<64>(0x2748774cdf8eeb99),\ + sc_biguint<64>(0x34b0bcb5e19b48a8), sc_biguint<64>(0x391c0cb3c5c95a63), sc_biguint<64>(0x4ed8aa4ae3418acb),\ + sc_biguint<64>(0x5b9cca4f7763e373), sc_biguint<64>(0x682e6ff3d6b2b8a3), sc_biguint<64>(0x748f82ee5defb2fc),\ + sc_biguint<64>(0x78a5636f43172f60), sc_biguint<64>(0x84c87814a1f0ab72), sc_biguint<64>(0x8cc702081a6439ec),\ + sc_biguint<64>(0x90befffa23631e28), sc_biguint<64>(0xa4506cebde82bde9), sc_biguint<64>(0xbef9a3f7b2c67915),\ + sc_biguint<64>(0xc67178f2e372532b), sc_biguint<64>(0xca273eceea26619c), sc_biguint<64>(0xd186b8c721c0c207),\ + sc_biguint<64>(0xeada7dd6cde0eb1e), sc_biguint<64>(0xf57d4f7fee6ed178), sc_biguint<64>(0x06f067aa72176fba),\ + sc_biguint<64>(0x0a637dc5a2c898a6), sc_biguint<64>(0x113f9804bef90dae), sc_biguint<64>(0x1b710b35131c471b),\ + sc_biguint<64>(0x28db77f523047d84), sc_biguint<64>(0x32caab7b40c72493), sc_biguint<64>(0x3c9ebe0a15c9bebc),\ + sc_biguint<64>(0x431d67c49c100d4c), sc_biguint<64>(0x4cc5d4becb3e42b6), sc_biguint<64>(0x597f299cfc657e2a),\ + sc_biguint<64>(0x5fcb6fab3ad6faec), sc_biguint<64>(0x6c44198c4a475817)}; + +SC_MODULE(SHA512_masked) { + + blocking_in SHA_Input; + blocking_out > out; + + array , 16> W; + array , 8> H; + array , 8> rh_masking_rnd = {sc_biguint<64>(0)}; + + masked_reg_t t1 = {sc_biguint<64>(0)}, t2 = {sc_biguint<64>(0)}, + a = {sc_biguint<64>(0)}, b = {sc_biguint<64>(0)}, + c = {sc_biguint<64>(0)}, d = {sc_biguint<64>(0)}, + e = {sc_biguint<64>(0)}, f = {sc_biguint<64>(0)}, + g = {sc_biguint<64>(0)}, h = {sc_biguint<64>(0)}, + w_data = {sc_biguint<64>(0)}; + sc_biguint<64> w = sc_biguint<64> (0), k = sc_biguint<64> (0); + sc_biguint<64> tmp_w; + + sc_biguint<1024> block_in; + sc_biguint<1024> block_copy; + sc_biguint<512> MSG_digest; + + sc_biguint<74> lfsr_rnd; + //sc_biguint<74> lfsr_rnd = LFSR_INIT_SEED; + sc_biguint<74> lfsr_rnd_c; + + sha_block SHA_in; + int SHA_Mode_in; + bool init_cmd, next_cmd, success, zeroize; + + bool masked_carry; + sc_biguint<64> mask = sc_biguint<64>(0x01);; + sc_biguint<64> rw_masking_rnd; + array q_masking_rnd; + sc_biguint<128> x_prime; + sc_biguint<128> x_masked; + + int i, j, m=0, p; + + void fsm(); + + SC_CTOR(SHA512_masked){ + SC_THREAD(fsm); + } +}; + +void SHA512_masked::fsm(){ + + while(true){ + //lfsr_rnd = LFSR_INIT_SEED; //BYME: otherwise in reset property would be 0 + SHA_Input->read(SHA_in, "IDLE"); + + block_in = SHA_in.block_msg; + lfsr_rnd = SHA_in.lfsr_rnd; + SHA_Mode_in = 384; + init_cmd = SHA_in.init; + next_cmd = SHA_in.next; + //zeroize = SHA_in.zeroize; + + //for (p=0; p(0x8c3d37c819544da2), sc_biguint<64>(0x73e1996689dcd4d6),\ + sc_biguint<64>(0x1dfab7ae32ff9c82), sc_biguint<64>(0x679dd514582f9fcf),\ + sc_biguint<64>(0x0f6d2b697bd44da8), sc_biguint<64>(0x77e36f7304c48942),\ + sc_biguint<64>(0x3f9d85a86a1d36c8), sc_biguint<64>(0x1112e6ad91d692a1)}; + break; + case 1: + H ={sc_biguint<64>(0x22312194fc2bf72c), sc_biguint<64>(0x9f555fa3c84c64c2),\ + sc_biguint<64>(0x2393b86b6f53b151), sc_biguint<64>(0x963877195940eabd),\ + sc_biguint<64>(0x96283ee2a88effe3), sc_biguint<64>(0xbe5e1e2553863992),\ + sc_biguint<64>(0x2b0199fc2c85b8aa), sc_biguint<64>(0x0eb72ddc81c52ca2)}; + break; + /*case 2: + H ={sc_biguint<64>(0xcbbb9d5dc1059ed8), sc_biguint<64>(0x629a292a367cd507),\ + sc_biguint<64>(0x9159015a3070dd17), sc_biguint<64>(0x152fecd8f70e5939),\ + sc_biguint<64>(0x67332667ffc00b31), sc_biguint<64>(0x8eb44a8768581511),\ + sc_biguint<64>(0xdb0c2e0d64f98fa7), sc_biguint<64>(0x47b5481dbefa4fa4)}; + break;*/ + case 3: + H ={sc_biguint<64>(0x6a09e667f3bcc908), sc_biguint<64>(0xbb67ae8584caa73b),\ + sc_biguint<64>(0x3c6ef372fe94f82b), sc_biguint<64>(0xa54ff53a5f1d36f1),\ + sc_biguint<64>(0x510e527fade682d1), sc_biguint<64>(0x9b05688c2b3e6c1f),\ + sc_biguint<64>(0x1f83d9abfb41bd6b), sc_biguint<64>(0x5be0cd19137e2179)}; + break; + default: + H ={sc_biguint<64>(0xcbbb9d5dc1059ed8), sc_biguint<64>(0x629a292a367cd507),\ + sc_biguint<64>(0x9159015a3070dd17), sc_biguint<64>(0x152fecd8f70e5939),\ + sc_biguint<64>(0x67332667ffc00b31), sc_biguint<64>(0x8eb44a8768581511),\ + sc_biguint<64>(0xdb0c2e0d64f98fa7), sc_biguint<64>(0x47b5481dbefa4fa4)}; + break; + } + // BYME: Wasn't it this way before? + t1= {sc_biguint<64>(0)}; t2 = {sc_biguint<64>(0)}; + a = {sc_biguint<64>(0)}; b = {sc_biguint<64>(0)}; + c = {sc_biguint<64>(0)}; d = {sc_biguint<64>(0)}; + e = {sc_biguint<64>(0)}; f = {sc_biguint<64>(0)}; + g = {sc_biguint<64>(0)}; h = {sc_biguint<64>(0)}; + w = sc_biguint<64> (0); k = sc_biguint<64> (0); + W = {sc_biguint<64>(0)}; + //lfsr_rnd = LFSR_INIT_SEED;//BYME lfsr_seed; + } + + for (j=0; j<8; ++j) { //BYME: if (masking_init)rh_masking_rnd[rnd_ctr_reg[2 : 0]] <= lfsr_rnd[63 : 0]; + rh_masking_rnd[j] = lfsr_rnd; + }; + + //next(block_in); + //W_schedule(block_in); + block_copy = block_in; + + for (j=0; j<16; ++j) { + W[15-j] = slicer(block_copy, j); + }; + + //copy_digest(); + a = {H[0] ^ rh_masking_rnd[0], rh_masking_rnd[0]}; b = {H[1] ^ rh_masking_rnd[1], rh_masking_rnd[1]}; + c = {H[2] ^ rh_masking_rnd[2], rh_masking_rnd[2]}; d = {H[3] ^ rh_masking_rnd[3], rh_masking_rnd[3]}; + e = {H[4] ^ rh_masking_rnd[4], rh_masking_rnd[4]}; f = {H[5] ^ rh_masking_rnd[5], rh_masking_rnd[5]}; + g = {H[6] ^ rh_masking_rnd[6], rh_masking_rnd[6]}; h = {H[7] ^ rh_masking_rnd[7], rh_masking_rnd[7]}; + + for (i=0; i>(distribution(generator))*sc_biguint<74>(1024) + static_cast>(distribution(generator)); + //std::cout << std::dec << "LFSR_RND in round " << i << " is: " << std::hex << lfsr_rnd << std::endl; + insert_state("SHA_Rounds"); + //sha512_round(i); + k = K[i]; + //w = next_w(i); + + if (i < 16) + w = W[i]; + else { + tmp_w = delta1(W[14]) + W[9] + delta0(W[1]) + W[0]; + for (j=0; j<15; ++j) { + W[j] = W[(j+1)]; + }; + W[15] = tmp_w; + w = tmp_w; + }; + + rw_masking_rnd = static_cast>(lfsr_rnd); + lfsr_rnd_c = lfsr_rnd >> 64; + for (j=0; j<10; ++j) { + q_masking_rnd[j] = ((lfsr_rnd_c) & 0x1) == 1; + lfsr_rnd_c = lfsr_rnd_c >> 1; + }; + w_data = {w ^ rw_masking_rnd, rw_masking_rnd}; + t1 = {T1_m(e.masked, e.random, f.masked, f.random, g.masked, g.random, h.masked, h.random, k, w_data.masked, w_data.random, masked_carry, x_prime, mask, q_masking_rnd[0], q_masking_rnd[1], q_masking_rnd[2], q_masking_rnd[3], q_masking_rnd[4], j), T1_r(e.random, g.random, h.random, w_data.random)}; + t2 = {T2_m(a.masked, a.random, b.masked, b.random, c.masked, c.random, masked_carry, x_prime, mask, q_masking_rnd[5], q_masking_rnd[6], j), T2_r(a.random, b.random)}; + h = g; + g = f; + f = e; + e = {A2B_conv((B2A_conv(d.masked, d.random, q_masking_rnd[7], masked_carry, x_prime, mask, j) + t1.masked), (d.random + t1.random), q_masking_rnd[9], masked_carry, x_masked, mask, j), (d.random + t1.random)}; + d = c; + c = b; + b = a; + a = {A2B_conv((t1.masked + t2.masked), (t1.random + t2.random), q_masking_rnd[8], masked_carry, x_masked, mask, j), (t1.random + t2.random)}; + + }; + insert_state("DONE"); + //update_digest(); + H[0] = (H[0] + (a.masked ^ a.random)); + H[1] = (H[1] + (b.masked ^ b.random)); + H[2] = (H[2] + (c.masked ^ c.random)); + H[3] = (H[3] + (d.masked ^ d.random)); + H[4] = (H[4] + (e.masked ^ e.random)); + H[5] = (H[5] + (f.masked ^ f.random)); + H[6] = (H[6] + (g.masked ^ g.random)); + H[7] = (H[7] + (h.masked ^ h.random)); + + MSG_digest = static_cast> (H[7] << (sc_biguint<64>(448))); + for (j=6; j > -1; --j) { + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(64)); + MSG_digest += static_cast> (H[j] << sc_biguint<64>(448)); + }; + //MSG_digest = concati(MSG_digest, H, j); + /* BYME: to comply with rtl + switch (SHA_Mode_in){ + case 0: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(288)); + break; + case 1: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(256)); + break; + case 2: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(128)); + break; + case 3: + MSG_digest = static_cast> (MSG_digest); + break; + default: + MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(128)); + break; + }*/ + + out->write(static_cast> (MSG_digest)); + + //}; + + //out->write(static_cast> (MSG_digest >> static_cast>(512-SHA_Mode_in))); + } +}; +#endif \ No newline at end of file diff --git a/src/hmac/formal/model/simulation_model/simulation/CMakeLists.txt b/src/hmac/formal/model/simulation_model/simulation/CMakeLists.txt new file mode 100644 index 000000000..19c71a4ee --- /dev/null +++ b/src/hmac/formal/model/simulation_model/simulation/CMakeLists.txt @@ -0,0 +1,51 @@ +########################## Configuration ########################## + +# Set the path to the directory where the 'Interfaces.h' header can be found +set(INTERFACES_DIR "/home/advaith-sreevalsan/.vscode-server/extensions/lubis.lubis-vsc-plugin-2023.3.2/LUBIS/include/interfaces") +# Set TRUE if this CMakeLists should download and install SystemC by itself, +# otherwise set to FALSE and give a directory path to another SystemC installation +set(INSTALL_SYSTEMC TRUE) +set(SYSTEMC_INCLUDE_DIR "/home/advaith-sreevalsan/.vscode-server/extensions/lubis.lubis-vsc-plugin-2023.3.2/LUBIS/include/systemc") +set(SYSTEMC_LIB_DIR "") + +################################################################### + +include(FetchContent) + +cmake_minimum_required(VERSION 3.10) +project(LUBIS_Simulation) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) + +if(INSTALL_SYSTEMC) + FetchContent_Declare(SYSTEMC + GIT_REPOSITORY https://github.com/accellera-official/systemc + GIT_TAG 2.3.3 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + ) + FetchContent_MakeAvailable(SYSTEMC) + include_directories( + ${CMAKE_CACHEFILE_DIR}/_deps/systemc-src/src + ) +else() + include_directories( + ${SYSTEMC_INCLUDE_DIR} + ) + link_directories( + ${SYSTEMC_LIB_DIR} + ) +endif() + +include_directories( + ${INTERFACES_DIR} +) + +add_executable(hmac_tests + hmac_main.cpp +) + +target_link_libraries(hmac_tests PRIVATE + systemc +) diff --git a/src/hmac/formal/model/simulation_model/simulation/hmac_main.cpp b/src/hmac/formal/model/simulation_model/simulation/hmac_main.cpp new file mode 100644 index 000000000..98d68f0ce --- /dev/null +++ b/src/hmac/formal/model/simulation_model/simulation/hmac_main.cpp @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// +// Description: +// + +#include "systemc.h" +#include "Interfaces.h" +#include "../../hmac_core.h" +#include "hmac_tests.h" +#include "../top.h" +#include "../sha_algo_masked.h" + +int sc_main(int argc, char **argv) { + top top1("top1"); + hmac_tests tests("tests"); + + + Blocking hmac_msg("hmac_msg"); + Blocking> tag("tag"); + + top1.top_hmac(hmac_msg); + top1.top_tag(tag); + + tests.hmac_msg(hmac_msg); + tests.tag(tag); + + + sc_start(); + return 0; +} diff --git a/src/hmac/formal/model/simulation_model/simulation/hmac_tests.h b/src/hmac/formal/model/simulation_model/simulation/hmac_tests.h new file mode 100644 index 000000000..2dc0ba359 --- /dev/null +++ b/src/hmac/formal/model/simulation_model/simulation/hmac_tests.h @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// +// Description: +// + +#ifndef HMAC_CORE_TESTS_H +#define HMAC_CORE_TESTS_H + + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include "../sha_algo_masked.h" +#include "../../hmac_core.h" +//#include "../top.h" + +using namespace std; + + +SC_MODULE(hmac_tests) { +public: + SC_CTOR(hmac_tests) { + // read_test_vectors(file_path); + SC_THREAD(testbench) + } + + blocking_out hmac_msg; + blocking_in> tag; + +private: + void testbench() { + + sc_biguint<384> test_result; + block test_input; + sc_biguint<384>KEY; + string COUNT; + sc_biguint<104000> MSG_raw; + sc_biguint<104000> MSG_padded; + sc_uint<32> MSG_Length; + sc_biguint<384> expected_result; + int num = 1; + int zero_pad_len, MSG_chnks,i; + /* std::string filename = "hmac_vectors_singleblk.txt"; + //std::ifstream myfile; + + std::ifstream myfile(filename); + + if (!myfile.is_open()) { + std::cout << "Failed to open the file: " << filename << std::endl; + // Handle the error condition + return; +} + while (myfile) + { + myfile >> COUNT; + myfile >> MSG_Length; + myfile >> std::hex >> KEY; + myfile >> std::hex >> MSG_padded; + myfile >> expected_result; + + + MSG_chnks = static_cast (MSG_Length / 1024); */ + while(true){ + test_input.init = 1; + test_input.next = 0; + test_input.key = 0; + MSG_padded = "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100768412320f7b0aa5812fce428dc4706b3cae50e02a64caa16a782249bfe8efc4b7ef1ccb126255d196047dfedf17a0a96b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000888"; + expected_result = 0; + MSG_Length = 2048; + MSG_chnks = static_cast (MSG_Length / 1024); + + for (i=0; i >(MSG_padded >> (1024*(MSG_chnks-1))); + cout<0){ + test_input.next = 1; + test_input.init = 0;} + hmac_msg->write(test_input); + MSG_padded = static_cast> (MSG_padded << 1024); + test_input.init = 0; + tag->read(test_result, "success"); + + }; + + if (test_result != (expected_result)){ + std::cout << "Test " << COUNT << " Failed!" << std::endl; + std::cout << std::hex << "Output: " << test_result << std::endl; + std::cout << std::hex << "Expected: " << expected_result << std::endl; + } + else { + std::cout << "Test " << COUNT << " Passed!" << std::endl; + } + + + + + //myfile.close(); + sc_stop(); +} + } +}; + + +#endif + + + + + + diff --git a/src/hmac/formal/model/simulation_model/simulation/hmac_vectors_singleblk.txt b/src/hmac/formal/model/simulation_model/simulation/hmac_vectors_singleblk.txt new file mode 100644 index 000000000..0912d3479 --- /dev/null +++ b/src/hmac/formal/model/simulation_model/simulation/hmac_vectors_singleblk.txt @@ -0,0 +1,35 @@ +COUNT0 +1024 +0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F +0x53616D706C65206D65737361676520666F72206B65796C656E3C626C6F636B6C656E80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000510 +0xbe92ab28770b45bdbff7c1ff8e559ec8db51852fe8ba1ac86e7f87c9dc8f2e5eb71a10b0033160740c8ab06181b62d7a +COUNT1 +1024 +0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +0x4869205468657265800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440 +0x47a071f44d2ea7df1ac5ff7cf937068ea34ed0453aed3a61c63d39ae475ed03ea426dce81fb89c3d239887fe2284c267 +COUNT2 +1024 +0x4a6566654a6566654a6566654a6566654a6566654a6566654a6566654a6566654a6566654a6566654a6566654a656665 +0x7768617420646f2079612077616e7420666f72206e6f7468696e673f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e0 +0xe51de7ae00cc719ec8a304d9ff962d53358a7e0b5b6874533af75a66e01a4ee504b9173fd582ba618fe1f6264a889d91 +COUNT3 +1024 +0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590 +0x06d08f889071a284af1bf4ba6b35599e728e20b0fbfa2103c7ebcb2aed872a8adc3769847c9dad14c43fbc9bb12a9e87 +COUNT4 +1024 +0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f200a0b0c0d0e0f10111213141516171819 +0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000590 +0x40e90e787a5cbffeba9252ee2fd76750701199b320cd4b7b9caaa196348ede37d26760e3ebb9ace726ec08a030c3cc2a +COUNT5 +1024 +0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +0x0000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000510 +0x282cf79e9dbe17f48911baa32b7840c4a045786992cde132a1d0dba00e0dd2631d94705be075ea5b90e90ea0c8da26e9 +COUNT6 +1024 +0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0x0000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000510 +0x4088db02e38c741c3d108cd17814afcdf5b27e93fa7baa5ea1d64f61ab9f70604a120e9fe5c3f713ede59db7adbc1c3e \ No newline at end of file diff --git a/src/hmac/formal/model/simulation_model/top.h b/src/hmac/formal/model/simulation_model/top.h new file mode 100644 index 000000000..3c7c7504f --- /dev/null +++ b/src/hmac/formal/model/simulation_model/top.h @@ -0,0 +1,105 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 "systemc.h" +#include "Interfaces.h" +#include "../hmac_core.h" +#include "sha_algo_masked.h" +#include "hmac_sha_join.h" + +SC_MODULE(top) +{ + + HMAC hmc; + SHA512_masked sha384_1; + SHA512_masked sha384_2; + hmac_sha hmacsha; + + blocking_in top_hmac; + blocking_out> top_tag; + + Blocking hmac_msg; + Blocking> tag; + + Blocking sha_msg_split_1, sha_msg_split_2; + Blocking> H1_setup_digest, hmac_1_digest, hmac_2_digest; + Blocking h_sha_msg_1, h_sha_msg_2; + Blocking> sha_1_digest, sha_2_digest; + + SC_CTOR(top) : hmc("hmc"), + sha384_1("sha384_1"), + sha384_2("sha384_2"), + hmacsha("hmacsha"), + + top_hmac("top_in"), + top_tag("top_out"), + + hmac_msg("hmac_msg"), + tag("tag"), + + sha_msg_split_1("sha_msg_split_1"), + sha_msg_split_2("sha_msg_split_2"), + //sha_msg_split_2("sha_msg_split_2"), + + H1_setup_digest("H1_setup_digest"), + hmac_1_digest("hmac_1_digest"), + hmac_2_digest("hmac_2_digest"), + + h_sha_msg_1("h_sha_msg_1"), + h_sha_msg_2("h_sha_msg_2"), + sha_1_digest("sha_1_digest"), + sha_2_digest("sha_2_digest") + { + + hmc.hmac_msg(top_hmac); + + hmc.sha_msg_1(sha_msg_split_1); + hmacsha.sha_msg_split_1(sha_msg_split_1); + + hmacsha.h_sha_msg_1(h_sha_msg_1); + sha384_1.SHA_Input(h_sha_msg_1); + + sha384_1.out(sha_1_digest); + + hmacsha.hmac_setup_digest(H1_setup_digest); + hmc.H1_setup_digest(H1_setup_digest); + + // hmc.sha_msg_2(sha_msg_split_2); + // hmacsha.sha_msg_split_2(sha_msg_split_2); + + hmacsha.sha_1_digest(sha_1_digest); + + hmacsha.hmac_1_digest(hmac_1_digest); + hmc.H1_digest(hmac_1_digest); + + hmc.sha_msg_2(sha_msg_split_2); + hmacsha.sha_msg_split_2(sha_msg_split_2); + + hmacsha.h_sha_msg_2(h_sha_msg_2); + sha384_2.SHA_Input(h_sha_msg_2); + + sha384_2.out(sha_2_digest); + hmacsha.sha_2_digest(sha_2_digest); + + hmacsha.hmac_2_digest(hmac_2_digest); + hmc.H2_digest(hmac_2_digest); + + hmc.tag(top_tag); + } +}; \ No newline at end of file diff --git a/src/hmac/formal/properties/fv_constraints.sv b/src/hmac/formal/properties/fv_constraints.sv new file mode 100644 index 000000000..2b9377ea7 --- /dev/null +++ b/src/hmac/formal/properties/fv_constraints.sv @@ -0,0 +1,98 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_constraints_m +( + input logic clk, + input logic rst_n, + input logic zeroize, + input logic hmac_init, + input logic hmac_next, + input logic [383:0] hmac_key +); + + logic fv_hmac_init_reg; + + default clocking default_clk @(posedge clk); endclocking + + + always @ (posedge clk or negedge rst_n) + begin + if (!rst_n || zeroize) + fv_hmac_init_reg <= 1'h0; + else if (hmac_init) + fv_hmac_init_reg <= 1'h1; + end + + + ////////////////////////// + // Assumptions 1 + // hmac_init and hmac_next + // cannot be high at same + // time. + ///// + property hmac_init_and_next_not_high_same; + !(hmac_init && hmac_next); + endproperty + assume_hmac_init_and_next_not_high_same: assume property(disable iff(!rst_n)hmac_init_and_next_not_high_same); + + /////////////////////////// + // Assumptions 2 + // hmac_init should be high + // first then next. + ////// + property hmac_first_init_then_next; + !fv_hmac_init_reg + |-> + !hmac_next; + endproperty + assume_hmac_first_init_then_next : assume property(disable iff(!rst_n) hmac_first_init_then_next); + + /////////////////////////// + // Assumptions 3 + // hmac_key must be stable + // from the receiving of the + // key + ///// + property hmac_key_stable; + ##1 $stable(hmac_key) || hmac_init; + endproperty + assume_key_stable: assume property(disable iff(!rst_n)hmac_key_stable); + + /////////////////////////// + // Assumptions 4 + // hmac_init must be high + // unitl ready is high + assume_init_not_ready: assume property (disable iff (!rst_n) + !hmac_core.ready + |-> + !hmac_init); + + endmodule + + bind hmac_core fv_constraints_m fv_constraints ( + .clk (clk ), + .rst_n (reset_n ), + .zeroize (zeroize ), + .hmac_init (init_cmd ), + .hmac_next (next_cmd ), + .hmac_key (key ) + ); + + diff --git a/src/hmac/formal/properties/fv_constraints_wip.sv b/src/hmac/formal/properties/fv_constraints_wip.sv new file mode 100644 index 000000000..346e7ac94 --- /dev/null +++ b/src/hmac/formal/properties/fv_constraints_wip.sv @@ -0,0 +1,59 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_constraints_wip_m +( + input logic clk, + input logic rst_n, + input logic hmac_init, + input logic hmac_next, + input wire [383 : 0] key, + input wire [1023 : 0] block_msg, + input logic sha1_init, + input logic sha1_next, + input logic sha2_init, + input logic sha2_next, + input logic [2 : 0] ctrl_reg, + input logic first_round +); + default clocking default_clk @(posedge clk); endclocking + +/* assume_wip_key_stable: assume property(disable iff(!rst_n) + hmac_init + |=> + ($stable(key) || hmac_init) + ); + */ + + endmodule + + bind hmac_core fv_constraints_wip_m constraints_wip( + .clk (clk ), + .rst_n (reset_n && !zeroize ), + .hmac_init (init_cmd ), + .hmac_next (next_cmd ), + .sha1_init (u_sha512_core_h1.init_cmd), + .sha1_next (u_sha512_core_h1.next_cmd), + .sha2_init (u_sha512_core_h2.init_cmd), + .sha2_next (u_sha512_core_h2.next_cmd), + .ctrl_reg (hmac_ctrl_new ), + .first_round(first_round ), + .key (key ), + .block_msg (block_msg ) + ); \ No newline at end of file diff --git a/src/hmac/formal/properties/fv_coverpoints.sv b/src/hmac/formal/properties/fv_coverpoints.sv new file mode 100644 index 000000000..fbbc7b9f6 --- /dev/null +++ b/src/hmac/formal/properties/fv_coverpoints.sv @@ -0,0 +1,61 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_coverpoints_m( + input logic clk, + input logic reset_n, + input logic zeroize +); + + default clocking default_clk @(posedge clk); endclocking + + //Cover zeroize: + //Assert zeroize input and check the status of all registers. All registers/internal memories should be cleared. + cover_zeroize: cover property(disable iff(!reset_n) hmac_core.zeroize ); + cover_zeroize_after_next: cover property(disable iff(!reset_n ) hmac_core.zeroize && hmac_core.ready && hmac_core.next_cmd ); + cover_multiple_next: cover property(disable iff(!reset_n || zeroize ) + hmac_core.next_cmd && hmac_core.ready ##1 hmac_core.next_cmd && hmac_core.ready[->1] ); + + // Assert init_cmd or next_cmd when HMAC_ready is still low. The engine ignores the new command and continues + // to complete the previous command. + cover_init_and_next_ready_low: cover property(disable iff(!reset_n || zeroize) + (hmac_core.init_cmd || + hmac_core.next_cmd) && + !hmac_core.ready + ); + + + // Assert to check if init_cmd then process the key if not process the block message. + cover_init_IPAD: cover property(disable iff(!reset_n || zeroize) + hmac_core.init_cmd + ##2 + hmac_core.CTRL_IPAD + ); + + cover_next_OPAD: cover property(disable iff(!reset_n || zeroize) + (hmac_core.next_cmd + ##2 + hmac_core.CTRL_OPAD + )); + + endmodule +bind hmac_core fv_coverpoints_m fv_coverpoints( + .clk(clk), + .reset_n(reset_n), + .zeroize(zeroize) +); \ No newline at end of file diff --git a/src/hmac/formal/properties/fv_hmac_core.sv b/src/hmac/formal/properties/fv_hmac_core.sv new file mode 100644 index 000000000..cfb56bae9 --- /dev/null +++ b/src/hmac/formal/properties/fv_hmac_core.sv @@ -0,0 +1,253 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// +import global_package::*; + +module fv_hmac_core_m( + input bit rst, + input bit clk, + input bit unsigned [511:0] H1_digest, + input bit unsigned [511:0] H1_setup_digest, + input bit unsigned [511:0] H2_digest, + input bit unsigned [383:0] hmac_msg_key, + input bit unsigned [1023:0] hmac_msg_block_msg, + input bit hmac_msg_init, + input bit hmac_msg_next, + input bit unsigned [1023:0] sha1_block_msg, + input bit sha1_init, + input bit sha1_next, + input bit unsigned [1023:0] sha2_block_msg, + input bit sha2_init, + input bit sha2_next, + input bit unsigned [383:0] tag, + input bit H1_digest_ready, + input bit H1_setup_digest_ready, + input bit H2_digest_ready, + input bit hmac_msg_valid, + input bit H1_digest_valid, + input bit H1_setup_digest_valid, + input bit H2_digest_valid, + input bit hmac_msg_ready, + input bit tag_valid, + input bit unsigned [383:0] hmac_key, + input bit unsigned [1023:0] hmac_block_msg, + input bit unsigned [511:0] sha_digest_out_opad, + input bit idle, + input bit ctrl_ipad, + input bit ctrl_opad, + input bit ctrl_hmac, + input bit done_tag +); + + +default clocking default_clk @(posedge clk); endclocking + +sequence reset_sequence; + rst ##1 !rst; +endsequence + +reset_a: assert property (reset_p); +property reset_p; + reset_sequence |-> + idle && + hmac_msg_ready == 1 && + tag_valid == 0; +endproperty + + +ctrl_hmac_to_done_tag_a: assert property (disable iff(rst) ctrl_hmac_to_done_tag_p); +property ctrl_hmac_to_done_tag_p; + ctrl_hmac && + H2_digest_ready +|-> + ##1 (hmac_msg_ready == 0) and + ##1 (tag_valid == 0) and + ##1 done_tag; +endproperty + + +done_tag_to_idle_a: assert property (disable iff(rst) done_tag_to_idle_p); +property done_tag_to_idle_p; + done_tag +|-> + ##1 + idle && + tag == 384'(((sha_digest_out_opad) >> 512'd128)) && + hmac_msg_ready == 1 && + tag_valid == 1; +endproperty + + +idle_to_ctrl_ipad_a: assert property (disable iff(rst) idle_to_ctrl_ipad_p); +property idle_to_ctrl_ipad_p; + idle && + hmac_msg_valid && + hmac_msg_init +|-> + ##1 (hmac_msg_ready == 0) and + ##1 (tag_valid == 0) and + ##1 + ctrl_ipad && + sha1_block_msg == key_ipadded($past(hmac_msg_key, 1)) && + sha1_init == 1 && + sha1_next == 0 && + sha2_block_msg == key_opadded($past(hmac_msg_key, 1)) && + sha2_init == 0 && + sha2_next == 0; +endproperty + + +idle_to_ctrl_opad_a: assert property (disable iff(rst) idle_to_ctrl_opad_p); +property idle_to_ctrl_opad_p; + idle && + hmac_msg_valid && + !hmac_msg_init +|-> + ##1 (hmac_msg_ready == 0) and + ##1 (tag_valid == 0) and + ##1 + ctrl_opad && + sha1_block_msg == (hmac_block_msg) && + sha1_init == 0 && + sha1_next == 1 && + sha2_block_msg == key_opadded($past(hmac_msg_key, 1)) && + sha2_init == 1 && + sha2_next == 0; +endproperty + + +ctrl_ipad_to_ctrl_opad_a: assert property (disable iff(rst) ctrl_ipad_to_ctrl_opad_p); +property ctrl_ipad_to_ctrl_opad_p; + ctrl_ipad && + H1_setup_digest_ready +|-> + ##1 (hmac_msg_ready == 0) and + ##1 (tag_valid == 0) and + ##1 + ctrl_opad && + sha1_block_msg == (hmac_block_msg) && + sha1_init == 0 && + sha1_next == 1 && + sha2_block_msg == key_opadded($past(hmac_key, 1)) && + sha2_init == 1 && + sha2_next == 0; +endproperty + + +ctrl_opad_to_ctrl_hmac_a: assert property (disable iff(rst) ctrl_opad_to_ctrl_hmac_p); +property ctrl_opad_to_ctrl_hmac_p; + ctrl_opad && + H1_digest_ready +|-> + ##1 (hmac_msg_ready == 0) and + ##1 (tag_valid == 0) and + ##1 + ctrl_hmac && + sha1_block_msg == key_ipadded($past(hmac_key, 1)) && + sha1_init == 0 && + sha1_next == 0 && + sha2_block_msg == hmac_padded(384'(((H1_digest) >> 512'd128))) && + sha2_init == 0 && + sha2_next == 1; +endproperty + + +ctrl_hmac_wait_a: assert property (disable iff(rst) ctrl_hmac_wait_p); +property ctrl_hmac_wait_p; + ctrl_hmac && + !H2_digest_ready +|-> + ##1 + ctrl_hmac && + hmac_msg_ready == 0 && + tag_valid == 0; +endproperty + + +idle_wait_a: assert property (disable iff(rst) idle_wait_p); +property idle_wait_p; + idle && + !hmac_msg_valid +|-> + ##1 + idle && + hmac_msg_ready == 1 && + tag_valid == $past(tag_valid); +endproperty + + +ctrl_ipad_wait_a: assert property (disable iff(rst) ctrl_ipad_wait_p); +property ctrl_ipad_wait_p; + ctrl_ipad && + !H1_setup_digest_ready +|-> + ##1 + ctrl_ipad && + hmac_msg_ready == 0 && + tag_valid == 0; +endproperty + + +ctrl_opad_wait_a: assert property (disable iff(rst) ctrl_opad_wait_p); +property ctrl_opad_wait_p; + ctrl_opad && + !H1_digest_ready +|-> + ##1 + ctrl_opad && + hmac_msg_ready == 0 && + tag_valid == 0; +endproperty + +endmodule + +bind hmac_core fv_hmac_core_m fv_hmac_core( + .rst((!hmac_core.reset_n || hmac_core.zeroize)), + .clk(hmac_core.clk), + .H1_digest({hmac_core.H1_digest,hmac_core.garbage_bit_vector1}), + .H1_setup_digest({hmac_core.H1_digest,hmac_core.garbage_bit_vector1}), + .H2_digest({hmac_core.H2_digest,hmac_core.garbage_bit_vector2}), + .hmac_msg_key(hmac_core.key), + .hmac_msg_block_msg(hmac_core.block_msg), + .hmac_msg_init(hmac_core.init_cmd), + .hmac_msg_next(hmac_core.next_cmd), + .sha1_block_msg(hmac_core.H1_block), + .sha1_init(hmac_core.H1_init), + .sha1_next(hmac_core.H1_next), + .sha2_block_msg(hmac_core.H2_block), + .sha2_init(hmac_core.H2_init), + .sha2_next(hmac_core.H2_next), + .tag(hmac_core.tag), + .H1_digest_ready((hmac_core.H1_ready && hmac_core.H2_ready) && !hmac_core.first_round), + .H1_setup_digest_ready(hmac_core.H1_ready && !hmac_core.first_round), + .H2_digest_ready(hmac_core.H2_ready && !hmac_core.first_round), + .hmac_msg_valid(hmac_core.init_cmd || hmac_core.next_cmd), + .H1_digest_valid(hmac_core.H1_digest_valid && hmac_core.H2_digest_valid), + .H1_setup_digest_valid(hmac_core.H1_digest_valid), + .H2_digest_valid(hmac_core.H2_digest_valid), + .hmac_msg_ready(hmac_core.ready), + .tag_valid(hmac_core.tag_valid), + .hmac_key((hmac_core.key)), + .hmac_block_msg((hmac_core.block_msg)), + .sha_digest_out_opad({hmac_core.H2_digest,hmac_core.garbage_bit_vector2}), + .idle(hmac_core.hmac_ctrl_reg==3'h0), + .ctrl_ipad(hmac_core.hmac_ctrl_reg==3'h1), + .ctrl_opad(hmac_core.hmac_ctrl_reg==3'h2), + .ctrl_hmac(hmac_core.hmac_ctrl_reg==3'h3), + .done_tag(hmac_core.hmac_ctrl_reg==3'h4) +); diff --git a/src/hmac/formal/properties/fv_hmac_pkg.sv b/src/hmac/formal/properties/fv_hmac_pkg.sv new file mode 100644 index 000000000..70f635ba6 --- /dev/null +++ b/src/hmac/formal/properties/fv_hmac_pkg.sv @@ -0,0 +1,47 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +package global_package; + + +// Constants + +localparam bit unsigned [639:0] FINAL_PAD = 640'h8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000580; + +localparam bit unsigned [1023:0] IPAD = 1024'h3636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636; + +localparam bit unsigned [1023:0] OPAD = 1024'h5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C; + + +// Functions + +function bit unsigned [1023:0] hmac_padded(bit unsigned [383:0] hmac_digest); + return ((hmac_digest << 384'd640) | FINAL_PAD); +endfunction + +function bit unsigned [1023:0] key_ipadded(bit unsigned [383:0] key); + return ((key << 384'd640) ^ IPAD); +endfunction + +function bit unsigned [1023:0] key_opadded(bit unsigned [383:0] key); + return ((key << 384'd640) ^ OPAD); +endfunction + + +endpackage diff --git a/src/hmac/formal/properties/fv_key_stable_top.sv b/src/hmac/formal/properties/fv_key_stable_top.sv new file mode 100644 index 000000000..f7f8c88bb --- /dev/null +++ b/src/hmac/formal/properties/fv_key_stable_top.sv @@ -0,0 +1,47 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_key_stable_top_m +( + input logic clk, + input logic rst_n +); + + default clocking default_clk @(posedge clk); endclocking + +//TODO: hmac top should keep the key stable for signle computation. Check with assertion +logic [383:0] hmac_key; +logic hmac_init; + +assign hmac_key = hmac_ctrl.hmac_inst.core.key; +assign hmac_init = hmac_ctrl.hmac_inst.core.init_cmd; + + +assert_wip_key_stable: assert property(disable iff(!rst_n) + hmac_init + |=> + ($stable(hmac_key) || hmac_init) + ); + + +endmodule + bind hmac_ctrl fv_key_stable_top_m fv_key_stable_top ( + .clk (clk ), + .rst_n (reset_n ) + ); \ No newline at end of file diff --git a/src/hmac/formal/readme.md b/src/hmac/formal/readme.md new file mode 100644 index 000000000..2418aef3c --- /dev/null +++ b/src/hmac/formal/readme.md @@ -0,0 +1,85 @@ +_*SPDX-License-Identifier: Apache-2.0
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+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.*_
+ +# HMAC + +Date: 28-07-2023 Author: LUBIS EDA + +## Folder Structure + +The following subdirectories are part of the main directory **formal** + +- model: Contains the high level abstracted model +- properties: Contains the assertion IP(AIP) named as fv_hmac.sv and the constraints in place for the respective AIP fv_constraints.sv and fv_constraints_wip.sv + +## DUT Overview + +The DUT hmac_core has the primary inputs and primary outputs as shown below. + +|S.No | Port |Direction| Description | +|---- |----------------- |-------- |-------------------------------------------------------------------------------------------| +|1 |clk | input | The positive edge of the clk is used for all the signals | +|2 |reset_n | input | The reset signal is active low and resets the core | +|3 |zeroize | input | The core is reseted when this signal is triggered. | +|4 |init_cmd | input | The core is initialised with respective mode constants and processes the message. | +|5 |next_cmd | input | The core processes the message block with the previously computed results | +|6 |key[383:0] | input | The input key | +|7 |block_msg[1023:0] | input | The padded block message | +|8 |lfsr_seed[147:0] | input | The input constant value that is feed to sha512_masked as an input for digest computation | +|8 |ready | output | When triggered indicates that the core is ready | +|9 |tag[383:0] | output | The tag value of the given message block | +|10 |tag_valid | output | When triggered indicates that the computed tag is ready | + +Hmac algorithm starts with padding the key with IPAD and OPAD constants. Once HMAC receives init_cmd, it initalizes both HMAC and first instantance of SHA, with IPAD padded key. With next_cmd, HMAC feeds block msg to first instantance of SHA, at the same time initalizes second instantance of SHA with OPAD padded key. With the digest recieved from first SHA, the digest is padded to have 1024 bit and later feed to second instantance of SHA, to get the final digest value, which the tag for HMAC. The digest of SHA is always of 512 bits, first 384 is considered valid while rest is garabage value. + +## Assertion IP Overview + +The Assertion IP signals are bound with the respective signals in the dut, where for the rst is binded with the DUT (reset_n && !zeroize), which ensures the reset functionality. Assertion IP is binded with hmac_core and checks for the functionality of only hmac_core. The digest of sha512_masked_core is considered to be cut open. This is perfomed on the formal tool. This way the tool has the freedom to choose any random value of digest coming out of sha512_maked_core so as to reduce the complex functionality of sha512 hashing. With this approach, IP makes sure hmac_core is functionality correct irrespective of correct computed value of digest and helps in proof convergence. Constraints are made on init_cmd and next_cmd signals of hmac_core The constraints can be looked up at fv_constraints.sv. + +- reset_a: Checks that all the resgiters are resetted and the state is idle, with the ready to high. + +- ctrl_hmac_to_done_tag_a: Checks the necessary registers, outputs holds the values when state transits from Done to idle, + +- done_tag_to_idle_a: Checks if tag register outputs correct value and tag_valid is high, when transition from done to idle states. + +- idle_to_ctrl_ipad_a: Checks if the state is in idle , if init is triggered then the sha_blocks should be assigned with respective padded key values and SHA1 is initailized. + +- idle_to_ctrl_opad_a: Checks if the state is in idle , if next is triggered then SHA2 is initailized with right padded key value, and SHA1 should be assigned with hmac block msg. + +- ctrl_ipad_to_ctrl_opad_a: Checks if the state is transitioned from inner_padding to outer_padding state , then SHA2 is initailized with right padded key value, and SHA1 should be assigned with hmac block msg. + +- ctrl_hmac_wait_a: Checks if digest from SHA2 is not ready, it remains in the same state until digest is ready. + +- idle_wait_a: Checks if the state remains same until, there is an init or next command. + +- ctrl_ipad_wait_a: Checks if the state remains same until, digest from SHA1 is ready. + +- ctrl_opad_wait_a: Checks if the state remains same until, digest from SHA2 is ready. + + +## Reproduce results + +The AIP has been tested with two major FV tools. For both tools proves pass in less then 2 hour and coverage is at 100%. + +For reproducing the results: +Load the AIP, hmac_core and fv_constraints together in your formal tool. +To ensure converging proves cut the following signals: + +cut u_sha512_core_h1.digest +cut u_sha512_core_h2.digest + +The sha512_masked core had been verified separately. By cutting the signal model complexity is drastically reduced. + +Feel free to reach out to contact@lubis-eda.com to request the loadscripts. diff --git a/src/hmac/rtl/hmac_reg.rdl b/src/hmac/rtl/hmac_reg.rdl index 4401d1c97..0f7713955 100644 --- a/src/hmac/rtl/hmac_reg.rdl +++ b/src/hmac/rtl/hmac_reg.rdl @@ -281,8 +281,10 @@ addrmap hmac_reg { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -300,8 +302,10 @@ addrmap hmac_reg { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -469,4 +473,4 @@ addrmap hmac_reg { * ----------------------- */ intr_block_t intr_block_rf @0x800; -}; \ No newline at end of file +}; diff --git a/src/hmac/uvmf_2022/config/uvmf_hmac.vf b/src/hmac/uvmf_2022/config/uvmf_hmac.vf new file mode 100644 index 000000000..a11f61ac2 --- /dev/null +++ b/src/hmac/uvmf_2022/config/uvmf_hmac.vf @@ -0,0 +1,146 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/coverage ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/../rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/../../libs/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/src ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/src ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/environment_packages/HMAC_env_pkg ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/tests ++incdir+${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512_masked/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/HMAC_in_pkg_hdl.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/HMAC_in_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/src/HMAC_in_driver_bfm.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/src/HMAC_in_if.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_in_pkg/src/HMAC_in_monitor_bfm.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/HMAC_out_pkg_hdl.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/HMAC_out_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/src/HMAC_out_driver_bfm.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/src/HMAC_out_if.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/interface_packages/HMAC_out_pkg/src/HMAC_out_monitor_bfm.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/verification_ip/environment_packages/HMAC_env_pkg/HMAC_env_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/parameters/HMAC_parameters_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/sequences/HMAC_sequences_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/tests/HMAC_tests_pkg.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_defines_pkg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_core.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_lfsr.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_param_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_ctrl.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_core.v +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg.sv \ No newline at end of file diff --git a/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv b/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv index feeda3abe..24bbe0a1c 100644 --- a/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv +++ b/src/hmac/uvmf_2022/uvmf_template_output/project_benches/HMAC/tb/testbench/hdl_top.sv @@ -108,6 +108,7 @@ hmac_ctrl #( .debugUnlock_or_scan_mode_switch('0) ); +hmac_ctrl_cov_bind i_hmac_ctrl_cov_bind(); // pragma uvmf custom dut_instantiation end initial begin // tbx vif_binding_block diff --git a/src/integration/asserts/caliptra_top_sva.sv b/src/integration/asserts/caliptra_top_sva.sv index 8da8234aa..cdb92c125 100644 --- a/src/integration/asserts/caliptra_top_sva.sv +++ b/src/integration/asserts/caliptra_top_sva.sv @@ -19,12 +19,17 @@ `include "config_defines.svh" //`include "kv_defines_pkg.sv" //`include "doe_defines_pkg.sv" -`define CPTRA_TOP_PATH caliptra_top_tb.caliptra_top_dut +`ifdef UVMF_CALIPTRA_TOP +`define CPTRA_TB_TOP_NAME hdl_top +`else +`define CPTRA_TB_TOP_NAME caliptra_top_tb +`endif +`define CPTRA_TOP_PATH `CPTRA_TB_TOP_NAME.caliptra_top_dut `define KEYVAULT_PATH `CPTRA_TOP_PATH.key_vault1 `define DOE_INST_PATH `CPTRA_TOP_PATH.doe.doe_inst `define DOE_PATH `DOE_INST_PATH.doe_fsm1 `define DOE_REG_PATH `DOE_INST_PATH.i_doe_reg -`define SERVICES_PATH caliptra_top_tb.tb_services_i +`define SERVICES_PATH `CPTRA_TB_TOP_NAME.tb_services_i `define SHA512_PATH `CPTRA_TOP_PATH.sha512.sha512_inst `define HMAC_PATH `CPTRA_TOP_PATH.hmac.hmac_inst `define ECC_PATH `CPTRA_TOP_PATH.ecc_top1.ecc_dsa_ctrl_i @@ -35,8 +40,13 @@ `define WDT_PATH `SOC_IFC_TOP_PATH.i_wdt `define SVA_RDC_CLK `CPTRA_TOP_PATH.rdc_clk_cg -`define SVA_CLK caliptra_top_tb.core_clk -`define SVA_RST caliptra_top_tb.cptra_rst_b +`ifdef UVMF_CALIPTRA_TOP + `define SVA_CLK `CPTRA_TB_TOP_NAME.clk + `define SVA_RST `CPTRA_TB_TOP_NAME.soc_ifc_subenv_soc_ifc_ctrl_agent_bus.cptra_rst_b +`else + `define SVA_CLK `CPTRA_TB_TOP_NAME.core_clk + `define SVA_RST `CPTRA_TB_TOP_NAME.cptra_rst_b +`endif module caliptra_top_sva import doe_defines_pkg::*; @@ -430,53 +440,67 @@ module caliptra_top_sva //WDT checks: cascade_wdt_t1_pet: assert property ( - @(posedge `WDT_PATH.clk) - (`WDT_PATH.timer1_restart && !`WDT_PATH.timer2_en) |=> (`WDT_PATH.timer1_count == 'h0) + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer1_restart && !`WDT_PATH.timer2_en && !`WDT_PATH.t1_timeout) |=> (`WDT_PATH.timer1_count == 'h0) ) else $display("SVA ERROR: [Cascade] WDT Timer1 did not restart on pet"); cascade_wdt_t2_pet: assert property ( - @(posedge `WDT_PATH.clk) - (`WDT_PATH.timer2_restart && !`WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) + @(posedge `SVA_RDC_CLK) + (`WDT_PATH.timer2_restart && !`WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer2_count == 'h0) ) else $display("SVA ERROR: [Cascade] WDT Timer2 did not restart on pet"); cascade_wdt_t1_service: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.wdt_timer1_timeout_serviced && !`WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer1_count == 'h0) ) else $display("SVA ERROR: [Cascade] WDT Timer1 did not restart after interrupt service"); cascade_wdt_t2_service: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.wdt_timer2_timeout_serviced && !`WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) ) else $display("SVA ERROR: [Cascade] WDT Timer2 did not restart after interrupt service"); independent_wdt_t1_pet: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.timer1_restart && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer1_count == 'h0) ) else $display("SVA ERROR: [Independent] WDT Timer1 did not restart on pet"); independent_wdt_t2_pet: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.timer2_restart && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) ) else $display("SVA ERROR: [Independent] WDT Timer2 did not restart on pet"); independent_wdt_t1_service: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.wdt_timer1_timeout_serviced && `WDT_PATH.timer2_en && !`WDT_PATH.t2_timeout) |=> (`WDT_PATH.timer1_count == 'h0) ) else $display("SVA ERROR: [Independent] WDT Timer1 did not restart after interrupt service"); independent_wdt_t2_service: assert property ( - @(posedge `WDT_PATH.clk) + @(posedge `SVA_RDC_CLK) (`WDT_PATH.wdt_timer2_timeout_serviced && `WDT_PATH.timer2_en) |=> (`WDT_PATH.timer2_count == 'h0) ) else $display("SVA ERROR: [Independent] WDT Timer2 did not restart after interrupt service"); + wdt_status_t1_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`WDT_PATH.t1_timeout) |=> $rose(`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_WDT_STATUS.t1_timeout.value) + ) + else $display("SVA ERROR: WDT Status bit not set on t1 expiry!"); + + wdt_status_t2_check: assert property ( + @(posedge `SVA_RDC_CLK) + disable iff (~`SVA_RST) + $rose(`WDT_PATH.t2_timeout) |=> $rose(`SOC_IFC_TOP_PATH.soc_ifc_reg_hwif_out.CPTRA_WDT_STATUS.t2_timeout.value) + ) + else $display("SVA ERROR: WDT Status bit not set on t2 expiry!"); + //VALID flag SVA diff --git a/src/integration/config/caliptra_top_tb.vf b/src/integration/config/caliptra_top_tb.vf index 836578fd2..7848871bc 100644 --- a/src/integration/config/caliptra_top_tb.vf +++ b/src/integration/config/caliptra_top_tb.vf @@ -20,6 +20,8 @@ +incdir+${CALIPTRA_ROOT}/src/hmac/coverage +incdir+${CALIPTRA_ROOT}/src/ecc/coverage +incdir+${CALIPTRA_ROOT}/src/soc_ifc/coverage ++incdir+${CALIPTRA_ROOT}/src/pcrvault/coverage ++incdir+${CALIPTRA_ROOT}/src/keyvault/coverage +incdir+${CALIPTRA_ROOT}/src/integration/tb +incdir+${CALIPTRA_ROOT}/src/integration/coverage +incdir+${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl @@ -90,10 +92,17 @@ ${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_if.sv ${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_bind.sv ${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv ${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_bind.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_if.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_props.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_bind.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_if.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_props.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_bind.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb_pkg.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_veer_sram_export.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb_services.sv ${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_if.sv +${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_props.sv ${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_bind.sv ${CALIPTRA_ROOT}/src/integration/test_suites/libs/jtagdpi/jtagdpi.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb.sv diff --git a/src/integration/config/caliptra_top_trng_tb.vf b/src/integration/config/caliptra_top_trng_tb.vf index 6e8b39584..52c42d8ff 100644 --- a/src/integration/config/caliptra_top_trng_tb.vf +++ b/src/integration/config/caliptra_top_trng_tb.vf @@ -20,6 +20,8 @@ +incdir+${CALIPTRA_ROOT}/src/hmac/coverage +incdir+${CALIPTRA_ROOT}/src/ecc/coverage +incdir+${CALIPTRA_ROOT}/src/soc_ifc/coverage ++incdir+${CALIPTRA_ROOT}/src/pcrvault/coverage ++incdir+${CALIPTRA_ROOT}/src/keyvault/coverage +incdir+${CALIPTRA_ROOT}/src/integration/tb +incdir+${CALIPTRA_ROOT}/src/integration/coverage +incdir+${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl @@ -90,10 +92,17 @@ ${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_if.sv ${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_bind.sv ${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv ${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_bind.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_if.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_props.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_bind.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_if.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_props.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_bind.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb_pkg.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_veer_sram_export.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb_services.sv ${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_if.sv +${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_props.sv ${CALIPTRA_ROOT}/src/integration/coverage/caliptra_top_cov_bind.sv ${CALIPTRA_ROOT}/src/integration/test_suites/libs/jtagdpi/jtagdpi.sv ${CALIPTRA_ROOT}/src/integration/tb/caliptra_top_tb.sv diff --git a/src/integration/config/compile.yml b/src/integration/config/compile.yml index 564ce173c..ef8f9ca6f 100644 --- a/src/integration/config/compile.yml +++ b/src/integration/config/compile.yml @@ -74,6 +74,8 @@ requires: - hmac_coverage - ecc_coverage - soc_ifc_coverage + - pcrvault_cov + - keyvault_cov targets: dpi_compile: directories: @@ -101,6 +103,7 @@ targets: - $COMPILE_ROOT/tb/caliptra_veer_sram_export.sv - $COMPILE_ROOT/tb/caliptra_top_tb_services.sv - $COMPILE_ROOT/coverage/caliptra_top_cov_if.sv + - $COMPILE_ROOT/coverage/caliptra_top_cov_props.sv - $COMPILE_ROOT/coverage/caliptra_top_cov_bind.sv - $COMPILE_ROOT/test_suites/libs/jtagdpi/jtagdpi.sv - $COMPILE_ROOT/tb/caliptra_top_tb.sv diff --git a/src/integration/coverage/caliptra_top_cov_bind.sv b/src/integration/coverage/caliptra_top_cov_bind.sv index 7f7903840..fad91e0b9 100644 --- a/src/integration/coverage/caliptra_top_cov_bind.sv +++ b/src/integration/coverage/caliptra_top_cov_bind.sv @@ -16,5 +16,6 @@ module caliptra_top_cov_bind; `ifdef FCOV bind caliptra_top caliptra_top_cov_if i_caliptra_top_cov_if(.*); + bind caliptra_top caliptra_top_cov_props i_caliptra_top_cov_props(.*); `endif endmodule diff --git a/src/integration/coverage/caliptra_top_cov_if.sv b/src/integration/coverage/caliptra_top_cov_if.sv index fe5ff93b3..d07196df5 100644 --- a/src/integration/coverage/caliptra_top_cov_if.sv +++ b/src/integration/coverage/caliptra_top_cov_if.sv @@ -49,8 +49,8 @@ interface caliptra_top_cov_if wdt_t1: coverpoint wdt_timer1_en; wdt_t2: coverpoint wdt_timer2_en; wdt_t1Xt2: cross wdt_t1, wdt_t2; - wdt_t1t2Xwarmrst: cross wdt_t1Xt2, cptra_rst_b; - wdt_t1t2Xcoldrst: cross wdt_t1Xt2, cptra_pwrgood; + // wdt_t1t2Xwarmrst: cross wdt_t1Xt2, cptra_rst_b; + // wdt_t1t2Xcoldrst: cross wdt_t1Xt2, cptra_pwrgood; //----------------------------------------- //CLK GATING coverpoints diff --git a/src/integration/coverage/caliptra_top_cov_props.sv b/src/integration/coverage/caliptra_top_cov_props.sv new file mode 100644 index 000000000..99cb33ffe --- /dev/null +++ b/src/integration/coverage/caliptra_top_cov_props.sv @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2019 Western Digital Corporation or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +// This file contains properties that define various sequences of events in KV + +module caliptra_top_cov_props(); + + `ifndef VERILATOR + + //------------------------------------------------------------------------------ + //Check that WDT was enabled before issuing warm reset + //------------------------------------------------------------------------------ + property cover_prop_wdt_t1_warmrst; + @(posedge soc_ifc_top1.i_wdt.clk) + ($rose(soc_ifc_top1.i_wdt.timer1_en) |-> ##[0:$] !soc_ifc_top1.i_wdt.cptra_rst_b); + endproperty + covprop_wdt_t1_warmrst: cover property(cover_prop_wdt_t1_warmrst); + + property cover_prop_wdt_t2_warmrst; + @(posedge soc_ifc_top1.i_wdt.clk) + ($rose(soc_ifc_top1.i_wdt.timer2_en) |-> ##[0:$] !soc_ifc_top1.i_wdt.cptra_rst_b); + endproperty + covprop_wdt_t2_warmrst: cover property(cover_prop_wdt_t2_warmrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing cold reset + //------------------------------------------------------------------------------ + property cover_prop_wdt_t1_coldrst; + @(posedge soc_ifc_top1.clk) + ($rose(soc_ifc_top1.i_wdt.timer1_en) |=> ##[0:$] !soc_ifc_top1.cptra_pwrgood); + endproperty + covprop_wdt_t1_coldrst: cover property(cover_prop_wdt_t1_coldrst); + + property cover_prop_wdt_t2_coldrst; + @(posedge soc_ifc_top1.clk) + ($rose(soc_ifc_top1.i_wdt.timer2_en) |=> ##[0:$] !soc_ifc_top1.cptra_pwrgood); + endproperty + covprop_wdt_t2_coldrst: cover property(cover_prop_wdt_t2_coldrst); + + `endif + +endmodule \ No newline at end of file diff --git a/src/integration/coverage/config/caliptra_top_tb_cm_hier.cfg b/src/integration/coverage/config/caliptra_top_tb_cm_hier.cfg index f0543f488..56a129afb 100644 --- a/src/integration/coverage/config/caliptra_top_tb_cm_hier.cfg +++ b/src/integration/coverage/config/caliptra_top_tb_cm_hier.cfg @@ -1,3 +1,3 @@ -begin line+tgl+fsm+cond - +tree caliptra_top_tb.caliptra_top 0 +begin line+tgl+fsm+cond+branch + +tree caliptra_top_tb.caliptra_top_dut 0 end diff --git a/src/integration/rtl/caliptra_top.sv b/src/integration/rtl/caliptra_top.sv index f0316d2e2..70713f359 100755 --- a/src/integration/rtl/caliptra_top.sv +++ b/src/integration/rtl/caliptra_top.sv @@ -40,7 +40,7 @@ module caliptra_top input logic jtag_tck, // JTAG clk input logic jtag_tms, // JTAG TMS input logic jtag_tdi, // JTAG tdi - input logic jtag_trst_n, // JTAG Reset //TODO optional needs review + input logic jtag_trst_n, // JTAG Reset output logic jtag_tdo, // JTAG TDO //APB Interface @@ -64,15 +64,11 @@ module caliptra_top output logic [`CALIPTRA_QSPI_IO_WIDTH-1:0] qspi_d_en_o, //UART Interface - // TODO: Determine if this should be set behind a ifdef `ifdef CALIPTRA_INTERNAL_UART output logic uart_tx, input logic uart_rx, `endif - //I3C Interface - //TODO update with I3C interface signals - // Caliptra Memory Export Interface el2_mem_if.veer_sram_src el2_mem_export, @@ -288,7 +284,7 @@ end .AHB_LITE_ADDR_WIDTH(`CALIPTRA_AHB_HADDR_SIZE), .AHB_LITE_DATA_WIDTH(`CALIPTRA_AHB_HDATA_SIZE) ) - responder_inst[`CALIPTRA_AHB_SLAVES_NUM-1:0](); + responder_inst[0:`CALIPTRA_AHB_SLAVES_NUM-1](); //======================================================================== // AHB Master ports @@ -357,16 +353,12 @@ end // RTL instance //=========================================================================- //FIXME TIE OFFS -logic [31:0] jtag_id; logic [31:0] reset_vector; logic [31:0] nmi_vector; logic nmi_int; logic soft_int; logic timer_int; -assign jtag_id[31:28] = 4'b1; -assign jtag_id[27:12] = '0; -assign jtag_id[11:1] = 11'h45; assign reset_vector = `RV_RESET_VEC; assign soft_int = 1'b0; @@ -418,7 +410,6 @@ el2_veer_wrapper rvtop ( .rst_vec ( reset_vector[31:1]), .nmi_int ( nmi_int ), .nmi_vec ( nmi_vector[31:1]), - .jtag_id ( jtag_id[31:1]), .haddr ( ic_haddr ), .hburst ( ic_hburst ), @@ -543,7 +534,7 @@ el2_veer_wrapper rvtop ( .soft_int (soft_int), .core_id ('0), - .scan_mode ( cptra_scan_mode_Latched ), // To enable scan mode + .scan_mode ( scan_mode ), // To enable scan mode .mbist_mode ( 1'b0 ) // to enable mbist ); @@ -1239,7 +1230,7 @@ soc_ifc_top1 .timer_intr(timer_int), //Obfuscated UDS and FE .clear_obf_secrets(clear_obf_secrets_debugScanQ), //input - includes debug & scan modes to do the register clearing - .scan_mode_f(cptra_scan_mode_Latched), + .scan_mode(scan_mode), .cptra_obf_key(cptra_obf_key), .cptra_obf_key_reg(cptra_obf_key_reg), .obf_field_entropy(obf_field_entropy), diff --git a/src/integration/stimulus/L0_regression.yml b/src/integration/stimulus/L0_regression.yml index e979afb51..2614e6710 100644 --- a/src/integration/stimulus/L0_regression.yml +++ b/src/integration/stimulus/L0_regression.yml @@ -58,6 +58,7 @@ contents: #smoke test interrupt handling #smoke test wd timer expiry and nmi generation - ../test_suites/smoke_test_wdt/smoke_test_wdt.yml + - ../test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.yml - ../test_suites/smoke_test_cg_wdt/smoke_test_cg_wdt.yml #smoke test jtag #smoke test generic input wire to fw interrupt diff --git a/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml b/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml index e726e2ba5..7e0ad8302 100644 --- a/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml +++ b/src/integration/stimulus/testsuites/caliptra_top_nightly_directed_regression.yml @@ -11,3 +11,44 @@ contents: - ${CALIPTRA_ROOT}/src/integration/test_suites/fw_test_sha256/fw_test_sha256.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/fw_test_sha384/fw_test_sha384.yml - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_datavault_mini/smoke_test_datavault_mini.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_veer/smoke_test_veer.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_mbox/smoke_test_mbox.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_sha512/smoke_test_sha512.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_sha256/smoke_test_sha256.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_sha_accel/smoke_test_sha_accel.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/memCpy_ROM_to_dccm/memCpy_ROM_to_dccm.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/memCpy_dccm_to_iccm/memCpy_dccm_to_iccm.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/hello_world_iccm/hello_world_iccm.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/iccm_lock/iccm_lock.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/c_intr_handler/c_intr_handler.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_ecc/smoke_test_ecc.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_hmac/smoke_test_hmac.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv/smoke_test_kv.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_sram_ecc/smoke_test_sram_ecc.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_ras/smoke_test_ras.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_trng/smoke_test_trng.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_qspi/smoke_test_qspi.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_uart/smoke_test_uart.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_uds_reset/smoke_test_kv_uds_reset.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_securitystate/smoke_test_kv_securitystate.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_ecc_flow/smoke_test_kv_ecc_flow.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_hmac_flow/smoke_test_kv_hmac_flow.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_sha512_flow/smoke_test_kv_sha512_flow.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_kv_crypto_flow/smoke_test_kv_crypto_flow.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/pv_hash_and_sign/pv_hash_and_sign.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_pcr_signing/smoke_test_pcr_signing.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_fw_kv_backtoback_hmac/smoke_test_fw_kv_backtoback_hmac.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_pcr_zeroize/smoke_test_pcr_zeroize.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_ahb_mux/smoke_test_ahb_mux.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_doe_rand/smoke_test_doe_rand.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_doe_scan/smoke_test_doe_scan.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_zeroize_crypto/smoke_test_zeroize_crypto.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_datavault_basic/smoke_test_datavault_basic.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_datavault_reset/smoke_test_datavault_reset.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_datavault_lock/smoke_test_datavault_lock.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_wdt/smoke_test_wdt.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_cg_wdt/smoke_test_cg_wdt.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_clk_gating/smoke_test_clk_gating.yml + - ${CALIPTRA_ROOT}/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.yml diff --git a/src/integration/stimulus/testsuites/caliptra_top_nightly_random_regression.yml b/src/integration/stimulus/testsuites/caliptra_top_nightly_random_regression.yml index 70c33e93e..0a2c3c918 100644 --- a/src/integration/stimulus/testsuites/caliptra_top_nightly_random_regression.yml +++ b/src/integration/stimulus/testsuites/caliptra_top_nightly_random_regression.yml @@ -16,5 +16,5 @@ contents: path: "{template_basename}__{seed}.yml" templates: $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_rand_test : { weight 100 } - $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test : { weight 100 } - $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_independent_test : { weight 100 } + $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test : { weight 10 } + $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_independent_test : { weight 10 } diff --git a/src/integration/tb/caliptra_top_tb.sv b/src/integration/tb/caliptra_top_tb.sv index ca7f5e21e..66de48009 100755 --- a/src/integration/tb/caliptra_top_tb.sv +++ b/src/integration/tb/caliptra_top_tb.sv @@ -165,6 +165,8 @@ module caliptra_top_tb ( logic cptra_error_fatal_dly_p; logic cptra_error_non_fatal_dly_p; + logic rv_dma_resp_error; + logic mbox_apb_dataout_read_ooo; logic mbox_ooo_read_done; logic mbox_apb_dataout_read_no_lock; @@ -232,7 +234,15 @@ module caliptra_top_tb ( end else if (ras_test_ctrl.reset_generic_input_wires) begin + `ifdef VERILATOR + generic_input_wires <= {32'h72746C76, ERROR_NONE_SET}; /* 32'h72746c76 is the big-endian ASCII representation of 'vltr' (r t l v) */ + `else generic_input_wires <= {32'h0, ERROR_NONE_SET}; + `endif + end + + else if (c_state_apb == S_APB_WAIT_ERROR_AXS && rv_dma_resp_error) begin + generic_input_wires <= {32'h0, DMA_ERROR_OBSERVED}; end else if (c_state_apb == S_APB_RD_HW_ERROR_FATAL && apb_xfer_end) begin @@ -1234,6 +1244,69 @@ caliptra_top_tb_services #( ); +`define RV_INST caliptra_top_dut.rvtop +`define RV_IDMA_RESP_INST caliptra_top_dut.responder_inst[`CALIPTRA_SLAVE_SEL_IDMA] +`define RV_DDMA_RESP_INST caliptra_top_dut.responder_inst[`CALIPTRA_SLAVE_SEL_DDMA] +task force_ahb_dma_read(input logic [31:0] address); + while(`RV_INST.dma_hsel) @(posedge core_clk); + force `RV_IDMA_RESP_INST.hreadyout = 1'b0; + force `RV_DDMA_RESP_INST.hreadyout = 1'b0; + + force `RV_INST.dma_haddr = address; + force `RV_INST.dma_hsize = 3'b010; // 4-bytes + force `RV_INST.dma_hwrite = 1'b0; + force `RV_INST.dma_hwdata = '0; + force `RV_INST.dma_hreadyin = 1'b1; + force `RV_INST.dma_hsel = 1'b1; + force `RV_INST.dma_htrans = 2'b10; + + // Wait for command to be accepted + do @(posedge core_clk); while(!`RV_INST.dma_hreadyout); + force `RV_INST.dma_htrans = 2'b00; + // Wait for response to be provided + do @(posedge core_clk); while(!`RV_INST.dma_hreadyout); + $display("[%t] AHB DMA FORCE READ: Address 0x%x Data 0x%x Resp 0x%x", $time, address, `RV_INST.dma_hrdata, `RV_INST.dma_hresp); + if (`RV_INST.dma_hresp) + rv_dma_resp_error = 1'b1; + release `RV_IDMA_RESP_INST.hreadyout; + release `RV_DDMA_RESP_INST.hreadyout; + + release `RV_INST.dma_htrans; + release `RV_INST.dma_haddr; + release `RV_INST.dma_hsize; + release `RV_INST.dma_hwrite; + release `RV_INST.dma_hwdata; + release `RV_INST.dma_hsel; + release `RV_INST.dma_hreadyin; +endtask + +task force_ahb_dma_loop_read(input logic [31:0] start_addr, input logic [19:0] count); + automatic logic [31:0] addr; + addr = start_addr; + $display("[%t] AHB DMA FORCE LOOP READ: Start Address 0x%x Count 0x%x", $time, addr, count); + if ($isunknown(start_addr) || $isunknown(addr)) + $error("[%t] Unknown signal found: start_addr 0x%x addr 0x%x", $time, start_addr, addr); + repeat(count) begin + force_ahb_dma_read(addr); + addr += 4; + end +endtask + +initial begin + fork + forever @(posedge core_clk) begin + if (ras_test_ctrl.dccm_read_burst.start) + force_ahb_dma_loop_read(ras_test_ctrl.dccm_read_burst.addr, ras_test_ctrl.dccm_read_burst.count); + if (ras_test_ctrl.iccm_read_burst.start) + force_ahb_dma_loop_read(ras_test_ctrl.iccm_read_burst.addr, ras_test_ctrl.iccm_read_burst.count); + end + forever @(posedge core_clk) begin + if (c_state_apb != S_APB_WAIT_ERROR_AXS) + rv_dma_resp_error = 1'b0; + end + join +end + caliptra_top_sva sva(); endmodule diff --git a/src/integration/tb/caliptra_top_tb_pkg.sv b/src/integration/tb/caliptra_top_tb_pkg.sv index 8a14afeb7..28f97e6f2 100644 --- a/src/integration/tb/caliptra_top_tb_pkg.sv +++ b/src/integration/tb/caliptra_top_tb_pkg.sv @@ -58,6 +58,13 @@ typedef struct packed { } veer_sram_error_injection_mode_t; typedef struct packed { + logic [31:0] addr; + logic [19:0] count; + logic start; +} rv_ccm_read_burst_pkt; +typedef struct packed { + rv_ccm_read_burst_pkt dccm_read_burst; + rv_ccm_read_burst_pkt iccm_read_burst; logic error_injection_seen; logic reset_generic_input_wires; logic do_no_lock_access; @@ -73,6 +80,7 @@ localparam PROT_OOO_NON_FATAL_OBSERVED = 32'h600dcafe; localparam ICCM_FATAL_OBSERVED = 32'hdeadaca1; localparam DCCM_FATAL_OBSERVED = 32'hdeadbeef; localparam NMI_FATAL_OBSERVED = 32'hdeadc0a7; +localparam DMA_ERROR_OBSERVED = 32'hfadebadd; localparam ERROR_NONE_SET = 32'hba5eba11; /* default value for a test with no activity observed by TB */ endpackage diff --git a/src/integration/tb/caliptra_top_tb_services.sv b/src/integration/tb/caliptra_top_tb_services.sv index e274b6565..8d167d0e7 100644 --- a/src/integration/tb/caliptra_top_tb_services.sv +++ b/src/integration/tb/caliptra_top_tb_services.sv @@ -169,6 +169,8 @@ module caliptra_top_tb_services logic inject_zero_sign_r; logic inject_zero_sign_r_needs_release; + logic inject_zero_sign_s; + logic inject_zero_sign_s_needs_release; logic en_jtag_access; @@ -235,8 +237,11 @@ module caliptra_top_tb_services // 8'h92 - Check PCR singing with randomized vector // 8'h98 - Inject invalid zero sign_r into ECC // 8'h99 - Inject zeroize into HMAC + // 8'h9a - Inject invalid zero sign_s into ECC // 8'ha0: 8'ha7 - Inject HMAC_KEY to kv_key register // 8'hc0: 8'hc7 - Inject SHA_BLOCK to kv_key register + // 8'hde - ICCM SRAM force loop read (requires read params written to other bytes of generic wires) + // 8'hdf - DCCM SRAM force loop read (requires read params written to other bytes of generic wires) // 8'he0 - Set random ICCM SRAM single bit error injection // 8'he1 - Set random ICCM SRAM double bit error injection // 8'he2 - Set random DCCM SRAM single bit error injection @@ -336,6 +341,41 @@ module caliptra_top_tb_services end end + always @(negedge clk or negedge cptra_rst_b) begin + if (!cptra_rst_b) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + else if((WriteData[7:0] == 8'hde) && mailbox_write) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b1; + ras_test_ctrl.iccm_read_burst.count <= WriteData[31:12]; + ras_test_ctrl.iccm_read_burst.addr <= caliptra_top_dut.soc_ifc_top1.i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[1].generic_wires.value; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + else if((WriteData[7:0] == 8'hdf) && mailbox_write) begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b1; + ras_test_ctrl.dccm_read_burst.count <= WriteData[31:12]; + ras_test_ctrl.dccm_read_burst.addr <= caliptra_top_dut.soc_ifc_top1.i_soc_ifc_reg.field_storage.CPTRA_GENERIC_OUTPUT_WIRES[1].generic_wires.value; + end + else begin + ras_test_ctrl.iccm_read_burst.start <= 1'b0; + ras_test_ctrl.iccm_read_burst.count <= '0; + ras_test_ctrl.iccm_read_burst.addr <= '0; + ras_test_ctrl.dccm_read_burst.start <= 1'b0; + ras_test_ctrl.dccm_read_burst.count <= '0; + ras_test_ctrl.dccm_read_burst.addr <= '0; + end + end + initial ras_test_ctrl.error_injection_seen = 1'b0; always @(negedge clk) begin if (mailbox_write && WriteData[7:0] == 8'hfd) begin @@ -450,10 +490,15 @@ module caliptra_top_tb_services if (~cptra_rst_b) begin inject_zero_sign_r <= 1'b0; inject_zero_sign_r_needs_release <= 1'b0; + inject_zero_sign_s <= 1'b0; + inject_zero_sign_s_needs_release <= 1'b0; end else if((WriteData[7:0] == 8'h98) && mailbox_write) begin inject_zero_sign_r <= 1'b1; end + else if((WriteData[7:0] == 8'h9a) && mailbox_write) begin + inject_zero_sign_s <= 1'b1; + end else if(inject_zero_sign_r) begin if (caliptra_top_dut.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd21) begin //R_ID force caliptra_top_dut.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '0; @@ -463,6 +508,15 @@ module caliptra_top_tb_services inject_zero_sign_r <= 1'b0; end end + else if(inject_zero_sign_s) begin + if (caliptra_top_dut.ecc_top1.ecc_dsa_ctrl_i.prog_instr.reg_id == 6'd22) begin //S_ID + force caliptra_top_dut.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o = '0; + inject_zero_sign_s_needs_release <= 1'b1; + end + else if (inject_zero_sign_s_needs_release) begin + inject_zero_sign_s <= 1'b0; + end + end else begin release caliptra_top_dut.ecc_top1.ecc_dsa_ctrl_i.ecc_arith_unit_i.d_o; end @@ -1660,6 +1714,8 @@ sha512_ctrl_cov_bind i_sha512_ctrl_cov_bind(); sha256_ctrl_cov_bind i_sha256_ctrl_cov_bind(); hmac_ctrl_cov_bind i_hmac_ctrl_cov_bind(); ecc_top_cov_bind i_ecc_top_cov_bind(); +keyvault_cov_bind i_keyvault_cov_bind(); +pcrvault_cov_bind i_pcrvault_cov_bind(); `endif /* verilator lint_off CASEINCOMPLETE */ diff --git a/src/integration/test_suites/caliptra_rt/caliptra_rt.c b/src/integration/test_suites/caliptra_rt/caliptra_rt.c index 5474d3032..b54dc54fc 100644 --- a/src/integration/test_suites/caliptra_rt/caliptra_rt.c +++ b/src/integration/test_suites/caliptra_rt/caliptra_rt.c @@ -36,6 +36,7 @@ #include #include #include "printf.h" +#include "wdt.h" /* --------------- Global symbols/typedefs --------------- */ extern uintptr_t STACK; @@ -142,7 +143,7 @@ void caliptra_rt() { lsu_write_32((uintptr_t) (CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR), (uint32_t) (nmi_handler)); // Initialize rand num generator - VPRINTF(LOW,"\nUsing random seed = %d\n\n", MY_RANDOM_SEED); + VPRINTF(LOW,"\nUsing random seed = %u\n\n", (uint32_t) MY_RANDOM_SEED); srand((uint32_t) MY_RANDOM_SEED); // Runtime flow -- set ready for RT @@ -154,71 +155,64 @@ void caliptra_rt() { lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R, SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK); //Generate constrained random WDT timer periods - wdt_rand_t1_val = rand() % 0xfff; - wdt_rand_t2_val = rand() % 0xfff; + wdt_rand_t1_val = rand() % 0xfff + 0x5; + wdt_rand_t2_val = rand() % 0xfff + 0x5; while (!(lsu_read_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R) & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK)); if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0) == WDT_CASCADE) { //rand() % 2; //0 - independent mode, 1 - cascade mode VPRINTF(LOW, "Restarting WDT in cascade mode\n"); - //Enable timer1 to start cascade mode - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN, SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK); - //Set timer1 period to a small random value, so core can see timer1 timing out - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, wdt_rand_t1_val); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0x00000000); - //Restart timer1 - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK); - - while (!(lsu_read_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R) & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK)); - //Clear timer1 intr - lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R, SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK); - - //Program timer1 and 2 periods to <= 0x100 to test NMI generation - wdt_rand_t1_val = rand() % 0x100; - wdt_rand_t2_val = rand() % 0x100; - //WDT cascade mode with t2 timeout - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN, !SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, wdt_rand_t1_val); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0x00000000); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0, wdt_rand_t2_val); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1, 0x00000000); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK); - // lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_MASK); - + // //Enable timer1 to start cascade mode + configure_wdt_cascade(wdt_rand_t1_val, 0x00000000, 0xffffffff, 0xffffffff); + service_t1_intr(); + + //Disable timers before next testing + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN, 0); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN, 0); + + //Program timer1 and 2 periods to <= 0x100 to test NMI generation. First check if there is any pending timer1 interrupt. In a corner case scenario, timer1 can timeout a second time (if the period is small enough) + //before its timeout value is changed in prep for NMI testing. In that case, the subsequent timer1 interrupt will not be serviced resulting in a hang + wdt_rand_t1_val = (rand() % 0x100) + 0x5; + wdt_rand_t2_val = (rand() % 0x100) + 0x5; + + if (lsu_read_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R) & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK) + lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R, SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK); + + // //WDT cascade mode with t2 timeout + configure_wdt_cascade(wdt_rand_t1_val, 0x00000000, wdt_rand_t2_val, 0x00000000); //Don't service interrupts so it can timeout and cause NMI } else if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_GENERIC_INPUT_WIRES_0) == WDT_INDEPENDENT){ - VPRINTF(LOW, "Restarting WDT in independent mode\n"); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN, SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, wdt_rand_t1_val); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0x00000000); - - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN, SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0, wdt_rand_t2_val); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1, 0x00000000); - - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_MASK); + + //------------------------------------------- + //Test independent mode - both timers enabled + //------------------------------------------- + configure_wdt_independent(BOTH_TIMERS_EN, wdt_rand_t1_val, 0x00000000, wdt_rand_t2_val, 0x00000000); while (!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T1_TIMEOUT_MASK)); //Reset timer1 period to avoid hangs in test - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, 0xffffffff); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0xffffffff); + set_default_t1_period(); - while (!(lsu_read_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R) & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK)); - //Clear timer1 intr - lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R, SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK); + service_t1_intr(); cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK; //Reset timer2 period to avoid hangs in test while (!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK)); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0, 0xffffffff); - lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1, 0xffffffff); + set_default_t2_period(); - while (!(lsu_read_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R) & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK)); - //Clear timer2 intr - lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R, SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK); + service_t2_intr(); cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK; + //------------------------------------------- + //Test independent mode - only timer2 enabled + //------------------------------------------- + configure_wdt_independent(T1_DIS_T2_EN, wdt_rand_t1_val, 0x00000000, wdt_rand_t2_val, 0x00000000); + + //Reset timer2 period to avoid hangs in test + while (!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK)); + set_default_t2_period(); + + service_t2_intr(); + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK; } #endif // Initialization @@ -331,20 +325,58 @@ void caliptra_rt() { VPRINTF(LOW, "Intr received: soc_ifc_notif\n"); if (cptra_intr_rcv.soc_ifc_notif & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) { CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_notif, ~SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) + // Always check mbox FSM state at new command entry to detect + // previously-handled error scenarios (FSM is IDLE) or new error + // injection (FSM is in ERROR) fsm_chk = soc_ifc_chk_execute_uc(); if (fsm_chk != 0) { if (fsm_chk == 0xF) { if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) - VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (cmd fail) after servicing\n"); + VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (cmd fail) prior to servicing\n"); } else { - VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n"); + VPRINTF(ERROR, "After finding an error requiring mailbox reset with force unlock, RT firmware has not received an soc_ifc_err_intr!\n"); SEND_STDOUT_CTRL(0x1); while(1); } + lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); + // This oftens occurs alongside the cmd_fail bit in error injection tests... + if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK) { + CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK) + VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (inv dev) after servicing\n"); + } } continue; } + // Clear any uncorrectable ECC error interrupts that may have held over from the previous operation + // This can happen after the command flow is transferred back to SOC + // if the ECC error occurred at address 0, since ending the flow triggers + // rst_mbox_rdptr and a final read from 0. This might be missed by the above + // soc_ifc_error handler. + // There might also be vestigial cmd_fail/inv_dev failures held over from a previous + // invalid reg_axs sequence... clear those too + if (cptra_intr_rcv.soc_ifc_error & (SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK | + SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK | + SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK )) { + CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK & + ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK & + ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK) + // Run the FSM check once more for late-arrival of errors + // that may correlate with the observed error interrupt + fsm_chk = soc_ifc_chk_execute_uc(); + if (fsm_chk) { + if (fsm_chk == 0xF) { + lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); + } + continue; + } + } + // Any other errors that are flagged at this point are unexpected and should cause a test failure + if (cptra_intr_rcv.soc_ifc_error) { + VPRINTF(ERROR, "Unexpected err intr 0x%x\n", cptra_intr_rcv.soc_ifc_error); + SEND_STDOUT_CTRL(0x1); + while(1); + } //read the mbox command op = soc_ifc_read_mbox_cmd(); if (op.cmd & MBOX_CMD_FIELD_FW_MASK) { @@ -408,6 +440,35 @@ void caliptra_rt() { } soc_ifc_sha_accel_clr_lock(); } + else if ((op.cmd == MBOX_CMD_SHA384_STREAM_REQ) | (op.cmd == MBOX_CMD_SHA512_STREAM_REQ)) { + enum sha_accel_mode_e mode; + mode = (op.cmd == MBOX_CMD_SHA384_STREAM_REQ) ? SHA_STREAM_384 : SHA_STREAM_512; + //First dword contains the start address + temp = soc_ifc_mbox_read_dataout_single(); + //ignore the bytes used for start address + op.dlen = op.dlen - 4; + //Acquire SHA Accel lock + soc_ifc_sha_accel_acquire_lock(); + soc_ifc_sha_accel_wr_mode(mode); + //write dlen in bytes + lsu_write_32((uintptr_t) (CLP_SHA512_ACC_CSR_DLEN), op.dlen); + //Stream the KAT to the sha accelerator + for (loop_iter = 0; loop_iter #include #include "printf.h" +#include "riscv_hw_if.h" +#include "wdt.h" volatile char* stdout = (char *)STDOUT; volatile uint32_t intr_count = 0; @@ -83,21 +85,21 @@ void main() { VPRINTF(LOW, "Cascaded mode\n"); //Enable WDT timer1 *wdt_timer1_en = SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK; - *wdt_timer1_period_0 = 0x00000040; - *wdt_timer1_period_1 = 0x00000000; + set_t1_period(0x00000040, 0x00000000); + VPRINTF(LOW, "Stall until timer1 times out\n"); + while (!(lsu_read_32(SOC_IFC_REG_CPTRA_WDT_STATUS_T1_TIMEOUT_MASK))); + VPRINTF(LOW, "WDT T1 timed out as expected\n"); *wdt_timer1_ctrl = SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK; - //Set timer1 period to something else to avoid immediate time out - *wdt_timer1_period_0 = 0x0000FFFF; - *wdt_timer1_period_1 = 0x00000000; + //Set timer1 period to default to avoid immediate time out + set_default_t1_period(); - VPRINTF(LOW, "Independent mode\n"); + VPRINTF(LOW, "Independent mode - both timers enabled\n"); //Enable WDT timer1 *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; - *wdt_timer2_period_0 = 0x00000040; - *wdt_timer2_period_1 = 0x00000000; + set_t2_period(0x00000040, 0x00000000); VPRINTF(LOW, "Stall until timer2 times out\n"); //Release forced timer periods from tb so test can set them @@ -108,21 +110,31 @@ void main() { *wdt_timer1_ctrl = 0x1; //restart counter so timer1 can start counting rst_count++; //Increment count so when NMI is processed we advance in the test - *wdt_timer1_period_0 = 0x00000040; - *wdt_timer1_period_1 = 0x00000000; + set_t1_period(0x00000040, 0x00000000); - VPRINTF(LOW, "Stall until timer1 times out"); - VPRINTF(LOW, "Stall until timer2 times out"); + VPRINTF(LOW, "Stall until timer1 times out\n"); + VPRINTF(LOW, "Stall until timer2 times out\n"); } else if(rst_count == 1) { //Issue warm reset after NMI as per spec + VPRINTF(LOW, "Issuing reset in response to NMI (t2 timeout)\n"); rst_count++; SEND_STDOUT_CTRL(0xf6); } else { + VPRINTF(LOW, "Independent mode - timer2 enabled, timer1 disabled\n"); + *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; + set_t2_period(0x00000040, 0x00000000); + + VPRINTF(LOW, "Stall until timer2 times out\n"); + while (!(lsu_read_32(SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK))); + VPRINTF(LOW, "WDT T2 timed out as expected\n") + //Release forced timer periods from tb so test can set them + // SEND_STDOUT_CTRL(0xf1); + //Write 1 to clear HW fatal error register if ((*hw_error_fatal && SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK) == 1) { *hw_error_fatal = SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK; diff --git a/src/integration/test_suites/smoke_test_wdt_rst/caliptra_isr.h b/src/integration/test_suites/smoke_test_wdt_rst/caliptra_isr.h new file mode 100644 index 000000000..ddad5ade5 --- /dev/null +++ b/src/integration/test_suites/smoke_test_wdt_rst/caliptra_isr.h @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// +// --------------------------------------------------------------------- +// File: caliptra_isr.h +// Description: +// Provides function declarations for use by external test files, so +// that the ISR functionality may behave like a library. +// TODO: +// This header file includes inline function definitions for event and +// test specific interrupt service behavior, so it should be copied and +// modified for each test. +// --------------------------------------------------------------------- + +#ifndef CALIPTRA_ISR_H + #define CALIPTRA_ISR_H + +#define EN_ISR_PRINTS 1 + +#include "caliptra_defines.h" +#include +#include "printf.h" + +//extern volatile uint32_t hmac_intr_status; + +/* --------------- symbols/typedefs --------------- */ +typedef struct { + uint32_t doe_error; + uint32_t doe_notif; + uint32_t ecc_error; + uint32_t ecc_notif; + uint32_t hmac_error; + uint32_t hmac_notif; + uint32_t kv_error; + uint32_t kv_notif; + uint32_t sha512_error; + uint32_t sha512_notif; + uint32_t sha256_error; + uint32_t sha256_notif; + uint32_t qspi_error; + uint32_t qspi_notif; + uint32_t uart_error; + uint32_t uart_notif; + uint32_t i3c_error; + uint32_t i3c_notif; + uint32_t soc_ifc_error; + uint32_t soc_ifc_notif; + uint32_t sha512_acc_error; + uint32_t sha512_acc_notif; +} caliptra_intr_received_s; +extern volatile caliptra_intr_received_s cptra_intr_rcv; + +////////////////////////////////////////////////////////////////////////////// +// Function Declarations +// +// Performs all the CSR setup to configure and enable vectored external interrupts +void init_interrupts(void); + +// These inline functions are used to insert event-specific functionality into the +// otherwise generic ISR that gets laid down by the parameterized macro "nonstd_veer_isr" +inline void service_doe_error_intr() {printf("ERROR");} +inline void service_doe_notif_intr() {printf("ERROR");} +inline void service_ecc_error_intr () {printf("ERROR");} +inline void service_ecc_notif_intr () {printf("ERROR");} +inline void service_hmac_error_intr () {printf("ERROR");} +inline void service_hmac_notif_intr () {printf("ERROR");} + +inline void service_kv_error_intr () {printf("ERROR");} +inline void service_kv_notif_intr () {printf("ERROR");} +inline void service_sha512_error_intr() {printf("ERROR");} +inline void service_sha512_notif_intr() {printf("ERROR");} +inline void service_sha256_error_intr() {printf("ERROR");} +inline void service_sha256_notif_intr() {printf("ERROR");} +inline void service_qspi_error_intr () {printf("ERROR");} +inline void service_qspi_notif_intr () {printf("ERROR");} +inline void service_uart_error_intr () {printf("ERROR");} +inline void service_uart_notif_intr () {printf("ERROR");} +inline void service_i3c_error_intr () {printf("ERROR");} +inline void service_i3c_notif_intr () {printf("ERROR");} +inline void service_soc_ifc_error_intr () { + // uint32_t * reg = (uint32_t *) (CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R); + // uint32_t sts = *reg; + // //Write 1 to clear pending interrupt + // if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK) { + // *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK; + // } + // //Write 1 to clear pending interrupt + // if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK) { + // *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK; + // } +} +inline void service_soc_ifc_notif_intr () {printf("ERROR");} +inline void service_sha512_acc_error_intr() {printf("ERROR");} +inline void service_sha512_acc_notif_intr() {printf("ERROR");} + + +#endif //CALIPTRA_ISR_H diff --git a/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.c b/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.c new file mode 100644 index 000000000..f472b3c2f --- /dev/null +++ b/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 "caliptra_defines.h" +#include "caliptra_isr.h" +#include "riscv-csr.h" +#include +#include +#include "printf.h" +#include "riscv_hw_if.h" +#include "wdt.h" + +volatile char* stdout = (char *)STDOUT; +volatile uint32_t intr_count = 0; +volatile uint32_t rst_count __attribute__((section(".dccm.persistent"))) = 0; + +#ifdef CPT_VERBOSITY + enum printf_verbosity verbosity_g = CPT_VERBOSITY; +#else + enum printf_verbosity verbosity_g = LOW; +#endif + +volatile uint32_t * wdt_timer1_en = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN; +volatile uint32_t * wdt_timer1_ctrl = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL; +volatile uint32_t * wdt_timer1_period_0 = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0; +volatile uint32_t * wdt_timer1_period_1 = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1; +volatile uint32_t * soc_intr_en = (uint32_t *) CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R; +volatile uint32_t * soc_global_intr_en = (uint32_t *) CLP_SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R; + +volatile uint32_t * wdt_timer2_en = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN; +volatile uint32_t * wdt_timer2_ctrl = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL; +volatile uint32_t * wdt_timer2_period_0 = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0; +volatile uint32_t * wdt_timer2_period_1 = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1; + +volatile uint32_t * hw_error_fatal = (uint32_t *) CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL; + +volatile caliptra_intr_received_s cptra_intr_rcv = { + .doe_error = 0, + .doe_notif = 0, + .ecc_error = 0, + .ecc_notif = 0, + .hmac_error = 0, + .hmac_notif = 0, + .kv_error = 0, + .kv_notif = 0, + .sha512_error = 0, + .sha512_notif = 0, + .sha256_error = 0, + .sha256_notif = 0, + .qspi_error = 0, + .qspi_notif = 0, + .uart_error = 0, + .uart_notif = 0, + .i3c_error = 0, + .i3c_notif = 0, + .soc_ifc_error = 0, + .soc_ifc_notif = 0, + .sha512_acc_error = 0, + .sha512_acc_notif = 0, +}; + +void nmi_handler (void); + +void nmi_handler (void) { + VPRINTF(LOW, "**** Entering NMI Handler ****\n"); + if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL) & SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK) { + SEND_STDOUT_CTRL(0xf5); + } + else { + VPRINTF(ERROR, "Unexpected entry into NMI handler function!\n"); + } + +} + +void main() { + VPRINTF(LOW, "---------------------------\n"); + VPRINTF(LOW, " WDT Smoke Test with reset !!\n"); + VPRINTF(LOW, "---------------------------\n"); + + //Enable SOC error interrupt + *soc_global_intr_en = SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK; + *soc_intr_en = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER1_TIMEOUT_EN_MASK | SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER2_TIMEOUT_EN_MASK; + + //Call interrupt init + // init_interrupts(); + + rst_count++; + + // Setup the NMI Handler + lsu_write_32((uintptr_t) (CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR), (uint32_t) (nmi_handler)); + + if(rst_count == 1) { + VPRINTF(LOW, "Cascaded mode\n"); + configure_wdt_cascade(0x200, 0x00, 0xffffffff, 0xffffffff); + + VPRINTF(LOW, "Stall until timer1 times out\n"); + service_t1_intr(); + + SEND_STDOUT_CTRL(0xf6); + } + else if (rst_count == 2) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + configure_wdt_cascade(0x200, 0x00, 0xffffffff, 0xffffffff); + + *wdt_timer1_ctrl = SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK; + + service_t1_intr(); + SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 3) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + // configure_wdt_cascade(0x200, 0x00, 0xffffffff, 0xffffffff); + // set_t2_period(0x00000200, 0x00000000); + configure_wdt_independent(BOTH_TIMERS_EN, 0x200, 0x00000000, 0x200, 0x00000000); + //Enable WDT timer2 + // *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; + + VPRINTF(LOW, "Independent mode - both timers enabled - warm rst\n"); + + VPRINTF(LOW, "Stall until timer1 times out\n"); + service_t1_intr(); + //reset t1 + *wdt_timer1_en = 0; + + service_t2_intr(); + //reset t2 + *wdt_timer2_en = 0; + + SEND_STDOUT_CTRL(0xf6); + } + else if (rst_count == 4) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + // configure_wdt_cascade(0x200, 0x00, 0xffffffff, 0xffffffff); + configure_wdt_independent(BOTH_TIMERS_EN, 0x200, 0x00000000, 0x200, 0x00000000); + + VPRINTF(LOW, "Independent mode - both timers enabled - cold rst\n"); + //Enable WDT timer1 + // *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; + // set_t2_period(0x00000200, 0x00000000); + + VPRINTF(LOW, "Stall until timer1 times out\n"); + service_t1_intr(); + *wdt_timer1_en = 0; + + VPRINTF(LOW, "Stall until timer2 times out\n"); + service_t2_intr(); + *wdt_timer2_en = 0; + + SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 5) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + configure_wdt_cascade(0x200, 0x00, 0xffffffff, 0xffffffff); + VPRINTF(LOW, "Cascaded mode with timer2 timeout - NMI - cold rst\n"); + *wdt_timer2_en = 0x0; + *wdt_timer1_ctrl = 0x1; //restart counter so timer1 can start counting + + set_t2_period(0x00000200, 0x00000000); + + VPRINTF(LOW, "Stall until timer1 times out\n"); + VPRINTF(LOW, "Stall until timer2 times out\n"); + // while (!(lsu_read_32(SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK)); + // service_t2_intr(); + while(!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL) & SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK)); + + //Not executed since handler issues reset + //Issue warm reset after NMI as per spec + // VPRINTF(LOW, "Issuing reset in response to NMI (t2 timeout)\n"); + // SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 6) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + //Write 1 to clear HW fatal error register + if ((*hw_error_fatal && SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK) == 1) { + VPRINTF(ERROR, "Cold rst should have reset hw_fatal_error nmi_pin!\n"); + SEND_STDOUT_CTRL(0x1); + } + + VPRINTF(LOW, "Independent mode - timer2 enabled, timer1 disabled - warm rst\n"); + *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; + set_t2_period(0x00000200, 0x00000000); + + VPRINTF(LOW, "Stall until timer2 times out\n"); + service_t2_intr(); + *wdt_timer2_en = 0; + + SEND_STDOUT_CTRL(0xf6); + + } + else if (rst_count == 7) { + //Release forced timer periods from tb so test can set them + SEND_STDOUT_CTRL(0xf1); + VPRINTF(LOW, "Independent mode - timer2 enabled, timer1 disabled - cold rst\n"); + // *wdt_timer2_en = SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK; + // set_t2_period(0x00000200, 0x00000000); + configure_wdt_independent(T1_DIS_T2_EN, 0x200, 0x00000000, 0x200, 0x00000000); + + VPRINTF(LOW, "Stall until timer2 times out\n"); + service_t2_intr(); + *wdt_timer2_en = 0; + + SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 8) { + //Issue warm reset during WDT operation + //WDT cascade mode + configure_wdt_cascade(0x37, 0x00, 0xffffffff, 0xffffffff); + SEND_STDOUT_CTRL(0xf6); + } + else if (rst_count == 9) { + //Issue cold reset during WDT operation + configure_wdt_cascade(0x37, 0x00, 0xffffffff, 0xffffffff); + SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 10) { + //Issue warm reset during WDT operation + //WDT cascade mode + configure_wdt_independent(BOTH_TIMERS_EN, 0x200, 0x00000000, 0x34, 0x00000000); + SEND_STDOUT_CTRL(0xf6); + } + else if (rst_count == 11) { + //Issue warm reset during WDT operation + //WDT cascade mode + configure_wdt_independent(BOTH_TIMERS_EN, 0x200, 0x00000000, 0x34, 0x00000000); + SEND_STDOUT_CTRL(0xf5); + } + else if (rst_count == 12) { + //Issue warm reset during WDT operation + //WDT cascade mode + configure_wdt_independent(T1_DIS_T2_EN, 0x200, 0x00000000, 0x200, 0x00000000); + SEND_STDOUT_CTRL(0xf6); + } + else if (rst_count == 13) { + //Issue warm reset during WDT operation + //WDT cascade mode + configure_wdt_independent(T1_DIS_T2_EN, 0x200, 0x00000000, 0x200, 0x00000000); + SEND_STDOUT_CTRL(0xf5); + } + else { + VPRINTF(LOW, "End of test\n"); + } +} diff --git a/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.yml b/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.yml new file mode 100644 index 000000000..0a06f3a4f --- /dev/null +++ b/src/integration/test_suites/smoke_test_wdt_rst/smoke_test_wdt_rst.yml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# 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. +# +--- +seed: 1 +testname: smoke_test_wdt_rst diff --git a/src/integration/uvmf_caliptra_top/config/compile.yml b/src/integration/uvmf_caliptra_top/config/compile.yml index a6eaa74e2..a2f5c1c7e 100644 --- a/src/integration/uvmf_caliptra_top/config/compile.yml +++ b/src/integration/uvmf_caliptra_top/config/compile.yml @@ -15,12 +15,15 @@ provides: [uvmf_caliptra_top] schema_version: 2.4.0 requires: - uvmf_caliptra_top_vip + - asserts - caliptra_top - sha512_coverage - sha256_coverage - hmac_coverage - ecc_coverage - soc_ifc_coverage + - pcrvault_cov + - keyvault_cov targets: tb: directories: @@ -37,6 +40,7 @@ targets: - ${COMPILE_ROOT}/../tb/caliptra_veer_sram_export.sv - ${COMPILE_ROOT}/../tb/caliptra_top_tb_services.sv - ${COMPILE_ROOT}/../coverage/caliptra_top_cov_if.sv + - ${COMPILE_ROOT}/../coverage/caliptra_top_cov_props.sv - ${COMPILE_ROOT}/../coverage/caliptra_top_cov_bind.sv - ${COMPILE_ROOT}/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv - ${COMPILE_ROOT}/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hvl_top.sv @@ -54,6 +58,7 @@ global: default: - '-assert svaext' - +define+CLP_ASSERT_ON + - +define+UVMF_CALIPTRA_TOP #- '-v2k_generate' #- '-timescale=1ns/1ps' - '-noinherit_timescale=1ns/1ps' @@ -99,6 +104,7 @@ global: default: - '-assert svaext' - +define+CLP_ASSERT_ON + - +define+UVMF_CALIPTRA_TOP - '-noinherit_timescale=1ns/1ps' - '+define+CALIPTRA_INTERNAL_TRNG' # Suppress a warning due to calling $fgets as task instead of function diff --git a/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top.vf b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top.vf new file mode 100644 index 000000000..219eb6217 --- /dev/null +++ b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top.vf @@ -0,0 +1,452 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg ++incdir+${CALIPTRA_ROOT}/src/doe/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/asserts ++incdir+${CALIPTRA_ROOT}/src/datavault/rtl ++incdir+${CALIPTRA_ROOT}/src/entropy_src/rtl ++incdir+${CALIPTRA_ROOT}/src/caliptra_prim/rtl ++incdir+${CALIPTRA_ROOT}/src/lc_ctrl/rtl ++incdir+${CALIPTRA_ROOT}/src/entropy_src/tb ++incdir+${CALIPTRA_ROOT}/src/csrng/rtl ++incdir+${CALIPTRA_ROOT}/src/spi_host/rtl ++incdir+${CALIPTRA_ROOT}/src/uart/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512/coverage ++incdir+${CALIPTRA_ROOT}/src/sha256/coverage ++incdir+${CALIPTRA_ROOT}/src/hmac/coverage ++incdir+${CALIPTRA_ROOT}/src/ecc/coverage ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/coverage ++incdir+${CALIPTRA_ROOT}/src/pcrvault/coverage ++incdir+${CALIPTRA_ROOT}/src/keyvault/coverage ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl ++incdir+${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl ++incdir+${CALIPTRA_ROOT}/src/sha256/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512_masked/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac_drbg/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/rtl ++incdir+${CALIPTRA_ROOT}/src/kmac/rtl ++incdir+${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl ++incdir+${CALIPTRA_ROOT}/src/edn/rtl ++incdir+${CALIPTRA_ROOT}/src/aes/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/include/el2_def.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/common_defines.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/caliptra_top_env_pkg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_defines_pkg.sv +${CALIPTRA_ROOT}/src/integration/asserts/caliptra_top_sva.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_defines_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_main_sm_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_ack_sm_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_reg_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_cipher_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sparse_fsm_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_state_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/tb/physical_rng.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_reg_pkg.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_pkg.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_reg_pkg.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_cmd_pkg.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_if.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_bind.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_bind.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_if.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_props.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_bind.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_if.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_props.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_bind.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_top_tb_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_veer_sram_export.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_top_tb_services.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_if.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_props.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_bind.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_arb.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/wdt.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_dma_ctrl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pic_ctrl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_veer.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dbg/el2_dbg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_decode_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_gpr_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_ib_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_tlu_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_trigger.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/dmi_jtag_to_core_sync.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_alu_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_div_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_mul_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_aln_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_bp_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_compress_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_iccm_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_ic_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_ifc_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/ahb_to_axi4.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/axi4_to_ahb.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/el2_lib.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/mem_lib.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/el2_mem_if.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_addrcheck.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_bus_buffer.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_bus_intf.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_clkdomain.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_dccm_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_dccm_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_ecc.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_lsc_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_stbuf.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_trigger.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_bus_inf.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_bus.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_params_pkg.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_ctrl.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_core.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_k_constants.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_w_mem.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_reg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_reg_pkg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_ctrl.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_decipher_block.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_encipher_block.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_inv_sbox.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_key_mem.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_sbox.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_cbc.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_core_cbc.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_reg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_fsm.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_defines_pkg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_core.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_lfsr.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_param_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_ctrl.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_core.v +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg_lfsr.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_defines_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_params_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_top.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_scalar_blinding.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_hmac_drbg_interface.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_arith_unit.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_ram_tdp_file.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_fau.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_montgomerymultiplier.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_first.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_final.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_mult_dsp.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_add_sub_mod_alter.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_adder.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_reg_pkg.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_reg.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3_pkg.sv +${CALIPTRA_ROOT}/src/kmac/rtl/keccak_round.sv +${CALIPTRA_ROOT}/src/kmac/rtl/keccak_2share.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3pad.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_flop_en.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop_en.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_cdc_rand_delay.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop_2sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_lfsr.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi4_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_diff_decode.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sec_anchor_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_slicer.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_count.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sparse_fsm_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_dom_and_2share.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sec_anchor_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_reg_we_check.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_packer_fifo.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_max_tree.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_arb.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_intr_hw.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_onehot_check.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi8_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_fifo_sync_cnt.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_lc_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_receiver.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_sender.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_fifo_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_arbiter_ppc.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sum_tree.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_ext.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_edge_detector.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_reg_top.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_bucket_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_cntr_reg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_enable_delay.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_markov_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_watermark_reg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_main_sm.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_repcnts_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_adaptp_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_core.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_repcnt_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_ack_sm.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src.sv +${CALIPTRA_ROOT}/src/edn/rtl/edn_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_reg_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_masked.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_core.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm_n.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm_p.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_lut.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_mix_columns.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_dom.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sub_bytes.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_masked_noreuse.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sel_buf_chk.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_shift_rows.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_mix_single_column.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_prng_masking.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_key_expand.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_core.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_main_sm.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_upd.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_cmd.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_reg_top.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_gen.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_block_encrypt.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_state_db.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_cmd_stage.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_byte_merge.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_byte_select.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_command_queue.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_core.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_data_fifos.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_fsm.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_reg_top.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_shift_register.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_tx.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_top.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_rx.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_core.sv +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_top.sv \ No newline at end of file diff --git a/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_itrng.vf b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_itrng.vf new file mode 100644 index 000000000..219eb6217 --- /dev/null +++ b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_itrng.vf @@ -0,0 +1,452 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg ++incdir+${CALIPTRA_ROOT}/src/doe/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/asserts ++incdir+${CALIPTRA_ROOT}/src/datavault/rtl ++incdir+${CALIPTRA_ROOT}/src/entropy_src/rtl ++incdir+${CALIPTRA_ROOT}/src/caliptra_prim/rtl ++incdir+${CALIPTRA_ROOT}/src/lc_ctrl/rtl ++incdir+${CALIPTRA_ROOT}/src/entropy_src/tb ++incdir+${CALIPTRA_ROOT}/src/csrng/rtl ++incdir+${CALIPTRA_ROOT}/src/spi_host/rtl ++incdir+${CALIPTRA_ROOT}/src/uart/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512/coverage ++incdir+${CALIPTRA_ROOT}/src/sha256/coverage ++incdir+${CALIPTRA_ROOT}/src/hmac/coverage ++incdir+${CALIPTRA_ROOT}/src/ecc/coverage ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/coverage ++incdir+${CALIPTRA_ROOT}/src/pcrvault/coverage ++incdir+${CALIPTRA_ROOT}/src/keyvault/coverage ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl ++incdir+${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl ++incdir+${CALIPTRA_ROOT}/src/sha256/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512_masked/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac_drbg/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/rtl ++incdir+${CALIPTRA_ROOT}/src/kmac/rtl ++incdir+${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl ++incdir+${CALIPTRA_ROOT}/src/edn/rtl ++incdir+${CALIPTRA_ROOT}/src/aes/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/include/el2_def.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/common_defines.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/caliptra_top_env_pkg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_defines_pkg.sv +${CALIPTRA_ROOT}/src/integration/asserts/caliptra_top_sva.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_defines_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_main_sm_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_ack_sm_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_reg_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_cipher_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_pkg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sparse_fsm_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_state_pkg.sv +${CALIPTRA_ROOT}/src/lc_ctrl/rtl/lc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/entropy_src/tb/physical_rng.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_reg_pkg.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_pkg.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_reg_pkg.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_cmd_pkg.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/hmac/coverage/hmac_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_if.sv +${CALIPTRA_ROOT}/src/ecc/coverage/ecc_top_cov_bind.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_bind.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_if.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_props.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_bind.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_if.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_props.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_bind.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_top_tb_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_veer_sram_export.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../tb/caliptra_top_tb_services.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_if.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_props.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/../coverage/caliptra_top_cov_bind.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_arb.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/wdt.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_dma_ctrl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pic_ctrl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_veer.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dbg/el2_dbg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_decode_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_gpr_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_ib_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_tlu_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dec/el2_dec_trigger.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/dmi_jtag_to_core_sync.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_alu_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_div_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu_mul_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/exu/el2_exu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_aln_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_bp_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_compress_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_iccm_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_ic_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_ifc_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/ahb_to_axi4.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/axi4_to_ahb.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/el2_lib.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/mem_lib.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/el2_mem_if.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_addrcheck.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_bus_buffer.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_bus_intf.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_clkdomain.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_dccm_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_dccm_mem.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_ecc.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_lsc_ctl.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_stbuf.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lsu/el2_lsu_trigger.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_bus_inf.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_bus.sv +${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_params_pkg.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_ctrl.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256.sv +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_core.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_k_constants.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_w_mem.v +${CALIPTRA_ROOT}/src/sha256/rtl/sha256_reg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_reg_pkg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_ctrl.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_decipher_block.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_encipher_block.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_inv_sbox.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_key_mem.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_sbox.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_cbc.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_core_cbc.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_reg.sv +${CALIPTRA_ROOT}/src/doe/rtl/doe_fsm.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_defines_pkg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_core.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_lfsr.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_param_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_ctrl.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_core.v +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg_lfsr.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_defines_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_params_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_top.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_scalar_blinding.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_hmac_drbg_interface.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_arith_unit.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_ram_tdp_file.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_fau.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_montgomerymultiplier.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_first.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_final.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_mult_dsp.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_add_sub_mod_alter.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_adder.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_reg_pkg.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv_reg.sv +${CALIPTRA_ROOT}/src/datavault/rtl/dv.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3_pkg.sv +${CALIPTRA_ROOT}/src/kmac/rtl/keccak_round.sv +${CALIPTRA_ROOT}/src/kmac/rtl/keccak_2share.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3pad.sv +${CALIPTRA_ROOT}/src/kmac/rtl/sha3.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_flop_en.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim_generic/rtl/caliptra_prim_generic_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop_en.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_cdc_rand_delay.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop_2sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_lfsr.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi4_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_diff_decode.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sec_anchor_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_slicer.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_count.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sparse_fsm_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_dom_and_2share.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sec_anchor_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_reg_we_check.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_packer_fifo.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_max_tree.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_arb.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_intr_hw.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_onehot_check.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_mubi8_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_fifo_sync_cnt.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_buf.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_lc_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_receiver.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_flop.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_sender.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_fifo_sync.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_arbiter_ppc.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sum_tree.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_ext.sv +${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_edge_detector.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_reg_top.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_bucket_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_cntr_reg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_enable_delay.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_markov_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_watermark_reg.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_main_sm.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_repcnts_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_adaptp_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_core.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_repcnt_ht.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src_ack_sm.sv +${CALIPTRA_ROOT}/src/entropy_src/rtl/entropy_src.sv +${CALIPTRA_ROOT}/src/edn/rtl/edn_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_reg_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_pkg.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_masked.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_core.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm_n.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm_p.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_lut.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_mix_columns.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_dom.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sub_bytes.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sbox_canright_masked_noreuse.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_sel_buf_chk.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control_fsm.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_shift_rows.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_mix_single_column.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_cipher_control.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_prng_masking.sv +${CALIPTRA_ROOT}/src/aes/rtl/aes_key_expand.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_core.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_main_sm.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_upd.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_cmd.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_reg_top.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_ctr_drbg_gen.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_block_encrypt.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_state_db.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng_cmd_stage.sv +${CALIPTRA_ROOT}/src/csrng/rtl/csrng.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_byte_merge.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_byte_select.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_command_queue.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_core.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_data_fifos.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_fsm.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_reg_top.sv +${CALIPTRA_ROOT}/src/spi_host/rtl/spi_host_shift_register.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_tx.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_top.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_rx.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart.sv +${CALIPTRA_ROOT}/src/uart/rtl/uart_core.sv +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_top.sv \ No newline at end of file diff --git a/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_vip.vf b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_vip.vf new file mode 100644 index 000000000..28e7f44d0 --- /dev/null +++ b/src/integration/uvmf_caliptra_top/config/uvmf_caliptra_top_vip.vf @@ -0,0 +1,168 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers ++incdir+${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/include/el2_def.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/common_defines.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +${CALIPTRA_ROOT}/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/caliptra_top_env_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_arb.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/wdt.sv \ No newline at end of file diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv index 3084672f4..ed10cc6da 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv @@ -372,6 +372,7 @@ import uvmf_base_pkg_hdl::*; .int_flag(int_flag) ); + caliptra_top_sva sva(); // pragma uvmf custom dut_instantiation end initial begin // tbx vif_binding_block diff --git a/src/keyvault/coverage/keyvault_cov_bind.sv b/src/keyvault/coverage/keyvault_cov_bind.sv index 7e2311508..0a6af3188 100644 --- a/src/keyvault/coverage/keyvault_cov_bind.sv +++ b/src/keyvault/coverage/keyvault_cov_bind.sv @@ -14,8 +14,8 @@ module keyvault_cov_bind; - //`ifdef FCOV - bind dut keyvault_cov_if i_keyvault_cov_if(.*); - bind dut keyvault_cov_props i_keyvault_cov_props(.*); - //`endif + `ifdef FCOV + bind kv keyvault_cov_if i_keyvault_cov_if(.*); + bind kv keyvault_cov_props i_keyvault_cov_props(.*); + `endif endmodule diff --git a/src/keyvault/coverage/keyvault_cov_if.sv b/src/keyvault/coverage/keyvault_cov_if.sv index f896c3d02..40f3c3548 100644 --- a/src/keyvault/coverage/keyvault_cov_if.sv +++ b/src/keyvault/coverage/keyvault_cov_if.sv @@ -25,7 +25,8 @@ interface keyvault_cov_if input logic rst_b, input logic core_only_rst_b, input logic cptra_pwrgood, - input logic debugUnlock_or_scan_mode_switch + input logic debugUnlock_or_scan_mode_switch, + input logic cptra_in_debug_scan_mode ); //Intermediate wires @@ -41,30 +42,30 @@ interface keyvault_cov_if //Assign clear and locks of each KEY_CTRL reg to corresponding bit in the intermediate bus generate for(genvar i = 0; i < KV_NUM_KEYS; i++) begin - assign key_ctrl_lock_wr[i] = dut.kv_reg_hwif_out.KEY_CTRL[i].lock_wr; - assign key_ctrl_lock_use[i] = dut.kv_reg_hwif_out.KEY_CTRL[i].lock_use; - assign key_ctrl_clear[i] = dut.kv_reg_hwif_out.KEY_CTRL[i].clear; + assign key_ctrl_lock_wr[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr; + assign key_ctrl_lock_use[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use; + assign key_ctrl_clear[i] = kv.kv_reg_hwif_out.KEY_CTRL[i].clear; end endgenerate //CLEAR_SECRETS - assign clear_secrets_wr = dut.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values; - assign clear_secrets_sel = dut.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value; + assign clear_secrets_wr = kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values; + assign clear_secrets_sel = kv.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value; //Crypto interface write_en generate for(genvar client = 0; client < KV_NUM_WRITE; client++) begin - assign kv_write_en[client] = dut.kv_write[client].write_en; + assign kv_write_en[client] = kv.kv_write[client].write_en; end endgenerate //AHB signals - assign ahb_write = dut.kv_ahb_slv1.dv & dut.kv_ahb_slv1.write; - assign ahb_read = dut.kv_ahb_slv1.dv & ~dut.kv_ahb_slv1.write; + assign ahb_write = kv.kv_ahb_slv1.dv & kv.kv_ahb_slv1.write; + assign ahb_read = kv.kv_ahb_slv1.dv & ~kv.kv_ahb_slv1.write; covergroup keyvault_top_cov_grp @(posedge clk); option.per_instance = 1; - debug: coverpoint debugUnlock_or_scan_mode_switch; + debug: coverpoint cptra_in_debug_scan_mode; //debugUnlock_or_scan_mode_switch; //Note: Bit transitions and values for lock_wr, lock_use and clear are covered //in UVM reg coverage. This coverpoint bins the 32-bit lock/clear bus so that @@ -101,21 +102,22 @@ interface keyvault_cov_if debugXclear: cross debug, clear; debugXlock_wrXlock_useXclear: cross debug, lock_wr, lock_use, clear; debugXclear_secrets: cross debug, cp_clear_secrets_wr, cp_clear_secrets_sel; + debugXkv_write: cross debug, kv_write_en; //Cover warm reset assertion while regs are locked/cleared - lock_wrXwarm_rst: cross lock_wr, rst_b; - lock_useXwarm_rst: cross lock_use, rst_b; - clearXwarm_rst: cross clear, rst_b; + // lock_wrXwarm_rst: cross lock_wr, rst_b; + // lock_useXwarm_rst: cross lock_use, rst_b; + // clearXwarm_rst: cross clear, rst_b; //Cover cold reset while regs are locked/cleared - lock_wrXcold_rst: cross lock_wr, cptra_pwrgood; - lock_useXcold_rst: cross lock_use, cptra_pwrgood; - clearXcold_rst: cross clear, cptra_pwrgood; + // lock_wrXcold_rst: cross lock_wr, cptra_pwrgood; + // lock_useXcold_rst: cross lock_use, cptra_pwrgood; + // clearXcold_rst: cross clear, cptra_pwrgood; //Cover core reset while regs are locked/cleared - lock_wrXcore_rst: cross lock_wr, core_only_rst_b; - lock_useXcore_rst: cross lock_use, core_only_rst_b; - clearXcore_rst: cross clear, core_only_rst_b; + // lock_wrXcore_rst: cross lock_wr, core_only_rst_b; + // lock_useXcore_rst: cross lock_use, core_only_rst_b; + // clearXcore_rst: cross clear, core_only_rst_b; //Cover simultaneous locks/clear settings lock_wrXlock_useXclearXclear_secrets: cross lock_wr, lock_use, clear, cp_clear_secrets_wr, cp_clear_secrets_sel; @@ -129,8 +131,10 @@ interface keyvault_cov_if clear_secretsXkv_write: cross kv_write_en, cp_clear_secrets_wr, cp_clear_secrets_sel; //Cover ahb write/read during crypto write and debug mode unlocked - ahbXkv_write: cross cp_ahb_write, cp_ahb_read, kv_write_en; - ahbXdebug: cross cp_ahb_write, cp_ahb_read, debug; //TODO: maybe not a real use case - revisit + ahb_writeXkv_write: cross cp_ahb_write, kv_write_en; + ahb_writeXdebug: cross cp_ahb_write, debug; + ahb_readXkv_write: cross cp_ahb_read, kv_write_en; + ahb_readXdebug: cross cp_ahb_read, debug; endgroup diff --git a/src/keyvault/coverage/keyvault_cov_props.sv b/src/keyvault/coverage/keyvault_cov_props.sv index f1ea9b9b7..91ed7d334 100644 --- a/src/keyvault/coverage/keyvault_cov_props.sv +++ b/src/keyvault/coverage/keyvault_cov_props.sv @@ -25,29 +25,96 @@ module keyvault_cov_props //clear_secrets followed by warm reset in the next clk //Expectation: Keys cleared before warm reset property cover_prop_clear_secr_warm_rst; - @(posedge dut.clk) - (dut.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !dut.rst_b); + @(posedge kv.clk) + (kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.rst_b); endproperty covprop_clear_secr_warmrst: cover property(cover_prop_clear_secr_warm_rst); generate for(genvar i = 0; i < KV_NUM_KEYS; i++) begin + //------------------------------------------------------------------------------ //lock write => clear secrets => warm reset in next clk //Expectation: Keys will be flushed since reset is not seen until next clk, locks are reset + //------------------------------------------------------------------------------ property cover_prop_locks_clear_secr_warm_rst; - @(posedge dut.clk) - (dut.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && dut.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !dut.rst_b); + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.rst_b); endproperty covprop_lock_clear_secr_warmrst: cover property(cover_prop_locks_clear_secr_warm_rst); + //------------------------------------------------------------------------------ //lock write => clear secrets => cold reset in next clk //Expectation: Keys will be flushed since reset is not seen until next clk, locks and keys are reset once cold reset happens + //------------------------------------------------------------------------------ property cover_prop_locks_clear_secr_cold_rst; - @(posedge dut.clk) - (dut.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && dut.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !dut.cptra_pwrgood); + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr && kv.kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values |-> ##[1:$] !kv.cptra_pwrgood); endproperty covprop_lock_clear_secr_coldrst: cover property(cover_prop_locks_clear_secr_cold_rst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing warm reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_warmrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.rst_b); + endproperty + covprop_lock_wr_warmrst: cover property(cover_prop_lock_wr_warmrst); + + property cover_prop_lock_use_warmrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.rst_b); + endproperty + covprop_lock_use_warmrst: cover property(cover_prop_lock_use_warmrst); + + property cover_prop_clear_warmrst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.rst_b); + endproperty + covprop_clear_warmrst: cover property(cover_prop_clear_warmrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing cold reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_coldrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_lock_wr_coldrst: cover property(cover_prop_lock_wr_coldrst); + + property cover_prop_lock_use_coldrst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_lock_use_coldrst: cover property(cover_prop_lock_use_coldrst); + + property cover_prop_clear_coldrst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.cptra_pwrgood); + endproperty + covprop_clear_coldrst: cover property(cover_prop_clear_coldrst); + + //------------------------------------------------------------------------------ + //Check that locks/clear were set before issuing core reset + //------------------------------------------------------------------------------ + property cover_prop_lock_wr_corerst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_wr) |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_lock_wr_corerst: cover property(cover_prop_lock_wr_corerst); + + property cover_prop_lock_use_corerst; + @(posedge kv.clk) + ($rose(kv.kv_reg_hwif_out.KEY_CTRL[i].lock_use) |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_lock_use_corerst: cover property(cover_prop_lock_use_corerst); + + property cover_prop_clear_corerst; + @(posedge kv.clk) + (kv.kv_reg_hwif_out.KEY_CTRL[i].clear |-> ##[0:$] !kv.core_only_rst_b); + endproperty + covprop_clear_corerst: cover property(cover_prop_clear_corerst); end endgenerate diff --git a/src/keyvault/uvmf_kv/config/uvmf_kv.vf b/src/keyvault/uvmf_kv/config/uvmf_kv.vf new file mode 100644 index 000000000..5d4fe2ce3 --- /dev/null +++ b/src/keyvault/uvmf_kv/config/uvmf_kv.vf @@ -0,0 +1,127 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/coverage ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests ++incdir+${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_if.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_props.sv +${CALIPTRA_ROOT}/src/keyvault/coverage/keyvault_cov_bind.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_adapter_functions_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg_hdl.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_driver_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_if.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_monitor_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/kv_read_pkg_hdl.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/kv_read_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_driver_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_if.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_monitor_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/kv_write_pkg_hdl.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/kv_write_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_driver_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_if.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_monitor_bfm.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/kv_env_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/parameters/kv_parameters_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/kv_sequences_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests/kv_tests_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_debug_test_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_debug_test_sequence.svh index 15d6b3fbf..307257780 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_debug_test_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_debug_test_sequence.svh @@ -65,6 +65,18 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; typedef kv_wr_rd_debug_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_wr_rd_debug_sequence_t; rand kv_wr_rd_debug_sequence_t kv_wr_rd_debug_seq; + typedef kv_env_debug_on_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_env_debug_on_sequence_t; + rand kv_env_debug_on_sequence_t kv_env_debug_on_seq; + + typedef kv_env_debug_off_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_env_debug_off_sequence_t; + rand kv_env_debug_off_sequence_t kv_env_debug_off_seq; + + typedef kv_env_scan_on_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_env_scan_on_sequence_t; + rand kv_env_scan_on_sequence_t kv_env_scan_on_seq; + + typedef kv_env_scan_off_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_env_scan_off_sequence_t; + rand kv_env_scan_off_sequence_t kv_env_scan_off_seq; + typedef kv_wr_rd_debug_lock_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_wr_rd_debug_lock_sequence_t; rand kv_wr_rd_debug_lock_sequence_t kv_wr_rd_debug_lock_seq; @@ -80,6 +92,9 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; typedef kv_wr_rd_debug_core_rst_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_wr_rd_debug_core_rst_sequence_t; rand kv_wr_rd_debug_core_rst_sequence_t kv_wr_rd_debug_core_rst_seq; + typedef kv_ahb_sequence #(.CONFIG_T(kv_env_configuration_t)) kv_ahb_sequence_t; + rand kv_ahb_sequence_t kv_ahb_seq; + //Responder sequences: typedef kv_read_responder_sequence kv_hmac_key_read_agent_responder_seq_t; kv_hmac_key_read_agent_responder_seq_t kv_hmac_key_read_agent_responder_seq; @@ -90,6 +105,7 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; virtual task body(); + kv_rst_poweron_seq = kv_rst_poweron_sequence_t::type_id::create("kv_rst_poweron_seq"); kv_wr_rd_seq = kv_wr_rd_sequence_t::type_id::create("kv_wr_rd_seq"); kv_wr_rd_rst_seq = kv_wr_rd_rst_sequence_t::type_id::create("kv_wr_rd_rst_seq"); kv_wr_rd_cold_rst_seq = kv_wr_rd_cold_rst_sequence_t::type_id::create("kv_wr_rd_cold_rst_seq"); @@ -99,12 +115,19 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; kv_wr_rd_lock_cold_rst_seq = kv_wr_rd_lock_cold_rst_sequence_t::type_id::create("kv_wr_rd_lock_cold_rst_seq"); kv_wr_rd_lock_core_rst_seq = kv_wr_rd_lock_core_rst_sequence_t::type_id::create("kv_wr_rd_lock_core_rst_seq"); kv_wr_rd_debug_seq = kv_wr_rd_debug_sequence_t::type_id::create("kv_wr_rd_debug_seq"); + kv_env_debug_on_seq = kv_env_debug_on_sequence_t::type_id::create("kv_env_debug_on_seq"); + kv_env_debug_off_seq = kv_env_debug_off_sequence_t::type_id::create("kv_env_debug_off_seq"); + kv_env_scan_on_seq = kv_env_scan_on_sequence_t::type_id::create("kv_env_scan_on_seq"); + kv_env_scan_off_seq = kv_env_scan_off_sequence_t::type_id::create("kv_env_scan_off_seq"); kv_wr_rd_debug_lock_seq = kv_wr_rd_debug_lock_sequence_t::type_id::create("kv_wr_rd_debug_lock_seq"); kv_wr_rd_debug_lock_clear_rst_seq = kv_wr_rd_debug_lock_clear_rst_sequence_t::type_id::create("kv_wr_rd_debug_lock_clear_rst_seq"); kv_wr_rd_debug_warm_rst_seq = kv_wr_rd_debug_warm_rst_sequence_t::type_id::create("kv_wr_rd_debug_warm_rst_seq"); kv_wr_rd_debug_cold_rst_seq = kv_wr_rd_debug_cold_rst_sequence_t::type_id::create("kv_wr_rd_debug_cold_rst_seq"); kv_wr_rd_debug_core_rst_seq = kv_wr_rd_debug_core_rst_sequence_t::type_id::create("kv_wr_rd_debug_core_rst_seq"); + kv_ahb_seq = kv_ahb_sequence_t::type_id::create("kv_ahb_seq"); + if(!kv_rst_poweron_seq.randomize()) + `uvm_fatal("KV POWERON SEQ", "Failed to randomize KV RST poweron seq"); if(!kv_wr_rd_seq.randomize()) `uvm_fatal("KV WR RD SEQ", "kv_rand_debug_test_sequence::body() - kv_wr_rd_seq randomization failed"); if(!kv_key_wr_rd_basic_seq.randomize()) @@ -115,11 +138,38 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; `uvm_fatal("KV WR RD COLD RST SEQ", "kv_rand_debug_test_sequence::body() - kv_wr_rd_cold_rst_seq randomization failed"); if(!kv_wr_rd_lock_seq.randomize()) `uvm_fatal("KV_WR_RD_LOCK_SEQ", "kv_rand_debug_test_sequence::body() - kv_wr_rd_lock_seq randomization failed"); + if(!kv_ahb_seq.randomize()) + `uvm_fatal("KV_AHB_SEQ", "kv_ahb_sequence::body() - kv_ahb_seq randomization failed"); + if(!kv_env_debug_on_seq.randomize()) + `uvm_fatal("KV_ENV_DEBUG_ON SEQ", "kv_rand_debug_test_sequence::body() - kv_env_debug_on_seq randomization failed"); + if(!kv_env_debug_off_seq.randomize()) + `uvm_fatal("KV_ENV_DEBUG_OFF SEQ", "kv_rand_debug_test_sequence::body() - kv_env_debug_off_seq randomization failed"); + if(!kv_env_scan_on_seq.randomize()) + `uvm_fatal("KV_ENV_SCAN_ON SEQ", "kv_rand_debug_test_sequence::body() - kv_env_scan_on_seq randomization failed"); + if(!kv_env_scan_off_seq.randomize()) + `uvm_fatal("KV_ENV_SCAN_OFF SEQ", "kv_rand_debug_test_sequence::body() - kv_env_scan_off_seq randomization failed"); reg_model.reset(); + `uvm_info("TOP", "AHB stop sequences", UVM_MEDIUM) + reg_model.kv_AHB_map.get_sequencer().stop_sequences(); + `uvm_info("TOP", "HMAC key read stop sequences", UVM_MEDIUM) + reg_model.kv_hmac_key_read_map.get_sequencer().stop_sequences(); + `uvm_info("TOP", "Poweron Sequence", UVM_MEDIUM) + kv_rst_poweron_seq.start(top_configuration.kv_rst_agent_config.sequencer); + + + `uvm_info("TOP", "DEBUG on sequence", UVM_MEDIUM) + kv_env_debug_on_seq.start(top_configuration.vsqr); + `uvm_info("TOP", "DEBUG OFF sequence", UVM_MEDIUM) + kv_env_debug_off_seq.start(top_configuration.vsqr); + `uvm_info("TOP", "AHB sequence", UVM_MEDIUM) + kv_ahb_seq.start(top_configuration.vsqr); + + `uvm_info("TOP", "DEBUG + WR/RD sequence",UVM_MEDIUM); + kv_wr_rd_debug_seq.start(top_configuration.vsqr); //has internal scan mode controls + `uvm_info("TOP", "SCAN on sequence", UVM_MEDIUM) + kv_env_scan_on_seq.start(top_configuration.vsqr); - `uvm_info("TOP", "DEBUG sequence",UVM_MEDIUM); - kv_wr_rd_debug_seq.start(top_configuration.vsqr); `uvm_info("TOP", "DEBUG lock sequence",UVM_MEDIUM); kv_wr_rd_debug_lock_seq.start(top_configuration.vsqr); `uvm_info("TOP", "DEBUG warm rst sequence",UVM_MEDIUM); @@ -131,6 +181,8 @@ class kv_rand_debug_test_sequence extends kv_bench_sequence_base; `uvm_info("TOP", "DEBUG lock clear rst sequence",UVM_MEDIUM); kv_wr_rd_debug_lock_clear_rst_seq.start(top_configuration.vsqr); + `uvm_info("TOP", "SCAN OFF sequence", UVM_MEDIUM) + kv_env_scan_off_seq.start(top_configuration.vsqr); if(1) $display("** TESTCASE PASSED"); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_wr_rd_test_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_wr_rd_test_sequence.svh index 897bce4e1..a95571f87 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_wr_rd_test_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/sequences/src/kv_rand_wr_rd_test_sequence.svh @@ -44,6 +44,9 @@ class kv_rand_wr_rd_test_sequence extends kv_bench_sequence_base; typedef kv_key_wr_rd_basic_sequence #(.CONFIG_T(kv_env_configuration_t))kv_key_wr_rd_basic_sequence_t; rand kv_key_wr_rd_basic_sequence_t kv_key_wr_rd_basic_seq; + // typedef kv_key_wr_rd_single_sequence #(.CONFIG_T(kv_env_configuration_t))kv_key_wr_rd_single_sequence_t; + // rand kv_key_wr_rd_single_sequence_t kv_key_wr_rd_single_seq; + typedef kv_wr_rd_rst_sequence #(.CONFIG_T(kv_env_configuration_t))kv_wr_rd_rst_sequence_t; rand kv_wr_rd_rst_sequence_t kv_wr_rd_rst_seq; diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests/src/kv_rand_debug_test.yml b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests/src/kv_rand_debug_test.yml index 29f7aaa67..3a01eff3f 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests/src/kv_rand_debug_test.yml +++ b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/tests/src/kv_rand_debug_test.yml @@ -1,6 +1,6 @@ --- # Random seed desired... -seed: ${PLAYBOOK_RANDOM_SEED} +seed: ${PLAYBOOK_RANDOM_SEED} plusargs: - '+UVM_TESTNAME=kv_rand_debug_test' testname: kv_rand_debug_test diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/kv_env_pkg.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/kv_env_pkg.sv index afa6d0c14..0d3e10c8a 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/kv_env_pkg.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/kv_env_pkg.sv @@ -107,6 +107,7 @@ package kv_env_pkg; `include "src/kv_scoreboard.svh" `include "src/kv_environment.svh" `include "src/kv_env_sequence_base.svh" + `include "src/kv_ahb_sequence.svh" `include "src/kv_wr_rd_sequence.svh" `include "src/kv_wr_rd_rst_sequence.svh" `include "src/kv_wr_rd_cold_rst_sequence.svh" @@ -116,12 +117,15 @@ package kv_env_pkg; `include "src/kv_wr_rd_lock_cold_rst_sequence.svh" `include "src/kv_wr_rd_lock_core_rst_sequence.svh" `include "src/kv_wr_rd_debug_sequence.svh" + `include "src/kv_env_debug_on_sequence.svh" + `include "src/kv_env_debug_off_sequence.svh" + `include "src/kv_env_scan_on_sequence.svh" + `include "src/kv_env_scan_off_sequence.svh" `include "src/kv_wr_rd_debug_lock_sequence.svh" `include "src/kv_wr_rd_debug_lock_clear_rst_sequence.svh" `include "src/kv_wr_rd_debug_warm_rst_sequence.svh" `include "src/kv_wr_rd_debug_cold_rst_sequence.svh" `include "src/kv_wr_rd_debug_core_rst_sequence.svh" - `include "src/kv_ahb_sequence.svh" // pragma uvmf custom package_item_additional begin // UVMF_CHANGE_ME : When adding new environment level sequences to the src directory diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv index 0132574a6..79c3706ef 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv @@ -110,6 +110,11 @@ package kv_reg_model_top_pkg; endclass : kv_reg_ext + // //Callbacks + // `include "kv_reg_delay_job.svh" + // `include "kv_reg_cbs_kv_reg_KEY_ENTRY_data.svh" + + //-------------------------------------------------------------------- // Class: kv_example_reg0 // @@ -316,6 +321,11 @@ package kv_reg_model_top_pkg; uvm_reg_map kv_ecc_privkey_read_map; uvm_reg_map kv_ecc_seed_read_map; + int ii, jj; + + // //Callbacks + // kv_reg_cbs_kv_reg_KEY_ENTRY_data KEY_ENTRY_data_cb; + // uvm_queue #(kv_reg_delay_job) delay_jobs; //TODO add coverage for the other maps // kv_ahb_map_coverage ahb_map_cg; @@ -325,6 +335,16 @@ package kv_reg_model_top_pkg; super.new(name, build_coverage(UVM_CVR_ALL)); endfunction + // Function: reset + // + // function void reset(string kind = "HARD"); + // super.reset(kind); + // if (kind == "HARD") begin + // `uvm_info("KV_REG_MODEL_TOP", {"Reset of kind ", kind, " results in delay_jobs being cleared"}, UVM_HIGH) + // delay_jobs.delete(); + // end + // endfunction + // Function: build // virtual function void build(); @@ -344,6 +364,9 @@ package kv_reg_model_top_pkg; // example_reg1.configure(this, null, "example_reg1"); // example_reg1.build(); + // delay_jobs = new("delay_jobs"); + // uvm_config_db#(uvm_queue#(kv_reg_delay_job))::set(null, "kv_reg_model_top", "delay_jobs", delay_jobs); + val_reg = kv_val_reg::type_id::create("val_reg"); val_reg.configure(this,null,"val_reg"); val_reg.build(); @@ -366,6 +389,11 @@ package kv_reg_model_top_pkg; this.kv_reg_rm.configure(this); this.kv_reg_rm.build(); + // //Add callbacks + // KEY_ENTRY_data_cb = kv_reg_cbs_kv_reg_KEY_ENTRY_data::type_id::create("KEY_ENTRY_data_cb"); + + // foreach (kv_reg_rm.KEY_ENTRY[ii][jj]) uvm_reg_field_cb::add(kv_reg_rm.KEY_ENTRY[ii][jj].data, KEY_ENTRY_data_cb); + this.default_map = create_map("kv_default_map", 0, 4, UVM_LITTLE_ENDIAN); this.default_map.add_submap(this.kv_reg_rm.default_map, 0); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_ahb_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_ahb_sequence.svh index 3867b3b62..5e4a5dcc3 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_ahb_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_ahb_sequence.svh @@ -52,20 +52,15 @@ class kv_ahb_sequence #( // 1 <= iter <= 5; // }; iter = 1; - //Issue reset - if(configuration.kv_rst_agent_config.sequencer != null) - kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); - else - `uvm_error("KV AHB", "kv_rst_agent_config.sequencer is null!") //KEY ENTRY reg writes for (i = 0; i < iter; i++) begin for(entry = 0; entry < KV_NUM_KEYS; entry++) begin - for (offset = 0; offset < KV_NUM_DWORDS; offset++) begin - std::randomize(wr_data); - reg_model.kv_reg_rm.KEY_ENTRY[entry][offset].write(sts, wr_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); - assert(sts == UVM_IS_OK) else `uvm_error("KV AHB", $sformatf("Failed when writing to KEY[%d][%d] entry",entry, offset)) - end + // for (offset = 0; offset < KV_NUM_DWORDS; offset++) begin + std::randomize(wr_data) with {wr_data <= 'h7;}; + reg_model.kv_reg_rm.KEY_CTRL[entry].write(sts, wr_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("KV AHB", $sformatf("Failed when writing to KEY[%d] entry",entry)) + // end end end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_off_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_off_sequence.svh new file mode 100644 index 000000000..c0a475505 --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_off_sequence.svh @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Performs KV writes and reads while randomly issuing debug unlock +// via input pin or CLEAR_SECRETS reg. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class kv_env_debug_off_sequence #( + type CONFIG_T +) extends kv_env_sequence_base #(.CONFIG_T(CONFIG_T)); + + `uvm_object_param_utils(kv_env_debug_off_sequence #(CONFIG_T)); + + typedef kv_rst_poweron_sequence kv_rst_agent_poweron_sequence_t; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq_2; + + typedef kv_rst_debug_sequence kv_rst_agent_debug_sequence_t; + kv_rst_agent_debug_sequence_t kv_rst_agent_debug_seq; + typedef kv_rst_debug_on_sequence kv_rst_agent_debug_on_sequence_t; + kv_rst_agent_debug_on_sequence_t kv_rst_agent_debug_on_seq; + typedef kv_rst_debug_off_sequence kv_rst_agent_debug_off_sequence_t; + kv_rst_agent_debug_off_sequence_t kv_rst_agent_debug_off_seq; + + typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; + kv_write_agent_key_entry_sequence_t hmac_write_seq; + kv_write_agent_key_entry_sequence_t sha512_write_seq; + kv_write_agent_key_entry_sequence_t ecc_write_seq; + kv_write_agent_key_entry_sequence_t doe_write_seq; + + typedef kv_read_key_entry_sequence kv_read_agent_key_entry_sequence_t; + kv_read_agent_key_entry_sequence_t hmac_key_read_seq; + kv_read_agent_key_entry_sequence_t hmac_block_read_seq; + kv_read_agent_key_entry_sequence_t sha512_block_read_seq; + kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; + kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; + + rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; + rand int unsigned wait_cycles_from_seq; + rand bit debug_type; + rand reg [1:0] clear_secrets_data; + + typedef enum {SECURITY_STATE, CLEAR_SECRETS} debug_inputs; + + function new(string name = ""); + super.new(name); + kv_rst_agent_poweron_seq = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV RST poweron seq"); + kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV RST poweron seq"); + + kv_rst_agent_debug_seq = kv_rst_agent_debug_sequence_t::type_id::create("kv_rst_agent_debug_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV RST debug seq"); + kv_rst_agent_debug_on_seq = kv_rst_agent_debug_on_sequence_t::type_id::create("kv_rst_agent_debug_on_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV RST debug on seq"); + kv_rst_agent_debug_off_seq = kv_rst_agent_debug_off_sequence_t::type_id::create("kv_rst_agent_debug_off_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV RST debug off seq"); + + hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV WRITE seq"); + sha512_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("sha512_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV WRITE seq"); + ecc_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("ecc_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV WRITE seq"); + doe_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("doe_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV WRITE seq"); + + hmac_key_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_key_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV READ seq"); + hmac_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV READ seq"); + sha512_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("sha512_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV READ seq"); + ecc_privkey_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_privkey_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV READ seq"); + ecc_seed_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_seed_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_debug_off", "Failed to randomize KV READ seq"); + //kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + endfunction + + virtual task body(); + uvm_status_e sts; + //uvm_reg_data_t rd_data; + int write_entry = 0; + int write_offset = 0; + int read_entry = 0; + int read_offset = 0; + reg [31:0] wr_data, rd_data; + reg_model = configuration.kv_rm; + + + kv_rst_agent_debug_off_seq.start(configuration.kv_rst_agent_config.sequencer); + + endtask +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_on_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_on_sequence.svh new file mode 100644 index 000000000..708b3566f --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_debug_on_sequence.svh @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Performs KV writes and reads while randomly issuing debug unlock +// via input pin or CLEAR_SECRETS reg. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class kv_env_debug_on_sequence #( + type CONFIG_T +) extends kv_env_sequence_base #(.CONFIG_T(CONFIG_T)); + + `uvm_object_param_utils(kv_env_debug_on_sequence #(CONFIG_T)); + + typedef kv_rst_poweron_sequence kv_rst_agent_poweron_sequence_t; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq_2; + + typedef kv_rst_debug_sequence kv_rst_agent_debug_sequence_t; + kv_rst_agent_debug_sequence_t kv_rst_agent_debug_seq; + typedef kv_rst_debug_on_sequence kv_rst_agent_debug_on_sequence_t; + kv_rst_agent_debug_on_sequence_t kv_rst_agent_debug_on_seq; + typedef kv_rst_debug_off_sequence kv_rst_agent_debug_off_sequence_t; + kv_rst_agent_debug_off_sequence_t kv_rst_agent_debug_off_seq; + + typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; + kv_write_agent_key_entry_sequence_t hmac_write_seq; + kv_write_agent_key_entry_sequence_t sha512_write_seq; + kv_write_agent_key_entry_sequence_t ecc_write_seq; + kv_write_agent_key_entry_sequence_t doe_write_seq; + + typedef kv_read_key_entry_sequence kv_read_agent_key_entry_sequence_t; + kv_read_agent_key_entry_sequence_t hmac_key_read_seq; + kv_read_agent_key_entry_sequence_t hmac_block_read_seq; + kv_read_agent_key_entry_sequence_t sha512_block_read_seq; + kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; + kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; + + rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; + rand int unsigned wait_cycles_from_seq; + rand bit debug_type; + rand reg [1:0] clear_secrets_data; + + typedef enum {SECURITY_STATE, CLEAR_SECRETS} debug_inputs; + + function new(string name = ""); + super.new(name); + kv_rst_agent_poweron_seq = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV RST poweron seq"); + kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV RST poweron seq"); + + kv_rst_agent_debug_seq = kv_rst_agent_debug_sequence_t::type_id::create("kv_rst_agent_debug_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV RST debug seq"); + kv_rst_agent_debug_on_seq = kv_rst_agent_debug_on_sequence_t::type_id::create("kv_rst_agent_debug_on_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV RST debug on seq"); + kv_rst_agent_debug_off_seq = kv_rst_agent_debug_off_sequence_t::type_id::create("kv_rst_agent_debug_off_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV RST debug off seq"); + + hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV WRITE seq"); + sha512_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("sha512_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV WRITE seq"); + ecc_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("ecc_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV WRITE seq"); + doe_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("doe_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV WRITE seq"); + + hmac_key_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_key_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV READ seq"); + hmac_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV READ seq"); + sha512_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("sha512_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV READ seq"); + ecc_privkey_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_privkey_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV READ seq"); + ecc_seed_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_seed_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_DEBUG_ON", "Failed to randomize KV READ seq"); + //kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + endfunction + + virtual task body(); + uvm_status_e sts; + //uvm_reg_data_t rd_data; + int write_entry = 0; + int write_offset = 0; + int read_entry = 0; + int read_offset = 0; + reg [31:0] wr_data, rd_data; + reg_model = configuration.kv_rm; + + + kv_rst_agent_debug_on_seq.start(configuration.kv_rst_agent_config.sequencer); + + endtask +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_off_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_off_sequence.svh new file mode 100644 index 000000000..c2530046e --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_off_sequence.svh @@ -0,0 +1,117 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Performs KV writes and reads while randomly issuing debug unlock +// via input pin or CLEAR_SECRETS reg. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class kv_env_scan_off_sequence #( + type CONFIG_T +) extends kv_env_sequence_base #(.CONFIG_T(CONFIG_T)); + + `uvm_object_param_utils(kv_env_scan_off_sequence #(CONFIG_T)); + + typedef kv_rst_poweron_sequence kv_rst_agent_poweron_sequence_t; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq_2; + + typedef kv_rst_debug_sequence kv_rst_agent_debug_sequence_t; + kv_rst_agent_debug_sequence_t kv_rst_agent_debug_seq; + typedef kv_rst_debug_on_sequence kv_rst_agent_debug_on_sequence_t; + kv_rst_agent_debug_on_sequence_t kv_rst_agent_debug_on_seq; + typedef kv_rst_scan_off_sequence kv_rst_agent_scan_off_sequence_t; + kv_rst_agent_scan_off_sequence_t kv_rst_agent_scan_off_seq; + + typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; + kv_write_agent_key_entry_sequence_t hmac_write_seq; + kv_write_agent_key_entry_sequence_t sha512_write_seq; + kv_write_agent_key_entry_sequence_t ecc_write_seq; + kv_write_agent_key_entry_sequence_t doe_write_seq; + + typedef kv_read_key_entry_sequence kv_read_agent_key_entry_sequence_t; + kv_read_agent_key_entry_sequence_t hmac_key_read_seq; + kv_read_agent_key_entry_sequence_t hmac_block_read_seq; + kv_read_agent_key_entry_sequence_t sha512_block_read_seq; + kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; + kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; + + rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; + rand int unsigned wait_cycles_from_seq; + rand bit debug_type; + rand reg [1:0] clear_secrets_data; + + typedef enum {SECURITY_STATE, CLEAR_SECRETS} debug_inputs; + + function new(string name = ""); + super.new(name); + kv_rst_agent_poweron_seq = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV RST poweron seq"); + kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV RST poweron seq"); + + kv_rst_agent_debug_seq = kv_rst_agent_debug_sequence_t::type_id::create("kv_rst_agent_debug_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV RST debug seq"); + kv_rst_agent_debug_on_seq = kv_rst_agent_debug_on_sequence_t::type_id::create("kv_rst_agent_debug_on_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV RST debug on seq"); + kv_rst_agent_scan_off_seq = kv_rst_agent_scan_off_sequence_t::type_id::create("kv_rst_agent_scan_off_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV RST debug off seq"); + + hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV WRITE seq"); + sha512_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("sha512_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV WRITE seq"); + ecc_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("ecc_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV WRITE seq"); + doe_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("doe_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV WRITE seq"); + + hmac_key_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_key_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV READ seq"); + hmac_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV READ seq"); + sha512_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("sha512_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV READ seq"); + ecc_privkey_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_privkey_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV READ seq"); + ecc_seed_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_seed_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_scan_off", "Failed to randomize KV READ seq"); + //kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + endfunction + + virtual task body(); + uvm_status_e sts; + //uvm_reg_data_t rd_data; + int write_entry = 0; + int write_offset = 0; + int read_entry = 0; + int read_offset = 0; + reg [31:0] wr_data, rd_data; + reg_model = configuration.kv_rm; + + + kv_rst_agent_scan_off_seq.start(configuration.kv_rst_agent_config.sequencer); + + endtask +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_on_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_on_sequence.svh new file mode 100644 index 000000000..7c58aac19 --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_scan_on_sequence.svh @@ -0,0 +1,108 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Performs KV writes and reads while randomly issuing debug unlock +// via input pin or CLEAR_SECRETS reg. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class kv_env_scan_on_sequence #( + type CONFIG_T +) extends kv_env_sequence_base #(.CONFIG_T(CONFIG_T)); + + `uvm_object_param_utils(kv_env_scan_on_sequence #(CONFIG_T)); + + typedef kv_rst_poweron_sequence kv_rst_agent_poweron_sequence_t; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq; + kv_rst_agent_poweron_sequence_t kv_rst_agent_poweron_seq_2; + + typedef kv_rst_debug_sequence kv_rst_agent_debug_sequence_t; + kv_rst_agent_debug_sequence_t kv_rst_agent_debug_seq; + typedef kv_rst_scan_on_sequence kv_rst_agent_scan_on_sequence_t; + kv_rst_agent_scan_on_sequence_t kv_rst_agent_scan_on_seq; + typedef kv_rst_debug_off_sequence kv_rst_agent_debug_off_sequence_t; + kv_rst_agent_debug_off_sequence_t kv_rst_agent_debug_off_seq; + + typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; + kv_write_agent_key_entry_sequence_t hmac_write_seq; + kv_write_agent_key_entry_sequence_t sha512_write_seq; + kv_write_agent_key_entry_sequence_t ecc_write_seq; + kv_write_agent_key_entry_sequence_t doe_write_seq; + + typedef kv_read_key_entry_sequence kv_read_agent_key_entry_sequence_t; + kv_read_agent_key_entry_sequence_t hmac_key_read_seq; + kv_read_agent_key_entry_sequence_t hmac_block_read_seq; + kv_read_agent_key_entry_sequence_t sha512_block_read_seq; + kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; + kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; + + rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; + rand int unsigned wait_cycles_from_seq; + rand bit debug_type; + rand reg [1:0] clear_secrets_data; + + typedef enum {SECURITY_STATE, CLEAR_SECRETS} debug_inputs; + + function new(string name = ""); + super.new(name); + kv_rst_agent_poweron_seq = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV RST poweron seq"); + kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV RST poweron seq"); + + kv_rst_agent_debug_seq = kv_rst_agent_debug_sequence_t::type_id::create("kv_rst_agent_debug_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV RST debug seq"); + kv_rst_agent_scan_on_seq = kv_rst_agent_scan_on_sequence_t::type_id::create("kv_rst_agent_scan_on_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV RST debug on seq"); + kv_rst_agent_debug_off_seq = kv_rst_agent_debug_off_sequence_t::type_id::create("kv_rst_agent_debug_off_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV RST debug off seq"); + + hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV WRITE seq"); + sha512_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("sha512_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV WRITE seq"); + ecc_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("ecc_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV WRITE seq"); + doe_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("doe_write_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV WRITE seq"); + + hmac_key_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_key_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV READ seq"); + hmac_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("hmac_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV READ seq"); + sha512_block_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("sha512_block_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV READ seq"); + ecc_privkey_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_privkey_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV READ seq"); + ecc_seed_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_seed_read_seq"); + if(!this.randomize()) `uvm_error("KV_ENV_SCAN_ON", "Failed to randomize KV READ seq"); + //kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); + endfunction + + virtual task body(); + + kv_rst_agent_scan_on_seq.start(configuration.kv_rst_agent_config.sequencer); + + endtask +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh index 66b1b7d84..9af627d82 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_sequence_base.svh @@ -35,10 +35,18 @@ class kv_env_sequence_base #( CONFIG_T ) ); + parameter int HMAC_WRITE = 0; + parameter int SHA512_WRITE = 1; + parameter int ECC_WRITE = 2; + parameter int DOE_WRITE = 3; + // Handle to the environments register model // This handle needs to be set before use. kv_reg_model_top reg_model; + rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; + rand reg [KV_NUM_WRITE-1:0] wr_clients; + // This kv_env_sequence_base contains a handle to a kv_env_configuration object // named configuration. This configuration variable contains a handle to each // sequencer within each agent within this environment and any sub-environments. @@ -65,17 +73,11 @@ class kv_env_sequence_base #( typedef kv_rst_random_sequence kv_rst_agent_random_sequence_t; kv_rst_agent_random_sequence_t kv_rst_agent_rand_seq; - typedef kv_write_random_sequence kv_hmac_write_agent_random_sequence_t; - kv_hmac_write_agent_random_sequence_t kv_hmac_write_agent_rand_seq; - - typedef kv_write_random_sequence kv_sha512_write_agent_random_sequence_t; - kv_sha512_write_agent_random_sequence_t kv_sha512_write_agent_rand_seq; - - typedef kv_write_random_sequence kv_ecc_write_agent_random_sequence_t; - kv_ecc_write_agent_random_sequence_t kv_ecc_write_agent_rand_seq; - - typedef kv_write_random_sequence kv_doe_write_agent_random_sequence_t; - kv_doe_write_agent_random_sequence_t kv_doe_write_agent_rand_seq; + typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; + kv_write_agent_key_entry_sequence_t hmac_write_seq; + kv_write_agent_key_entry_sequence_t sha512_write_seq; + kv_write_agent_key_entry_sequence_t ecc_write_seq; + kv_write_agent_key_entry_sequence_t doe_write_seq; typedef kv_read_random_sequence kv_hmac_key_read_agent_random_sequence_t; kv_hmac_key_read_agent_random_sequence_t kv_hmac_key_read_agent_rand_seq; @@ -101,10 +103,14 @@ class kv_env_sequence_base #( function new(string name = "" ); super.new(name); kv_rst_agent_rand_seq = kv_rst_agent_random_sequence_t::type_id::create("kv_rst_agent_rand_seq"); - kv_hmac_write_agent_rand_seq = kv_hmac_write_agent_random_sequence_t::type_id::create("kv_hmac_write_agent_rand_seq"); - kv_sha512_write_agent_rand_seq = kv_sha512_write_agent_random_sequence_t::type_id::create("kv_sha512_write_agent_rand_seq"); - kv_ecc_write_agent_rand_seq = kv_ecc_write_agent_random_sequence_t::type_id::create("kv_ecc_write_agent_rand_seq"); - kv_doe_write_agent_rand_seq = kv_doe_write_agent_random_sequence_t::type_id::create("kv_doe_write_agent_rand_seq"); + hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV WRITE seq"); + sha512_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("sha512_write_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV WRITE seq"); + ecc_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("ecc_write_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV WRITE seq"); + doe_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("doe_write_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV WRITE seq"); kv_hmac_key_read_agent_rand_seq = kv_hmac_key_read_agent_random_sequence_t::type_id::create("kv_hmac_key_read_agent_rand_seq"); kv_hmac_block_read_agent_rand_seq = kv_hmac_block_read_agent_random_sequence_t::type_id::create("kv_hmac_block_read_agent_rand_seq"); kv_sha512_block_read_agent_rand_seq = kv_sha512_block_read_agent_random_sequence_t::type_id::create("kv_sha512_block_read_agent_rand_seq"); @@ -114,18 +120,89 @@ class kv_env_sequence_base #( endfunction +virtual task gen_rand_entries(); + std::randomize(hmac_write_entry) with { + hmac_write_entry != sha512_write_entry; + hmac_write_entry != ecc_write_entry; + hmac_write_entry != doe_write_entry; + }; + + std::randomize(sha512_write_entry) with { + sha512_write_entry != hmac_write_entry; + sha512_write_entry != ecc_write_entry; + sha512_write_entry != doe_write_entry; + }; + + std::randomize(ecc_write_entry) with { + ecc_write_entry != hmac_write_entry; + ecc_write_entry != sha512_write_entry; + ecc_write_entry != doe_write_entry; + }; + + std::randomize(doe_write_entry) with { + doe_write_entry != hmac_write_entry; + doe_write_entry != sha512_write_entry; + doe_write_entry != ecc_write_entry; + }; + +endtask + +virtual task queue_writes(); + + repeat(20) begin + gen_rand_entries(); + std::randomize(wr_clients); + + fork + begin + if (wr_clients[HMAC_WRITE]) begin + `uvm_info("QUEUE_HMAC_WRITE", $sformatf("hmac write with entry = %h", hmac_write_entry), UVM_HIGH) + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_entry",hmac_write_entry); + hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); + end + end + begin + if (wr_clients[SHA512_WRITE]) begin + `uvm_info("QUEUE_SHA512_WRITE", $sformatf("sha512 write with entry = %h", sha512_write_entry), UVM_HIGH) + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_sha512_write_agent.sequencer.sha512_write_seq", "local_write_entry",sha512_write_entry); + sha512_write_seq.start(configuration.kv_sha512_write_agent_config.sequencer); + end + end + begin + if (wr_clients[DOE_WRITE]) begin + `uvm_info("QUEUE_DOE_WRITE", $sformatf("doe write with entry = %h", doe_write_entry), UVM_HIGH) + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_doe_write_agent.sequencer.doe_write_seq", "local_write_entry",doe_write_entry); + doe_write_seq.start(configuration.kv_doe_write_agent_config.sequencer); + end + end + begin + if (wr_clients[ECC_WRITE]) begin + `uvm_info("QUEUE_ECC_WRITE", $sformatf("ecc write with entry = %h", ecc_write_entry), UVM_HIGH) + uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_ecc_write_agent.sequencer.ecc_write_seq", "local_write_entry",ecc_write_entry); + ecc_write_seq.start(configuration.kv_ecc_write_agent_config.sequencer); + end + end + join + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); + end + endtask + virtual task body(); if ( configuration.kv_rst_agent_config.sequencer != null ) repeat (25) kv_rst_agent_rand_seq.start(configuration.kv_rst_agent_config.sequencer); if ( configuration.kv_hmac_write_agent_config.sequencer != null ) - repeat (25) kv_hmac_write_agent_rand_seq.start(configuration.kv_hmac_write_agent_config.sequencer); + repeat (25) hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); if ( configuration.kv_sha512_write_agent_config.sequencer != null ) - repeat (25) kv_sha512_write_agent_rand_seq.start(configuration.kv_sha512_write_agent_config.sequencer); + repeat (25) sha512_write_seq.start(configuration.kv_sha512_write_agent_config.sequencer); if ( configuration.kv_ecc_write_agent_config.sequencer != null ) - repeat (25) kv_ecc_write_agent_rand_seq.start(configuration.kv_ecc_write_agent_config.sequencer); + repeat (25) ecc_write_seq.start(configuration.kv_ecc_write_agent_config.sequencer); if ( configuration.kv_doe_write_agent_config.sequencer != null ) - repeat (25) kv_doe_write_agent_rand_seq.start(configuration.kv_doe_write_agent_config.sequencer); + repeat (25) doe_write_seq.start(configuration.kv_doe_write_agent_config.sequencer); + if ( configuration.kv_hmac_key_read_agent_config.sequencer != null ) repeat (25) kv_hmac_key_read_agent_rand_seq.start(configuration.kv_hmac_key_read_agent_config.sequencer); if ( configuration.kv_hmac_block_read_agent_config.sequencer != null ) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh index 7b9db72bf..d17b1a2ac 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh @@ -206,8 +206,25 @@ class kv_predictor #( string client; logic [KV_ENTRY_SIZE_W-1:0]last_dword_written[0:KV_NUM_KEYS-1]; + // process running_dly_jobs[$]; + // int unsigned job_end_count[time]; + // bit write_entry_pending = 0; + // bit send_hmac_write_txn = 0; + bit set_val_ctrl_derived = 0; + logic [KV_NUM_KEYS-1:0] val_ctrl_derived_data = 0; + logic [KV_NUM_KEYS-1:0] key_entry_ctrl_we = 0; + + //Set when lock_wr/lock_use is 0 and set by AHB txn. Reset only during reset + logic [KV_NUM_KEYS-1:0] key_ctrl_lock_wr = 0; + logic [KV_NUM_KEYS-1:0] key_ctrl_lock_use = 0; + extern function void populate_expected_kv_read_txn(ref kv_sb_ap_output_transaction_t t_expected, kv_read_transaction t_received, string client); extern function void populate_expected_kv_write_txn(ref kv_sb_ap_output_transaction_write_t t_expected, kv_write_transaction t_received); + extern task poll_and_run_delay_jobs(); + // extern function send_delayed_expected_transactions_hmac_write(kv_write_transaction t); + // extern function send_delayed_expected_transactions_sha512_write(kv_write_transaction t); + // extern function send_delayed_expected_transactions_ecc_write(kv_write_transaction t); + // extern function send_delayed_expected_transactions_doe_write(kv_write_transaction t); // pragma uvmf custom class_item_additional end // FUNCTION: new @@ -272,6 +289,13 @@ class kv_predictor #( // pragma uvmf custom build_phase end endfunction + task run_phase (uvm_phase phase); + fork + poll_and_run_delay_jobs(); + join_none + super.run_phase(phase); + endtask + // FUNCTION: write_kv_rst_agent_ae // Transactions received through kv_rst_agent_ae initiate the execution of this function. // This function performs prediction of DUT output values based on DUT input, configuration and state @@ -300,12 +324,15 @@ class kv_predictor #( for(entry = 0; entry < KV_NUM_KEYS; entry++) begin last_dword_written[entry] = 'h0; //Clear last dword on hard rst end + key_ctrl_lock_wr = 'h0; + key_ctrl_lock_use = 'h0; end else if (t.debug_mode | t.scan_mode) begin //Set val_reg to 1 for use in reg predictor p_kv_rm.val_reg.debug_mode_unlocked.set(1'b1); p_kv_rm.val_reg.cptra_in_debug_scan_mode.set(1'b1); + `uvm_info("PRED", "Clear_secrets reg is set in debug/scan mode. Flushing KV", UVM_MEDIUM) if (clear_secrets_data[p_kv_rm.kv_reg_rm.CLEAR_SECRETS.sel_debug_value.get_lsb_pos()] == 'h1) begin for(entry = 0; entry < KV_NUM_KEYS; entry++) begin //Debug mode should flush all regs inspite of locks @@ -349,6 +376,8 @@ class kv_predictor #( kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); kv_reg_data = kv_reg.get_mirrored_value(); end + key_ctrl_lock_wr = 'h0; + key_ctrl_lock_use = 'h0; end //If debug mode was unlocked, set a val register to let reg predictor know @@ -382,6 +411,8 @@ class kv_predictor #( // Construct one of each output transaction type. kv_sb_ap_output_transaction_write = kv_sb_ap_output_transaction_write_t::type_id::create("kv_sb_ap_output_transaction_write"); populate_expected_kv_write_txn(kv_sb_ap_output_transaction_write, t); + // this.write_entry_pending = 1'b1; + // send_hmac_write_txn = 1'b1; // Code for sending output transaction out through kv_sb_ap // Please note that each broadcasted transaction should be a different object than previously @@ -593,8 +624,9 @@ class kv_predictor #( reg [KV_DATA_W-1:0] data_active; reg [ahb_lite_slave_0_params::AHB_WDATA_WIDTH-1:0] address_aligned; uvm_reg val_ctrl, val_reg, val_ctrl_derived; - uvm_reg_data_t val_ctrl_data, val_reg_data, val_ctrl_derived_data; + uvm_reg_data_t val_ctrl_data, val_reg_data; + this.set_val_ctrl_derived = 'b0; ahb_slave_0_ae_debug = t; `uvm_info("PRED", "Transaction Received through ahb_slave_0_ae", UVM_MEDIUM) `uvm_info("PRED", {" Data: ",t.convert2string()}, UVM_FULL) @@ -605,15 +637,15 @@ class kv_predictor #( //Convert data from AHB to txn address_aligned = ahb_txn.address & ~(KV_DATA_W/8 - 1); data_active = KV_DATA_W'(ahb_txn.data[0] >> (8*(address_aligned % (ahb_lite_slave_0_params::AHB_WDATA_WIDTH/8)))); + + //Read val reg to determine if we're in debug mode + val_reg = p_kv_rm.get_reg_by_name("val_reg"); + val_reg_data = val_reg.get(); if(ahb_txn.RnW == AHB_WRITE) begin //Copy txn and modify required fields later kv_sb_ahb_ap_output_transaction.copy(ahb_txn); - //Read val reg to determine if we're in debug mode - val_reg = p_kv_rm.get_reg_by_name("val_reg"); - val_reg_data = val_reg.get(); - //Only allow clear_secrets during debug mode if ((ahb_txn.address == `KV_REG_CLEAR_SECRETS) ) begin //Update val register with CLEAR_SECRETS wr_debug_values field @@ -621,7 +653,9 @@ class kv_predictor #( if (val_reg_data[p_kv_rm.val_reg.cptra_in_debug_scan_mode.get_lsb_pos()]) begin //[2]) begin //Only allow clear operation if in debug mode - if (data_active[1:0] == 'h1) begin + //if (data_active[1:0] == 'h1) begin + if (data_active [p_kv_rm.kv_reg_rm.CLEAR_SECRETS.wr_debug_values.get_lsb_pos()] && !data_active[p_kv_rm.kv_reg_rm.CLEAR_SECRETS.sel_debug_value.get_lsb_pos()]) begin + `uvm_info("PRED", "Clear_secrets reg is set in debug/scan mode. Flushing KV with DEBUG0 values", UVM_MEDIUM) for(entry = 0; entry < KV_NUM_KEYS; entry++) begin //Read locks before clearing - do not clear if locked kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); @@ -634,7 +668,9 @@ class kv_predictor #( end end end - else if(data_active[1:0] == 'h3) begin + //else if(data_active[1:0] == 'h3) begin + else if (data_active [p_kv_rm.kv_reg_rm.CLEAR_SECRETS.wr_debug_values.get_lsb_pos()] && data_active[p_kv_rm.kv_reg_rm.CLEAR_SECRETS.sel_debug_value.get_lsb_pos()]) begin + `uvm_info("PRED", "Clear_secrets reg is set in debug/scan mode. Flushing KV with DEBUG1 values", UVM_MEDIUM) for(entry = 0; entry < KV_NUM_KEYS; entry++) begin //Read locks before clearing kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); @@ -660,21 +696,43 @@ class kv_predictor #( val_ctrl = p_kv_rm.get_reg_by_name("val_ctrl"); val_ctrl_data = val_ctrl.get(); - if(data_active[2] && !kv_reg_data[0] && !kv_reg_data[1]) begin + //Once set, keep lock_wr set until a reset is issued. AHB txn with lock_wr = 0 should not have any effect on the reg + if (data_active[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].lock_wr.get_lsb_pos()]) begin + key_ctrl_lock_wr[entry] = 'b1; + end + + //Once set, keep lock_use set until a reset is issued. AHB txn with lock_use = 0 should not have any effect on the reg + if (data_active[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].lock_use.get_lsb_pos()]) begin + key_ctrl_lock_use[entry] = 'b1; + end + + // if(data_active[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].clear.get_lsb_pos()] && !kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].lock_wr.get_lsb_pos()] && !kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].lock_use.get_lsb_pos()] && !val_reg_data[p_kv_rm.val_reg.cptra_in_debug_scan_mode.get_lsb_pos()]) begin + if (data_active[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].clear.get_lsb_pos()] && !key_ctrl_lock_wr[entry] && !key_ctrl_lock_use[entry] && !val_reg_data[p_kv_rm.val_reg.cptra_in_debug_scan_mode.get_lsb_pos()]) begin val_ctrl_data[entry] = 'b1; //In design, clear is a single pulse reg. This val_ctrl[*] will be reset in kv_reg_predictor - val_ctrl_derived_data[entry] = 'b1; + // for (int i = 0; i < KV_NUM_KEYS; i++) begin + this.val_ctrl_derived_data[entry] = 'b1; + last_dword_written[entry] = 'h0; //clear last dword of that entry + // this.val_ctrl_derived_data[i] = (i == entry); + // end + // this.set_val_ctrl_derived = 'b1; //p_kv_rm.kv_reg_rm.kv_val_ctrl.predict(val_ctrl_data); - `uvm_info("PRED", "Setting clear field of val_ctrl register", UVM_MEDIUM) p_kv_rm.val_ctrl.set(val_ctrl_data); - `uvm_info("PRED", "Setting clear field of val_ctrl_derived register", UVM_MEDIUM) - p_kv_rm.val_ctrl_derived.set(val_ctrl_derived_data); + //`uvm_info("PRED", "Setting clear field of val_ctrl_derived register", UVM_MEDIUM) + // //configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1); + //p_kv_rm.val_ctrl_derived.set(val_ctrl_derived_data); //Clear the entry that is being accessed for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict('h0); p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].set('h0); end end + //Reset all bits of val_ctrl_derived except current entry irrespective of locks + this.set_val_ctrl_derived = 'b1; + for (int i = 0; i < KV_NUM_KEYS; i++) begin + if (i != entry) + this.val_ctrl_derived_data[i] = 0; + end end end else begin @@ -708,8 +766,8 @@ endclass uvm_reg kv_reg; uvm_reg_data_t kv_reg_data; - uvm_reg val_ctrl; - uvm_reg_data_t val_ctrl_data; + uvm_reg val_ctrl, val_ctrl_derived; + uvm_reg_data_t val_ctrl_data, val_ctrl_derived_data; logic lock_use; logic [KV_NUM_READ-1:0] dest_valid; logic client_dest_valid; @@ -717,12 +775,16 @@ endclass val_ctrl = p_kv_rm.get_reg_by_name("val_ctrl"); val_ctrl_data = val_ctrl.get(); + val_ctrl_derived = p_kv_rm.get_reg_by_name("val_ctrl_derived"); + val_ctrl_derived_data = val_ctrl_derived.get(); + kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",t_received.read_entry)); kv_reg_data = kv_reg.get_mirrored_value(); kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_ENTRY[%0d][%0d]",t_received.read_entry,t_received.read_offset)); - lock_use = kv_reg_data[1]; + lock_use = kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[t_received.read_entry].lock_use.get_lsb_pos()]; dest_valid = kv_reg_data[13:9]; //[16:14] are rsvd + // dest_valid = kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[entry].dest_valid.get_lsb_pos()]; case(client) inside @@ -744,19 +806,21 @@ endclass //kv_predictor takes care of #1. #2 and #3 should be done is custom AHB reg predictor which we don't have //As a workaround, setting a val_ctrl reg when clear happens. Until a write occurs on that entry, this bit will remain set //During every read, we check val_ctrl[entry] bit. If 1, return 0s, resp.err = 1 and last dword = 0 to mimic design - if (lock_use || !client_dest_valid || val_ctrl_data[t_received.read_entry]) begin + if (lock_use || !client_dest_valid || val_ctrl_data[t_received.read_entry] || val_ctrl_derived_data[t_received.read_entry]) begin t_expected.read_data = 'h0; t_expected.error = 'b1; end else begin kv_reg_data = kv_reg.get_mirrored_value(); - t_expected.read_data = kv_reg_data[31:0]; //Data from KEY entry + t_expected.read_data = KV_DATA_W'(kv_reg_data); //kv_reg_data[31:0]; //Data from KEY entry t_expected.error = 'b0; end - if (val_ctrl_data[t_received.read_entry]) begin - last_dword_written[t_received.read_entry] = 'h0; - end + // if (val_ctrl_data[t_received.read_entry]) begin + // if (val_ctrl_derived_data[t_received.read_entry]) begin + // `uvm_info("KNU_DBG","Resetting last_dword because val_ctrl_data is set!", UVM_FULL) + // last_dword_written[t_received.read_entry] = 'h0; + // end t_expected.last = (last_dword_written[t_received.read_entry] == t_received.read_offset); t_expected.read_entry = t_received.read_entry; @@ -764,8 +828,8 @@ endclass endfunction function void kv_predictor::populate_expected_kv_write_txn (ref kv_sb_ap_output_transaction_write_t t_expected, kv_write_transaction t_received); - uvm_reg kv_reg, val_ctrl_derived; - uvm_reg_data_t kv_reg_data, val_ctrl_derived_data; + uvm_reg kv_reg, val_ctrl_derived, val_ctrl; + uvm_reg_data_t kv_reg_data, val_ctrl_derived_data, val_ctrl_data; logic lock_use; logic lock_wr; logic clear; @@ -776,12 +840,17 @@ endclass kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",t_received.write_entry)); kv_reg_data = kv_reg.get_mirrored_value(); - lock_wr = kv_reg_data[0]; - lock_use = kv_reg_data[1]; + // lock_wr = kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[t_received.write_entry].lock_wr.get_lsb_pos()]; + // lock_use = kv_reg_data[p_kv_rm.kv_reg_rm.KEY_CTRL[t_received.write_entry].lock_use.get_lsb_pos()]; + lock_wr = key_ctrl_lock_wr[t_received.write_entry]; + lock_use = key_ctrl_lock_use[t_received.write_entry]; val_ctrl_derived = p_kv_rm.get_reg_by_name("val_ctrl_derived"); val_ctrl_derived_data = val_ctrl_derived.get(); + val_ctrl = p_kv_rm.get_reg_by_name("val_ctrl"); + val_ctrl_data = val_ctrl.get(); + //Copy received txn // t_expected = t_received; t_expected.write_en = t_received.write_en; @@ -796,22 +865,107 @@ endclass t_expected.error = 1'b1; `uvm_info("PRED", "Trying to write to a locked reg", UVM_MEDIUM) end - else if (/*this.write_in_progress[t_received.write_entry] &&*/ val_ctrl_derived_data[t_received.write_entry]) begin - t_expected.error = 1'b1; - `uvm_info("PRED","Attempts to clear a reg while write is in progress results in an error", UVM_MEDIUM) - `uvm_info("PRED", $sformatf("Write entry = %0d, val_ctrl_derived_data = %b", t_received.write_entry, val_ctrl_derived_data), UVM_MEDIUM) - end else begin - t_expected.error = 1'b0; - //Keep track of last dword written - last_dword_written[t_received.write_entry] = t_received.write_offset; + key_entry_ctrl_we[t_received.write_entry] = 1'b1; + if (/*this.write_in_progress[t_received.write_entry] &&*/ val_ctrl_derived_data[t_received.write_entry]) begin + t_expected.error = 1'b1; + `uvm_info("PRED","Attempts to clear a reg while write is in progress results in an err", UVM_MEDIUM) + end + else begin + t_expected.error = 1'b0; + //Keep track of last dword written + last_dword_written[t_received.write_entry] = t_received.write_offset; + end end end else begin t_expected.error = 1'b0; + //Reset all bits of val_ctrl_derived except current entry irrespective of locks + this.set_val_ctrl_derived = 'b1; + for (int i = 0; i < KV_NUM_KEYS; i++) begin + this.val_ctrl_derived_data[i] = 0; + key_entry_ctrl_we[i] = 1'b0; + end + end endfunction + + // function void kv_predictor::send_delayed_expected_transactions_hmac_write(kv_write_transaction t); + // bit send_hmac_write_txn = 0; + + // kv_sb_ap_output_transaction_write = kv_sb_ap_output_transaction_write_t::type_id::create("kv_sb_ap_output_transaction_write"); + + // if (this.write_entry_pending) begin + // `uvm_info("PRED_DLY", "Delay job to update KEY_ENTRY value", UVM_HIGH) + // this.write_entry_pending = 1'b0; + // end + + // //------------------------------------- + // //Send expected txns to SCBD + // //------------------------------------- + // if (send_hmac_write_txn) begin + // populate_expected_kv_write_txn(kv_sb_ap_output_transaction_write, t); + // kv_hmac_write_sb_ap.write(kv_sb_ap_output_transaction_write); + // `uvm_info("PRED_DLY", "Transaction submitted through kv_hmac_write_sb_ap", UVM_MEDIUM) + // send_hmac_write_txn = 1'b0; + // end + + // endfunction + + // task kv_predictor::poll_and_run_delay_jobs(); + // forever begin + // while (p_kv_rm.delay_jobs.size() > 0) begin + // fork + // kv_reg_delay_job job = p_kv_rm.delay_jobs.pop_front(); + // //TODO: add reset check + // int idx[$]; + // time end_time; + // this.running_dly_jobs.push_back(process::self()); // This tracks all the delay_jobs that are pending so they can be clobbered on rst + // `uvm_info("PRED_DLY", $sformatf("Doing delay of %0d cycles before running delay job with signature: %s", job.get_delay_cycles(), job.get_name()), UVM_HIGH) + // end_time = $time + 10*job.get_delay_cycles(); + // job_end_count[end_time] += 1; + // //Delay jobs have 1 cycle inherent delay + // if (job.get_delay_cycles()) configuration.kv_hmac_write_agent_config.wait_for_num_clocks(job.get_delay_cycles()); + // uvm_wait_for_nba_region(); + // idx = this.running_dly_jobs.find_first_index(pr) with (pr == process::self()); + // this.running_dly_jobs.delete(idx.pop_front()); + // job.do_job(); + // job_end_count[end_time] -= 1; + + // if (job_end_count[end_time] == 0) begin + // job_end_count.delete(end_time); + // // send_delayed_expected_transactions_hmac_write(t); + // end + // //end TODO: add reset check + // join_none + // end + // configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1); + // end + // endtask + + task kv_predictor::poll_and_run_delay_jobs(); + forever begin + if (this.set_val_ctrl_derived) begin + // fork + //Delay by 2 clks to match the clear txn reaching predictor by then + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(2); //2 + `uvm_info("PRED", $sformatf("Setting clear field of val_ctrl_derived register from %b to %b",p_kv_rm.val_ctrl_derived.get(), this.val_ctrl_derived_data), UVM_FULL) + p_kv_rm.val_ctrl_derived.set(this.val_ctrl_derived_data); + this.set_val_ctrl_derived = 'b0; + // join_none + end + else begin + for (int i = 0; i < KV_NUM_KEYS; i++) begin + if (!key_entry_ctrl_we[i]) begin + this.val_ctrl_derived_data[i] = 'b0; //reset clear bit if there's no write_en for it + end + this.set_val_ctrl_derived = 'b1; //update in next clk + end + end + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1); + end + endtask // pragma uvmf custom external end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh index de58e86f4..fb5e0fc14 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh @@ -152,7 +152,7 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //This will be used to hold the clear until writes are finished to current entry //----------------------------------------------- for (int i = 0; i < KV_NUM_KEYS; i++) begin - val_ctrl_derived_data[i] /*[entry_offset[4:0]]*/ = (val_ctrl_derived_data[i] & (i == entry_offset[4:0])); //'b0; //Reset clear bit of current entry + val_ctrl_derived_data[i] = (val_ctrl_derived_data[i] & (i == entry_offset[4:0])); //'b0; //Reset clear bit of everything except current entry end val_ctrl_item = new; @@ -182,10 +182,11 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //TODO: Revisit lock and clear condition //TODO: Can write to regs during debug mode. Remove check after updating sequences `uvm_info("KV_REG_PRED", $sformatf("OUTSIDE, lock_wr = %0d, lock_use = %0d, clear_secrets_wren = %0d, val_reg_data = %b", lock_wr, lock_use, clear_secrets_data[0], val_reg_data), UVM_FULL) - if (!lock_wr && !lock_use && !(clear_secrets_data[0] && val_reg_data[2]) && !val_reg_data[0]) begin + if (!lock_wr && !lock_use && !(clear_secrets_data[0] && val_reg_data[2]) /*&& !val_reg_data[0]*/) begin `uvm_info("KV_REG_PRED", "Writing to KEY_ENTRY", UVM_FULL) super.write(tr); + if ((rw.addr >= `KV_REG_KEY_ENTRY_0_0) && (rw.addr <= `KV_REG_KEY_ENTRY_31_11)) begin //Only update KEY_CTRL if it's a KEY_ENTRY write `uvm_info("KV_REG_PRED", "Updating KEY_CTRL", UVM_FULL) //----------------------------------------------- @@ -201,6 +202,7 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //Update CTRL reg kv_reg_ctrl.do_predict(kv_reg_ctrl_item, UVM_PREDICT_DIRECT); + end end else begin `uvm_info("KV_REG_PRED", "Skipping write to KEY_ENTRY", UVM_FULL) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh index 90d0a06a9..7e32d9da8 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_cold_rst_sequence.svh @@ -252,6 +252,16 @@ class kv_wr_rd_cold_rst_sequence #( join active_phase.reset; + configuration.kv_rst_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_key_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_privkey_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_seed_read_agent_config.wait_for_num_clocks(1000); endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh index 48cfbaf03..114d7a2c0 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_clear_rst_sequence.svh @@ -204,7 +204,7 @@ class kv_wr_rd_debug_lock_clear_rst_sequence #( endcase kv_warm_rst_seq.start(configuration.kv_rst_agent_config.sequencer); - fork + // fork // begin // //Write to all entries // for (write_entry = 0; write_entry < KV_NUM_KEYS; write_entry++) begin @@ -215,7 +215,7 @@ class kv_wr_rd_debug_lock_clear_rst_sequence #( // end // end // end - begin + // begin //Read all entries for (read_entry = 0; read_entry < KV_NUM_KEYS; read_entry++) begin for (read_offset = 0; read_offset < KV_NUM_DWORDS; read_offset++) begin @@ -224,7 +224,7 @@ class kv_wr_rd_debug_lock_clear_rst_sequence #( sha512_block_read_seq.start(configuration.kv_sha512_block_read_agent_config.sequencer); end end - end - join + // end + // join endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_sequence.svh index 12ce1eab2..00e97ce95 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_lock_sequence.svh @@ -157,7 +157,7 @@ class kv_wr_rd_debug_lock_sequence #( endcase - fork + // fork // begin // //Write to all entries // for (write_entry = 0; write_entry < KV_NUM_KEYS; write_entry++) begin @@ -168,7 +168,7 @@ class kv_wr_rd_debug_lock_sequence #( // end // end // end - begin + // begin //Read all entries for (read_entry = 0; read_entry < KV_NUM_KEYS; read_entry++) begin for (read_offset = 0; read_offset < KV_NUM_DWORDS; read_offset++) begin @@ -177,7 +177,7 @@ class kv_wr_rd_debug_lock_sequence #( sha512_block_read_seq.start(configuration.kv_sha512_block_read_agent_config.sequencer); end end - end - join + // end + // join endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_sequence.svh index 08233fef5..319fb1c02 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_debug_sequence.svh @@ -39,6 +39,15 @@ class kv_wr_rd_debug_sequence #( typedef kv_rst_debug_sequence kv_rst_agent_debug_sequence_t; kv_rst_agent_debug_sequence_t kv_rst_agent_debug_seq; + typedef kv_rst_debug_on_sequence kv_rst_agent_debug_on_sequence_t; + kv_rst_agent_debug_on_sequence_t kv_rst_agent_debug_on_seq; + typedef kv_rst_debug_off_sequence kv_rst_agent_debug_off_sequence_t; + kv_rst_agent_debug_off_sequence_t kv_rst_agent_debug_off_seq; + + typedef kv_rst_scan_on_sequence kv_rst_agent_scan_on_sequence_t; + kv_rst_agent_scan_on_sequence_t kv_rst_agent_scan_on_seq; + typedef kv_rst_scan_off_sequence kv_rst_agent_scan_off_sequence_t; + kv_rst_agent_scan_off_sequence_t kv_rst_agent_scan_off_seq; typedef kv_write_key_entry_sequence kv_write_agent_key_entry_sequence_t; kv_write_agent_key_entry_sequence_t hmac_write_seq; @@ -69,6 +78,15 @@ class kv_wr_rd_debug_sequence #( kv_rst_agent_debug_seq = kv_rst_agent_debug_sequence_t::type_id::create("kv_rst_agent_debug_seq"); if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV RST debug seq"); + kv_rst_agent_debug_on_seq = kv_rst_agent_debug_on_sequence_t::type_id::create("kv_rst_agent_debug_on_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV RST debug on seq"); + kv_rst_agent_debug_off_seq = kv_rst_agent_debug_off_sequence_t::type_id::create("kv_rst_agent_debug_off_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV RST debug off seq"); + + kv_rst_agent_scan_on_seq = kv_rst_agent_scan_on_sequence_t::type_id::create("kv_rst_agent_scan_on_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV RST scan on seq"); + kv_rst_agent_scan_off_seq = kv_rst_agent_scan_off_sequence_t::type_id::create("kv_rst_agent_scan_off_seq"); + if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV RST scan off seq"); hmac_write_seq = kv_write_agent_key_entry_sequence_t::type_id::create("hmac_write_seq"); if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV WRITE seq"); @@ -90,7 +108,6 @@ class kv_wr_rd_debug_sequence #( ecc_seed_read_seq = kv_read_agent_key_entry_sequence_t::type_id::create("ecc_seed_read_seq"); if(!this.randomize()) `uvm_error("KV WR RD", "Failed to randomize KV READ seq"); //kv_rst_agent_poweron_seq_2 = kv_rst_agent_poweron_sequence_t::type_id::create("kv_rst_agent_poweron_seq_2"); - endfunction virtual task body(); @@ -103,39 +120,30 @@ class kv_wr_rd_debug_sequence #( reg [31:0] wr_data, rd_data; reg_model = configuration.kv_rm; + //Unlock debug mode or clear secrets randomly + std::randomize(debug_type); //0 - security state, 1 - clear secrets + // debug_type = 0; + + std::randomize(wait_cycles_from_seq) with { + wait_cycles_from_seq >= 5; + wait_cycles_from_seq <= 100; + }; + std::randomize(clear_secrets_data); //wren, debug_value0/1 + //Wait for random delay before starting debug txn + configuration.kv_rst_agent_config.wait_for_num_clocks(wait_cycles_from_seq); + case(debug_type) + SECURITY_STATE: begin + //start debug seq on rst agent + // kv_rst_agent_debug_seq.start(configuration.kv_rst_agent_config.sequencer); + kv_rst_agent_debug_on_seq.start(configuration.kv_rst_agent_config.sequencer); + kv_rst_agent_debug_off_seq.start(configuration.kv_rst_agent_config.sequencer); + end + CLEAR_SECRETS: begin + reg_model.kv_reg_rm.CLEAR_SECRETS.write(sts, clear_secrets_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("AHB_CLEAR_SECRETS_SET", "Failed when writing to CLEAR_SECRETS reg!") + end + endcase - //Issue and wait for reset - if(configuration.kv_rst_agent_config.sequencer != null) - kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); - else - `uvm_error("KV WR RD", "kv_rst_agent_config.sequencer is null!") - - - //Unlock debug mode or clear secrets randomly - - std::randomize(debug_type); //0 - security state, 1 - clear secrets - - std::randomize(wait_cycles_from_seq) with { - wait_cycles_from_seq >= 5; - wait_cycles_from_seq <= 100; - }; - - std::randomize(clear_secrets_data); //wren, debug_value0/1 - - //Wait for random delay before starting debug txn - configuration.kv_rst_agent_config.wait_for_num_clocks(wait_cycles_from_seq); - - case(debug_type) - SECURITY_STATE: begin - //start debug seq on rst agent - kv_rst_agent_debug_seq.start(configuration.kv_rst_agent_config.sequencer); - end - CLEAR_SECRETS: begin - reg_model.kv_reg_rm.CLEAR_SECRETS.write(sts, clear_secrets_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); - assert(sts == UVM_IS_OK) else `uvm_error("AHB_CLEAR_SECRETS_SET", "Failed when writing to CLEAR_SECRETS reg!") - end - endcase - fork begin //Write to all entries @@ -157,6 +165,58 @@ class kv_wr_rd_debug_sequence #( end end end + join + + `uvm_info("DEBUG_WR_RD", "Waiting for sha512 write/read to finish", UVM_FULL) + configuration.kv_rst_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_key_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_privkey_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_seed_read_agent_config.wait_for_num_clocks(1000); + + `uvm_info("DEBUG_WR_RD", "Scan mode and queue writes", UVM_FULL) + fork //debug mode + begin + kv_rst_agent_scan_on_seq.start(configuration.kv_rst_agent_config.sequencer); + end + begin + queue_writes(); + //Wait for these writes to finish before setting next CTRL reg to avoid collision (test trying to write to CTRL and predictor trying to read from CTRL) + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); + end + join + + `uvm_info("DEBUG_WR_RD", "clear_secrets and queue writes", UVM_FULL) + fork //clear secrets + begin + repeat(20) begin + std::randomize(clear_secrets_data); //wren, debug_value0/1 + + reg_model.kv_reg_rm.CLEAR_SECRETS.write(sts, clear_secrets_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("AHB_CLEAR_SECRETS_SET", "Failed when writing to CLEAR_SECRETS reg!") + + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(2); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(2); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(2); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(2); + end //repeat + end + begin + queue_writes(); + //Wait for these writes to finish before setting next CTRL reg to avoid collision (test trying to write to CTRL and predictor trying to read from CTRL) + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); + end join endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh index 37b51bb32..7305ec891 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh @@ -49,13 +49,14 @@ class kv_wr_rd_lock_sequence #( kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; - rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; - rand reg[2:0] lock_data; + rand reg[2:0] lock_data; + rand reg [1:0] clear_secrets_data; rand reg [1:0] write_id; rand reg [2:0] read_id; typedef enum {HMAC, SHA512, ECC, DOE} write_agents; typedef enum {HMAC_KEY, HMAC_BLOCK, SHA512_BLOCK, ECC_PRIVKEY, ECC_SEED} read_agents; + // rand reg [KV_NUM_WRITE-1:0] wr_clients; function new(string name = ""); @@ -95,29 +96,7 @@ class kv_wr_rd_lock_sequence #( reg [31:0] wr_data, rd_data; reg_model = configuration.kv_rm; - std::randomize(hmac_write_entry) with { - hmac_write_entry != sha512_write_entry; - hmac_write_entry != ecc_write_entry; - hmac_write_entry != doe_write_entry; - }; - - std::randomize(sha512_write_entry) with { - sha512_write_entry != hmac_write_entry; - sha512_write_entry != ecc_write_entry; - sha512_write_entry != doe_write_entry; - }; - - std::randomize(ecc_write_entry) with { - ecc_write_entry != hmac_write_entry; - ecc_write_entry != sha512_write_entry; - ecc_write_entry != doe_write_entry; - }; - - std::randomize(doe_write_entry) with { - doe_write_entry != hmac_write_entry; - doe_write_entry != sha512_write_entry; - doe_write_entry != ecc_write_entry; - }; + gen_rand_entries(); //Issue and wait for reset if(configuration.kv_rst_agent_config.sequencer != null) @@ -198,47 +177,83 @@ class kv_wr_rd_lock_sequence #( end end - //TODO: this needs env clean up! (Emulate 1 clk delay between key_entry_clear and wr_resp_error) - // //clear x write - // // fork - - // //Issue and wait for reset - // if(configuration.kv_rst_agent_config.sequencer != null) - // kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); - // else - // `uvm_error("KV_WR_RD_LOCK", "kv_rst_agent_config.sequencer is null!") - - // // begin - // //Set each CTRL reg with random lock data - // for(int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin - // // if (write_entry_temp < KV_NUM_KEYS-1) begin - // // lock_data = $urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together - // reg_model.kv_reg_rm.KEY_CTRL[write_entry_temp].write(sts, 'h4, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); - // `uvm_info("KNU_LOCK", $sformatf("Setting KEY CTRL: %d", write_entry_temp), UVM_MEDIUM) - // assert(sts == UVM_IS_OK) else `uvm_error("AHB_LOCK_SET", $sformatf("Failed when writing to KEY_CTRL[%d]",write_entry_temp)) - // // end - - // for (int write_offset_temp = 0; write_offset_temp < KV_NUM_DWORDS; write_offset_temp++) begin - // // Construct the transaction - // uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_entry",write_entry_temp); - // uvm_config_db#(reg [KV_ENTRY_SIZE_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_offset",write_offset_temp); - // `uvm_info("KNU_WRITE", $sformatf("Writing to entry: %0d, offset: %0d", write_entry_temp, write_offset_temp), UVM_MEDIUM) - // hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); - // end - - - // end - // // end - - // // begin - // //Write to all entries, random offsets - // // for (int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin - - // // end - - // // end - // // join + + //clear x write + // fork + + //Issue and wait for reset + if(configuration.kv_rst_agent_config.sequencer != null) + kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); + else + `uvm_error("KV_WR_RD_LOCK", "kv_rst_agent_config.sequencer is null!") + fork + begin + repeat(20) begin + //Set each CTRL reg with random lock data + for(int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin + lock_data = $urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together + reg_model.kv_reg_rm.KEY_CTRL[write_entry_temp].write(sts, lock_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("AHB_LOCK_SET", $sformatf("Failed when writing to KEY_CTRL[%d]",write_entry_temp)) + + //Wait for lock settings to go through - design is updated after 1 clk, predictor receives txn after 2 additional clks and flags are updated accordingly + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100);//(3); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100);//(3); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100);//(3); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100);//(3); + end + end //repeat + end + begin + queue_writes(); + //Wait for these writes to finish before setting next CTRL reg to avoid collision (test trying to write to CTRL and predictor trying to read from CTRL) + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); + + end + join + fork + begin + repeat(20) begin + //Set each CTRL reg with random lock data + for(int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin + lock_data = $urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together + reg_model.kv_reg_rm.KEY_CTRL[write_entry_temp].write(sts, lock_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("AHB_LOCK_SET", $sformatf("Failed when writing to KEY_CTRL[%d]",write_entry_temp)) + + //Wait for lock settings to go through - design is updated after 1 clk, predictor receives txn after 2 additional clks and flags are updated accordingly + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(3); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(3); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(3); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(3); + end + end //repeat + end + begin + repeat(20) begin + std::randomize(clear_secrets_data); //wren, debug_value0/1 + + reg_model.kv_reg_rm.CLEAR_SECRETS.write(sts, clear_secrets_data, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + assert(sts == UVM_IS_OK) else `uvm_error("AHB_CLEAR_SECRETS_SET", "Failed when writing to CLEAR_SECRETS reg!") + + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(2); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(2); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(2); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(2); + end //repeat + end + begin + queue_writes(); + //Wait for these writes to finish before setting next CTRL reg to avoid collision (test trying to write to CTRL and predictor trying to read from CTRL) + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(100); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(100); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(100); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(100); + + end + join endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh index 9bf46403f..173f61e47 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_rst_sequence.svh @@ -192,6 +192,17 @@ class kv_wr_rd_rst_sequence #( join active_phase.reset; + configuration.kv_rst_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_doe_write_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_key_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_hmac_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_sha512_block_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_privkey_read_agent_config.wait_for_num_clocks(1000); + configuration.kv_ecc_seed_read_agent_config.wait_for_num_clocks(1000); + endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh index 180059e7f..e12a1ac9f 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_sequence.svh @@ -49,12 +49,6 @@ class kv_wr_rd_sequence #( kv_read_agent_key_entry_sequence_t ecc_privkey_read_seq; kv_read_agent_key_entry_sequence_t ecc_seed_read_seq; - rand reg [KV_ENTRY_ADDR_W-1:0] hmac_write_entry, sha512_write_entry, ecc_write_entry, doe_write_entry; - //constraint valid_entry {hmac_write_entry != sha512_write_entry != ecc_write_entry != doe_write_entry;} - - - - function new(string name = ""); super.new(name); @@ -93,29 +87,7 @@ class kv_wr_rd_sequence #( int offset = 0; reg [31:0] wr_data, rd_data; - std::randomize(hmac_write_entry) with { - hmac_write_entry != sha512_write_entry; - hmac_write_entry != ecc_write_entry; - hmac_write_entry != doe_write_entry; - }; - - std::randomize(sha512_write_entry) with { - sha512_write_entry != hmac_write_entry; - sha512_write_entry != ecc_write_entry; - sha512_write_entry != doe_write_entry; - }; - - std::randomize(ecc_write_entry) with { - ecc_write_entry != hmac_write_entry; - ecc_write_entry != sha512_write_entry; - ecc_write_entry != doe_write_entry; - }; - - std::randomize(doe_write_entry) with { - doe_write_entry != hmac_write_entry; - doe_write_entry != sha512_write_entry; - doe_write_entry != ecc_write_entry; - }; + gen_rand_entries(); //Issue and wait for reset if(configuration.kv_rst_agent_config.sequencer != null) @@ -193,6 +165,8 @@ class kv_wr_rd_sequence #( end join + + queue_writes(); endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction_coverage.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction_coverage.svh index 83a9258f0..1e05201f3 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction_coverage.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction_coverage.svh @@ -30,7 +30,7 @@ // // -covergroup rd_data(input logic rd_data_bit); +covergroup rd_data with function sample(input logic rd_data_bit); option.per_instance = 1; value: coverpoint rd_data_bit; transition: coverpoint rd_data_bit { @@ -55,7 +55,7 @@ class kv_read_transaction_coverage #( T coverage_trans; // pragma uvmf custom class_item_additional begin - rd_data rd_data_bus[KV_DATA_W]; + rd_data rd_data_bus[KV_DATA_W-1:0]; // pragma uvmf custom class_item_additional end // **************************************************************************** @@ -83,6 +83,7 @@ class kv_read_transaction_coverage #( function new(string name="", uvm_component parent=null); super.new(name,parent); kv_read_transaction_cg=new; + foreach(coverage_trans.read_data[i]) rd_data_bus[i] = new; //`uvm_warning("COVERAGE_MODEL_REVIEW", "A covergroup has been constructed which may need review because of either generation or re-generation with merging. Please note that transaction variables added as a result of re-generation and merging are not automatically added to the covergroup. Remove this warning after the covergroup has been reviewed.") endfunction @@ -92,6 +93,7 @@ class kv_read_transaction_coverage #( // function void build_phase(uvm_phase phase); kv_read_transaction_cg.set_inst_name($sformatf("kv_read_transaction_cg_%s",get_full_name())); + foreach(coverage_trans.read_data[i]) rd_data_bus[i].set_inst_name($sformatf("rd_data_bus[%0d]_%s",i,get_full_name())); endfunction // **************************************************************************** @@ -104,11 +106,8 @@ class kv_read_transaction_coverage #( `uvm_info("COV","Received transaction",UVM_HIGH); coverage_trans = t; - foreach(rd_data_bus[i]) rd_data_bus[i] = new(coverage_trans.read_data[i]); - foreach(rd_data_bus[i]) rd_data_bus[i].set_inst_name($sformatf("rd_data_bus[%0d]_%s",i,get_full_name())); - kv_read_transaction_cg.sample(); - foreach(rd_data_bus[i]) rd_data_bus[i].sample(); + foreach(rd_data_bus[i]) rd_data_bus[i].sample(coverage_trans.read_data[i]); endfunction endclass diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg.sv index aa593334e..bbdc826c9 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/kv_rst_pkg.sv @@ -79,6 +79,10 @@ package kv_rst_pkg; `include "src/kv_rst_cold_rst_sequence.svh" `include "src/kv_rst_core_rst_sequence.svh" `include "src/kv_rst_debug_sequence.svh" + `include "src/kv_rst_debug_on_sequence.svh" + `include "src/kv_rst_debug_off_sequence.svh" + `include "src/kv_rst_scan_on_sequence.svh" + `include "src/kv_rst_scan_off_sequence.svh" `include "src/kv_rst_agent.svh" diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_off_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_off_sequence.svh new file mode 100644 index 000000000..069cb5f6c --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_off_sequence.svh @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the soc_ifc_ctrl transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a soc_ifc_ctrl_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class kv_rst_debug_off_sequence extends kv_rst_sequence_base; + + `uvm_object_utils( kv_rst_debug_off_sequence ) + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + + task body(); + + // Deassert debug mode + req=kv_rst_transaction::type_id::create("rst_req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("KV_RST_DEBUG", "kv_rst_debug_off_sequence::body()-kv_rst_transaction randomization failed") + `uvm_info("KV_RST_DEBUG", "Asserting reset, pwrgood high", UVM_MEDIUM) + req.set_pwrgood = 1'b1; + req.assert_rst = 1'b0; + req.assert_core_rst = 1'b0; + req.debug_mode = 1'b0; + req.scan_mode = 1'b0; + + finish_item(req); + `uvm_info("KV_RST_DEBUG", {"Response:",req.convert2string()},UVM_MEDIUM) + + + +endtask + +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_on_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_on_sequence.svh new file mode 100644 index 000000000..7daaf9ea2 --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_on_sequence.svh @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the soc_ifc_ctrl transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a soc_ifc_ctrl_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class kv_rst_debug_on_sequence extends kv_rst_sequence_base; + + `uvm_object_utils( kv_rst_debug_on_sequence ) + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + + task body(); + + // Assert debug mode + req=kv_rst_transaction::type_id::create("pwr_req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("KV_RST_DEBUG", "kv_rst_debug_on_sequence::body()-kv_rst_transaction randomization failed") + `uvm_info("KV_RST_DEBUG", "Asserting reset, pwrgood low", UVM_MEDIUM) + req.set_pwrgood = 1'b1; + req.assert_rst = 1'b0; + req.assert_core_rst = 1'b0; + req.debug_mode = 1'b1; + req.scan_mode = 1'b0; + + finish_item(req); + `uvm_info("KV_RST_DEBUG", {"Response:",req.convert2string()},UVM_MEDIUM) + + + + +endtask + +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_off_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_off_sequence.svh new file mode 100644 index 000000000..8e0bea9ec --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_off_sequence.svh @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the soc_ifc_ctrl transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a soc_ifc_ctrl_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class kv_rst_scan_off_sequence extends kv_rst_sequence_base; + + `uvm_object_utils( kv_rst_scan_off_sequence ) + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + + task body(); + + // Assert debug mode + req=kv_rst_transaction::type_id::create("pwr_req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("KV_RST_SCAN_OFF", "kv_rst_scan_off_sequence::body()-kv_rst_transaction randomization failed") + `uvm_info("KV_RST_SCAN_OFF", "Disabling scan mode", UVM_MEDIUM) + req.set_pwrgood = 1'b1; + req.assert_rst = 1'b0; + req.assert_core_rst = 1'b0; + req.debug_mode = 1'b0; + req.scan_mode = 1'b0; + + finish_item(req); + `uvm_info("KV_RST_SCAN_OFF", {"Response:",req.convert2string()},UVM_MEDIUM) + + + + +endtask + +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_on_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_on_sequence.svh new file mode 100644 index 000000000..960931259 --- /dev/null +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_scan_on_sequence.svh @@ -0,0 +1,84 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the soc_ifc_ctrl transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a soc_ifc_ctrl_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class kv_rst_scan_on_sequence extends kv_rst_sequence_base; + + `uvm_object_utils( kv_rst_scan_on_sequence ) + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + + task body(); + + // Assert scan mode, debugUnlock_or_scan_mode_switch + req=kv_rst_transaction::type_id::create("dbg_on_req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("KV_RST_SCAN_ON", "kv_rst_scan_on_sequence::body()-kv_rst_transaction randomization failed") + `uvm_info("KV_RST_SCAN_ON", "Enabling scan mode, emulate pulse on debug_mode input", UVM_MEDIUM) + req.set_pwrgood = 1'b1; + req.assert_rst = 1'b0; + req.assert_core_rst = 1'b0; + req.debug_mode = 1'b1; + req.scan_mode = 1'b1; + + finish_item(req); + `uvm_info("KV_RST_SCAN_ON", {"Response:",req.convert2string()},UVM_MEDIUM) + + // Assert scan mode, deassert debugUnlock_or_scan_mode_switch + req=kv_rst_transaction::type_id::create("dbg_off_req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("KV_RST_SCAN_ON", "kv_rst_scan_on_sequence::body()-kv_rst_transaction randomization failed") + `uvm_info("KV_RST_SCAN_ON", "Reset debug_mode input", UVM_MEDIUM) + req.set_pwrgood = 1'b1; + req.assert_rst = 1'b0; + req.assert_core_rst = 1'b0; + req.debug_mode = 1'b0; + req.scan_mode = 1'b1; + + finish_item(req); + `uvm_info("KV_RST_SCAN_ON", {"Response:",req.convert2string()},UVM_MEDIUM) + + + + +endtask + +endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_key_entry_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_key_entry_sequence.svh index a202578d5..fb0b28b66 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_key_entry_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_key_entry_sequence.svh @@ -69,6 +69,7 @@ task body(); if((local_write_entry !== 'x) && (local_write_offset !== 'x)) begin //Use write_entry and write_offset passed in from top level sequence + `uvm_info("KV_WRITE_KEY_ENTRY_SEQ", "Write entry and write offset were set by top level seq", UVM_HIGH) `uvm_do_with(req, { req.write_entry == local_write_entry; req.write_offset == local_write_offset; @@ -76,18 +77,21 @@ task body(); end else if((local_write_entry !== 'x)) begin //Use write entry passed in from top level sequence + `uvm_info("KV_WRITE_KEY_ENTRY_SEQ", "Write entry was set by top level seq", UVM_HIGH) `uvm_do_with(req, { req.write_entry == local_write_entry; }) end else if ((local_write_offset !== 'x)) begin //Use write offset passed in from top level sequence + `uvm_info("KV_WRITE_KEY_ENTRY_SEQ", "Write offset was set by top level seq", UVM_HIGH) `uvm_do_with(req, { req.write_offset == local_write_offset; }) end else begin //Use randomized transaction write entry + `uvm_info("KV_WRITE_KEY_ENTRY_SEQ", "Write entry and write offset were not set by top level seq, randomizing in kv_write_key_entry_seq", UVM_HIGH) `uvm_do(req); end diff --git a/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv b/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv index d8850eaf4..42823c762 100644 --- a/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv +++ b/src/lc_ctrl/rtl/lc_ctrl_reg_pkg.sv @@ -268,7 +268,7 @@ package lc_ctrl_reg_pkg; parameter logic [31:0] LC_CTRL_MANUF_STATE_7_RESVAL = 32'h 0; // Register index - typedef enum int { + typedef enum logic [31:0] { LC_CTRL_ALERT_TEST, LC_CTRL_STATUS, LC_CTRL_CLAIM_TRANSITION_IF, diff --git a/src/libs/config/mvc_lib.vf b/src/libs/config/mvc_lib.vf new file mode 100644 index 000000000..a9d638c24 --- /dev/null +++ b/src/libs/config/mvc_lib.vf @@ -0,0 +1,18 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv \ No newline at end of file diff --git a/src/libs/config/uvm_lib.vf b/src/libs/config/uvm_lib.vf new file mode 100644 index 000000000..c12fb083e --- /dev/null +++ b/src/libs/config/uvm_lib.vf @@ -0,0 +1,3 @@ ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi +${UVM_HOME}/src/uvm_pkg.sv \ No newline at end of file diff --git a/src/libs/config/uvmf_lib.vf b/src/libs/config/uvmf_lib.vf new file mode 100644 index 000000000..6f0182070 --- /dev/null +++ b/src/libs/config/uvmf_lib.vf @@ -0,0 +1,64 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv \ No newline at end of file diff --git a/src/libs/rtl/clk_gate.sv b/src/libs/rtl/clk_gate.sv index 73e9ba1bd..ef01cf7d7 100644 --- a/src/libs/rtl/clk_gate.sv +++ b/src/libs/rtl/clk_gate.sv @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +`include "config_defines.svh" + module clk_gate ( input logic clk, input logic cptra_rst_b, diff --git a/src/libs/rtl/interrupt_regs.rdl b/src/libs/rtl/interrupt_regs.rdl index 2ef0e24c8..8880a5e72 100644 --- a/src/libs/rtl/interrupt_regs.rdl +++ b/src/libs/rtl/interrupt_regs.rdl @@ -141,8 +141,10 @@ addrmap interrupt_regs { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -160,8 +162,10 @@ addrmap interrupt_regs { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/ahb_lite_slave_0_config_policy.svh b/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/ahb_lite_slave_0_config_policy.svh index 1e4a139eb..1057eb119 100644 --- a/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/ahb_lite_slave_0_config_policy.svh +++ b/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/ahb_lite_slave_0_config_policy.svh @@ -121,7 +121,7 @@ class ahb_lite_slave_0_config_policy; // // If true, drives previous address when bus is IDLE // cfg.m_bfm.config_address_on_idle = 1'b0; // // Maximum number of successive wait states - cfg.m_bfm.config_max_wait_states_count = 20; + cfg.m_bfm.config_max_wait_states_count = 34; // // Data endianness // cfg.m_bfm.config_endianness = AHB_LITTLE_ENDIAN; // // Sets the domain diff --git a/src/pcrvault/coverage/pcrvault_cov_bind.sv b/src/pcrvault/coverage/pcrvault_cov_bind.sv index 09251cf44..c54f3fc3d 100644 --- a/src/pcrvault/coverage/pcrvault_cov_bind.sv +++ b/src/pcrvault/coverage/pcrvault_cov_bind.sv @@ -14,8 +14,8 @@ module pcrvault_cov_bind; - //`ifdef FCOV - bind dut pcrvault_cov_if i_pcrvault_cov_if(.*); - bind dut pcrvault_cov_props i_pcrvault_cov_props(.*); - //`endif + `ifdef FCOV + bind pv pcrvault_cov_if i_pcrvault_cov_if(.*); + bind pv pcrvault_cov_props i_pcrvault_cov_props(.*); + `endif endmodule diff --git a/src/pcrvault/coverage/pcrvault_cov_if.sv b/src/pcrvault/coverage/pcrvault_cov_if.sv index c14ec311a..45ae4d94c 100644 --- a/src/pcrvault/coverage/pcrvault_cov_if.sv +++ b/src/pcrvault/coverage/pcrvault_cov_if.sv @@ -31,19 +31,19 @@ interface pcrvault_cov_if //Assign clear and locks of each PCR_CTRL reg to corresponding bit in the intermediate bus generate for(genvar i = 0; i < PV_NUM_PCR; i++) begin - assign pcr_ctrl_lock[i] = dut.pv_reg_hwif_out.PCR_CTRL[i].lock; + assign pcr_ctrl_lock[i] = pv.pv_reg_hwif_out.PCR_CTRL[i].lock; end endgenerate generate for(genvar client = 0; client < PV_NUM_WRITE; client++) begin - assign pv_write_en[client] = dut.pv_write[client].write_en; + assign pv_write_en[client] = pv.pv_write[client].write_en; end endgenerate //AHB signals - assign ahb_write = dut.pv_ahb_slv1.dv & dut.pv_ahb_slv1.write; - assign ahb_read = dut.pv_ahb_slv1.dv & ~dut.pv_ahb_slv1.write; + assign ahb_write = pv.pv_ahb_slv1.dv & pv.pv_ahb_slv1.write; + assign ahb_read = pv.pv_ahb_slv1.dv & ~pv.pv_ahb_slv1.write; covergroup pcrvault_top_cov_grp @(posedge clk); option.per_instance = 1; diff --git a/src/pcrvault/coverage/pcrvault_cov_props.sv b/src/pcrvault/coverage/pcrvault_cov_props.sv index ba63232e7..3df578a6f 100644 --- a/src/pcrvault/coverage/pcrvault_cov_props.sv +++ b/src/pcrvault/coverage/pcrvault_cov_props.sv @@ -26,24 +26,24 @@ module pcrvault_cov_props //clear followed by warm reset in the next clk //Expectation: PCRs cleared before warm reset property cover_prop_clear_warm_rst; - @(posedge dut.clk) - (dut.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !dut.rst_b); + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.rst_b); endproperty covprop_clear_warmrst: cover property(cover_prop_clear_warm_rst); //locks, followed by clear, followed by warm reset in the next clk //Expectation: Unlocked PCRs cleared before warm reset, locks cleared on warm reset property cover_prop_lock_clear_warm_rst; - @(posedge dut.clk) - (dut.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] dut.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !dut.rst_b); + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.rst_b); endproperty covprop_lock_clear_warmrst: cover property(cover_prop_lock_clear_warm_rst); //locks, followed by clear, followed by cold reset in the next clk //Expectation: Unlocked PCRs cleared before cold reset, everything cleared on cold reset property cover_prop_lock_clear_cold_rst; - @(posedge dut.clk) - (dut.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] dut.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !dut.cptra_pwrgood); + @(posedge pv.clk) + (pv.pv_reg_hwif_out.PCR_CTRL[i].lock |-> ##[0:$] pv.pv_reg_hwif_out.PCR_CTRL[i].clear |-> ##[1:$] !pv.cptra_pwrgood); endproperty covprop_lock_clear_coldrst: cover property(cover_prop_lock_clear_cold_rst); end diff --git a/src/pcrvault/uvmf_pv/config/uvmf_pv.vf b/src/pcrvault/uvmf_pv/config/uvmf_pv.vf new file mode 100644 index 000000000..4092d085e --- /dev/null +++ b/src/pcrvault/uvmf_pv/config/uvmf_pv.vf @@ -0,0 +1,125 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/coverage ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/src ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/src ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/src ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/environment_packages/pv_env_pkg ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/tests ++incdir+${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/testbench +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_if.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_props.sv +${CALIPTRA_ROOT}/src/pcrvault/coverage/pcrvault_cov_bind.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/environment_packages/pv_env_pkg/registers/pv_reg_adapter_functions_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/pv_rst_pkg_hdl.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/pv_rst_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/src/pv_rst_driver_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/src/pv_rst_if.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_rst_pkg/src/pv_rst_monitor_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/pv_read_pkg_hdl.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/pv_read_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/src/pv_read_driver_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/src/pv_read_if.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_read_pkg/src/pv_read_monitor_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/pv_write_pkg_hdl.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/pv_write_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/src/pv_write_driver_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/src/pv_write_if.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/interface_packages/pv_write_pkg/src/pv_write_monitor_bfm.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/environment_packages/pv_env_pkg/registers/pv_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/verification_ip/environment_packages/pv_env_pkg/pv_env_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/parameters/pv_parameters_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/sequences/pv_sequences_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/tests/pv_tests_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/pcrvault/uvmf_pv/uvmf_template_output/project_benches/pv/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv \ No newline at end of file diff --git a/src/riscv_core/veer_el2/config/compile.yml b/src/riscv_core/veer_el2/config/compile.yml index ee025269a..dad981819 100755 --- a/src/riscv_core/veer_el2/config/compile.yml +++ b/src/riscv_core/veer_el2/config/compile.yml @@ -24,8 +24,6 @@ targets: rtl: directories: [$COMPILE_ROOT/rtl] files: - - $COMPILE_ROOT/rtl/pic_map_auto.h - - $COMPILE_ROOT/rtl/el2_param.vh - $COMPILE_ROOT/rtl/el2_mem.sv - $COMPILE_ROOT/rtl/el2_dma_ctrl.sv - $COMPILE_ROOT/rtl/el2_pic_ctrl.sv diff --git a/src/riscv_core/veer_el2/rtl/common_defines.sv b/src/riscv_core/veer_el2/rtl/common_defines.sv index afcbaa9a1..af5223220 100644 --- a/src/riscv_core/veer_el2/rtl/common_defines.sv +++ b/src/riscv_core/veer_el2/rtl/common_defines.sv @@ -21,6 +21,8 @@ // // cmd: veer -target=default_ahb --iccm_region=0x4 -set=ret_stack_size=8 -set=btb_enable=1 -set=btb_fullya=0 -set=btb_size=512 -set=bht_size=512 -set=div_bit=4 -set=div_new=1 -set=dccm_enable=1 -set=dccm_num_banks=4 -set=dccm_region=0x5 -set=dccm_offset=0x00000 -set=dccm_size=128 -set=dma_buf_depth=5 -set=fast_interrupt_redirect=1 -set=iccm_enable=1 -set=icache_enable=0 -set=icache_waypack=1 -set=icache_ecc=1 -set=icache_size=16 -set=icache_2banks=1 -set=icache_num_ways=2 -set=icache_bypass_enable=1 -set=icache_num_bypass=2 -set=icache_num_tag_bypass=2 -set=icache_tag_bypass_enable=1 -set=iccm_offset=0x0 -set=iccm_size=128 -set=iccm_num_banks=4 -set=lsu_stbuf_depth=4 -set=lsu_num_nbload=4 -set=load_to_use_plus1=0 -set=pic_2cycle=0 -set=pic_region=0x6 -set=pic_offset=0 -set=pic_size=32 -set=pic_total_int=31 -set=dma_buf_depth=5 -set=timer_legal_en=1 -set=bitmanip_zba=1 -set=bitmanip_zbb=1 -set=bitmanip_zbc=1 -set=bitmanip_zbe=0 -set=bitmanip_zbf=0 -set=bitmanip_zbp=0 -set=bitmanip_zbr=0 -set=bitmanip_zbs=1 -fpga_optimize=0 -snapshot=iccm_dccm_diff_region // +`ifndef COMMON_DEFINES_HEADER +`define COMMON_DEFINES_HEADER `define RV_ROOT "" `define RV_NMI_VEC 'h11110000 @@ -263,3 +265,5 @@ `define RV_IFU_BUS_ID 1 `define RV_LSU_BUS_ID 1 `define RV_NUMIREGS 32 + +`endif \ No newline at end of file diff --git a/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v b/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v index d9fd74104..39fdccde2 100644 --- a/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v +++ b/src/riscv_core/veer_el2/rtl/dmi/dmi_wrapper.v @@ -34,7 +34,6 @@ module dmi_wrapper( // Processor Signals input core_rst_n, // Core reset input core_clk, // Core clock - input [31:1] jtag_id, // JTAG ID input [31:0] rd_data, // 32 bit Read data from Processor output [31:0] reg_wr_data, // 32 bit Write data to Processor output [6:0] reg_wr_addr, // 7 bit reg address to Processor @@ -70,7 +69,6 @@ module dmi_wrapper( .idle(3'h0), // no need to wait to sample data .dmi_stat(2'b0), // no need to wait or error possible .version(4'h1), // debug spec 0.13 compliant - .jtag_id(jtag_id), .dmi_hard_reset(dmi_hard_reset), .dmi_reset(dmireset) ); diff --git a/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v b/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v index 2553575ff..ef872999f 100644 --- a/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v +++ b/src/riscv_core/veer_el2/rtl/dmi/rvjtag_tap.v @@ -37,13 +37,6 @@ output reg dmi_hard_reset, input [2:0] idle, input [1:0] dmi_stat, -/* --- revisionCode : 4'h0; --- manufacturersIdCode : 11'h45; --- deviceIdCode : 16'h0001; --- order MSB .. LSB -> [4 bit version or revision] [16 bit part number] [11 bit manufacturer id] [value of 1'b1 in LSB] -*/ -input [31:1] jtag_id, input [3:0] version ); @@ -67,7 +60,6 @@ wire pause_ir ; wire update_ir ; wire capture_ir; wire[1:0] dr_en; -wire devid_sel; wire [5:0] abits; assign abits = AWIDTH[5:0]; @@ -143,7 +135,6 @@ always @ (negedge tck or negedge trst) begin end -assign devid_sel = ir == 5'b00001; assign dr_en[0] = ir == 5'b10000; assign dr_en[1] = ir == 5'b10001; @@ -166,9 +157,7 @@ always_comb begin shift_dr: begin case(1) dr_en[1]: nsr = {tdi, sr[USER_DR_LENGTH-1:1]}; - - dr_en[0], - devid_sel: nsr = {{USER_DR_LENGTH-32{1'b0}},tdi, sr[31:1]}; + dr_en[0]: nsr = {{USER_DR_LENGTH-32{1'b0}},tdi, sr[31:1]}; default: nsr = {{USER_DR_LENGTH-1{1'b0}},tdi}; // bypass endcase end @@ -177,7 +166,6 @@ always_comb begin case(1) dr_en[0]: nsr = {{USER_DR_LENGTH-15{1'b0}}, idle, dmi_stat, abits, version}; dr_en[1]: nsr = {{AWIDTH{1'b0}}, rd_data, rd_status}; - devid_sel: nsr = {{USER_DR_LENGTH-32{1'b0}}, jtag_id, 1'b1}; endcase end shift_ir: nsr = {{USER_DR_LENGTH-5{1'b0}},tdi, sr[4:1]}; diff --git a/src/riscv_core/veer_el2/rtl/el2_veer.sv b/src/riscv_core/veer_el2/rtl/el2_veer.sv index 1ade17502..39590a63e 100644 --- a/src/riscv_core/veer_el2/rtl/el2_veer.sv +++ b/src/riscv_core/veer_el2/rtl/el2_veer.sv @@ -400,6 +400,7 @@ import el2_pkg::*; logic ifu_pmu_instr_aligned; logic ifu_ic_error_start; logic ifu_iccm_rd_ecc_single_err; + logic cptra_iccm_dma_rd_ecc_single_err; logic cptra_iccm_rd_ecc_double_err; logic lsu_axi_awready_ahb; @@ -884,7 +885,7 @@ import el2_pkg::*; .* ); - assign cptra_iccm_ecc_single_error = ifu_iccm_rd_ecc_single_err; + assign cptra_iccm_ecc_single_error = ifu_iccm_rd_ecc_single_err || cptra_iccm_dma_rd_ecc_single_err; assign cptra_iccm_ecc_double_error = cptra_iccm_rd_ecc_double_err; diff --git a/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv b/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv index cec4d24cf..d7d1d3841 100755 --- a/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv +++ b/src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv @@ -33,7 +33,6 @@ import soc_ifc_pkg::*; input logic [31:1] rst_vec, input logic nmi_int, input logic [31:1] nmi_vec, - input logic [31:1] jtag_id, output logic [31:0] trace_rv_i_insn_ip, @@ -724,7 +723,6 @@ import soc_ifc_pkg::*; // Processor Signals .core_rst_n (dbg_rst_l), // Debug reset, active low .core_clk (clk), // Core clock - .jtag_id (jtag_id), // JTAG ID .rd_data (dmi_reg_rdata_PostQ), // Read data from Processor .reg_wr_data (dmi_reg_wdata), // Write data to Processor .reg_wr_addr (dmi_reg_addr), // Write address to Processor diff --git a/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv b/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv index ddd429b1d..0c1ed5f18 100644 --- a/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv +++ b/src/riscv_core/veer_el2/rtl/ifu/el2_ifu.sv @@ -150,6 +150,7 @@ import el2_pkg::*; input logic [77:0] iccm_rd_data_ecc, // Data + ECC read from ICCM. output logic ifu_iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. + output logic cptra_iccm_dma_rd_ecc_single_err, // Active DMA access has a single ICCM ecc error. output logic cptra_iccm_rd_ecc_double_err, // Output added for Caliptra reporting // Perf counter sigs @@ -248,6 +249,8 @@ import el2_pkg::*; logic ifc_fetch_req_f; logic ifc_fetch_req_f_raw; logic [1:0] iccm_rd_ecc_double_err; // This fetch has an iccm double error. + logic iccm_dma_rd_ecc_single_err; // Active DMA access has a single ICCM ecc error. + logic iccm_dma_rd_ecc_double_err; // Active DMA access has a double ICCM ecc error. logic ifu_async_error_start; @@ -282,7 +285,8 @@ import el2_pkg::*; assign ifu_bp_inst_mask_f = 1'b1; end - assign cptra_iccm_rd_ecc_double_err = |iccm_rd_ecc_double_err; + assign cptra_iccm_dma_rd_ecc_single_err = iccm_dma_rd_ecc_single_err; + assign cptra_iccm_rd_ecc_double_err = |iccm_rd_ecc_double_err || |iccm_dma_rd_ecc_double_err; // aligner diff --git a/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv b/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv index 0d267f27e..99d537696 100644 --- a/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv +++ b/src/riscv_core/veer_el2/rtl/ifu/el2_ifu_mem_ctl.sv @@ -164,6 +164,8 @@ import el2_pkg::*; output logic [1:0] ic_access_fault_type_f, // Access fault types output logic iccm_rd_ecc_single_err, // This fetch has a single ICCM ecc error. output logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error. + output logic iccm_dma_rd_ecc_single_err, // Active DMA access has a single ICCM ecc error. + output logic iccm_dma_rd_ecc_double_err, // Active DMA access has a double ICCM ecc error. output logic ic_error_start, // This has any I$ errors ( data/tag/ecc/parity ) output logic ifu_async_error_start, // Or of the sb iccm, and all the icache errors sent to aligner to stop @@ -1275,6 +1277,8 @@ ifc_dma_access_ok_prev,dma_iccm_req_f}) assign iccm_rw_addr[pt.ICCM_BITS-1:1] = ( ifc_dma_access_q_ok & dma_iccm_req & ~iccm_correct_ecc) ? dma_mem_addr[pt.ICCM_BITS-1:1] : (~(ifc_dma_access_q_ok & dma_iccm_req) & iccm_correct_ecc) ? {iccm_ecc_corr_index_ff[pt.ICCM_BITS-1:2],1'b0} : ifc_fetch_addr_bf[pt.ICCM_BITS-1:1] ; + assign iccm_dma_rd_ecc_single_err = iccm_dma_sb_error; + assign iccm_dma_rd_ecc_double_err = iccm_dma_rvalid && iccm_dma_ecc_error; diff --git a/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv b/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv index a1d1c9793..921975a55 100644 --- a/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +++ b/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv @@ -15,6 +15,7 @@ // all flops call the rvdff flop +`include "common_defines.sv" module rvdff #( parameter WIDTH=1, SHORT=0 ) ( diff --git a/src/riscv_core/veer_el2/tb/el2_veer_wrapper_tb.sv b/src/riscv_core/veer_el2/tb/el2_veer_wrapper_tb.sv index d979631e8..889c3735a 100755 --- a/src/riscv_core/veer_el2/tb/el2_veer_wrapper_tb.sv +++ b/src/riscv_core/veer_el2/tb/el2_veer_wrapper_tb.sv @@ -28,7 +28,6 @@ module el2_veer_wrapper_tb ( input bit core_clk ); logic [31:0] reset_vector; logic [31:0] nmi_vector; - logic [31:1] jtag_id; logic [31:0] ic_haddr ; logic [2:0] ic_hburst ; @@ -411,9 +410,6 @@ module el2_veer_wrapper_tb ( input bit core_clk ); abi_reg[30] = "t5"; abi_reg[31] = "t6"; // tie offs - jtag_id[31:28] = 4'b1; - jtag_id[27:12] = '0; - jtag_id[11:1] = 11'h45; reset_vector = `RV_RESET_VEC; nmi_vector = 32'hee000000; nmi_int = 0; @@ -448,7 +444,6 @@ el2_veer_wrapper rvtop ( .rst_vec ( reset_vector[31:1]), .nmi_int ( nmi_int ), .nmi_vec ( nmi_vector[31:1]), - .jtag_id ( jtag_id[31:1]), `ifdef RV_BUILD_AHB_LITE .haddr ( ic_haddr ), diff --git a/src/sha256/formal/model/sha256_core.h b/src/sha256/formal/model/sha256_core.h new file mode 100644 index 000000000..808628fa1 --- /dev/null +++ b/src/sha256/formal/model/sha256_core.h @@ -0,0 +1,316 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + + +#ifndef SHA256_CORE_H +#define SHA256_CORE_H + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include +#include +#include +#include +#include + +SC_MODULE(sha256_core) +{ +public: + uint32_t maj, xorA, ch, xorE, sum, newA, newE; + std::array m; + std::array state; + std::array K; + std::array m_state; + std::array n; + std::array hashing;//uint8 + uint32_t i, k; + uint32_t j; + int next_dummy, init_transform_dummy, ctrl_done_dummy, mode_dummy; + + blocking_in> w_core; + blocking_in mode; +#define loopstart 0u +#define loopbound 2u +#define incr 1u + +#ifdef SIMULATION + + blocking_out digest_block; +#else + blocking_out> digest_block;//uint8 +#endif + + blocking_in next_signal, init_signal, ctrl_done; + + SC_CTOR(sha256_core) + { + SC_THREAD(fsm); + } + + uint32_t rotr(uint32_t x, uint32_t n) const + { + return (x >> n) | (x << (32u - n)); + } + uint32_t choose(uint32_t e, uint32_t f, uint32_t g) const + { + return (e & f) ^ (~e & g); + } + uint32_t majority(uint32_t a, uint32_t b, uint32_t c) const + { + return (a & (b | c)) | (b & c); + } + uint32_t sig0(uint32_t x) const + { + return rotr(x, 7u) ^ rotr(x, 18u) ^ (x >> 3u); + } + uint32_t sig1(uint32_t x) const + { + return rotr(x, 17u) ^ rotr(x, 19u) ^ (x >> 10u); + } + + void fsm() + { + K[0] = 0x428a2f98u; + K[1] = 0x71374491u; + K[2] = 0xb5c0fbcfu; + K[3] = 0xe9b5dba5u; + K[4] = 0x3956c25bu; + K[5] = 0x59f111f1u; + K[6] = 0x923f82a4u; + K[7] = 0xab1c5ed5u; + K[8] = 0xd807aa98u; + K[9] = 0x12835b01u; + K[10] = 0x243185beu; + K[11] = 0x550c7dc3u; + K[12] = 0x72be5d74u; + K[13] = 0x80deb1feu; + K[14] = 0x9bdc06a7u; + K[15] = 0xc19bf174u; + K[16] = 0xe49b69c1u; + K[17] = 0xefbe4786u; + K[18] = 0x0fc19dc6u; + K[19] = 0x240ca1ccu; + K[20] = 0x2de92c6fu; + K[21] = 0x4a7484aau; + K[22] = 0x5cb0a9dcu; + K[23] = 0x76f988dau; + K[24] = 0x983e5152u; + K[25] = 0xa831c66du; + K[26] = 0xb00327c8u; + K[27] = 0xbf597fc7u; + K[28] = 0xc6e00bf3u; + K[29] = 0xd5a79147u; + K[30] = 0x06ca6351u; + K[31] = 0x14292967u; + K[32] = 0x27b70a85u; + K[33] = 0x2e1b2138u; + K[34] = 0x4d2c6dfcu; + K[35] = 0x53380d13u; + K[36] = 0x650a7354u; + K[37] = 0x766a0abbu; + K[38] = 0x81c2c92eu; + K[39] = 0x92722c85u; + K[40] = 0xa2bfe8a1u; + K[41] = 0xa81a664bu; + K[42] = 0xc24b8b70u; + K[43] = 0xc76c51a3u; + K[44] = 0xd192e819u; + K[45] = 0xd6990624u; + K[46] = 0xf40e3585u; + K[47] = 0x106aa070u; + K[48] = 0x19a4c116u; + K[49] = 0x1e376c08u; + K[50] = 0x2748774cu; + K[51] = 0x34b0bcb5u; + K[52] = 0x391c0cb3u; + K[53] = 0x4ed8aa4au; + K[54] = 0x5b9cca4fu; + K[55] = 0x682e6ff3u; + K[56] = 0x748f82eeu; + K[57] = 0x78a5636fu; + K[58] = 0x84c87814u; + K[59] = 0x8cc70208u; + K[60] = 0x90befffau; + K[61] = 0xa4506cebu; + K[62] = 0xbef9a3f7u; + K[63] = 0xc67178f2u; + m_state[0] = 0x0u; + m_state[1] = 0x0u; + m_state[2] = 0x0u; + m_state[3] = 0x0u; + m_state[4] = 0x0u; + m_state[5] = 0x0u; + m_state[6] = 0x0u; + m_state[7] = 0x0u; + state[0] = 0x0u; + state[1] = 0x0u; + state[2] = 0x0u; + state[3] = 0x0u; + state[4] = 0x0u; + state[5] = 0x0u; + state[6] = 0x0u; + state[7] = 0x0u; + while (true) + + { + mode->read(mode_dummy, "idle"); + ctrl_done->read(ctrl_done_dummy, "idle"); + next_signal->read(next_dummy, "idle"); + init_signal->read(init_transform_dummy, "idle"); + + if (mode_dummy == 0) + { + m_state[0] = 0x6a09e667u; + m_state[1] = 0xbb67ae85u; + m_state[2] = 0x3c6ef372u; + m_state[3] = 0xa54ff53au; + m_state[4] = 0x510e527fu; + m_state[5] = 0x9b05688cu; + m_state[6] = 0x1f83d9abu; + m_state[7] = 0x5be0cd19u; + } + else if (mode_dummy == 1) + { + + m_state[0] = 0xc1059ed8u; + m_state[1] = 0x367cd507u; + m_state[2] = 0x3070dd17u; + m_state[3] = 0xf70e5939u; + m_state[4] = 0xffc00b31u; + m_state[5] = 0x68581511u; + m_state[6] = 0x64f98fa7u; + m_state[7] = 0xbefa4fa4u; + } + + if (next_dummy == 1 || init_transform_dummy == 1 || ctrl_done_dummy == 1) + { + + if (next_dummy == 1 || init_transform_dummy == 1 || ctrl_done_dummy == 1) + + { + + w_core->read(n, "ctrl_rotation"); + for (j = 0u; j < 8u; ++j) // 16 + { + + m[j] = n[j]; + } + + for (k = 0u; k < 2u; ++k) // 64 + { + m[k] = sig1(m[k - 2u]) + m[k - 7u] + sig0(m[k - 15u]) + m[k - 16u]; + } + + for (i = 0u; i < 8u; ++i) + { + state[i] = m_state[i]; + } + + for (i = 0u; i < 2u; ++i) // 64 + { + maj = majority(state[0], state[1], state[2]); + xorA = rotr(state[0], 2u) ^ rotr(state[0], 13u) ^ rotr(state[0], 22u); + + ch = choose(state[4], state[5], state[6]); + + xorE = rotr(state[4], 6u) ^ rotr(state[4], 11u) ^ rotr(state[4], 25u); + + sum = m[i] + K[i] + state[7u] + ch + xorE; + newA = xorA + maj + sum; + newE = state[3] + sum; + + state[7] = state[6]; + state[6] = state[5]; + state[5] = state[4]; + state[4] = newE; + state[3] = state[2]; + state[2] = state[1]; + state[1] = state[0]; + state[0] = newA; + } + + /*for (i = 0u; i < 8u; ++i) // 8 + { //The error is here. + m_state[i]+=state[i]; + }*/ + } + } + if (next_dummy == 0 && init_transform_dummy == 0 && ctrl_done_dummy == 1) + { + + for (i = 0u; i < 1u; ++i) // 4 + { + for (k = 0u; k < 2u; ++k) // 8 + { + hashing[i + (k * 4u)] = (m_state[k] >> (24u - i * 8u))& 0x000000ffu; + } + } + } +#ifdef SIMULATION + std::stringstream s; // THIS PART IS FOR TESTING + s << std::setfill('0') << std::hex; // THIS PART IS FOR TESTING + if (mode_dummy == 0) + { + for (uint8_t i = 0; i < 32; i++) // THIS PART IS FOR TESTING + { + s << std::setw(2) << (unsigned int)hashing[i]; // THIS PART IS FOR TESTING + } + } + else + { + for (uint8_t i = 0; i < 28; i++) // THIS PART IS FOR TESTING + { + s << std::setw(2) << (unsigned int)hashing[i]; // THIS PART IS FOR TESTING + } + + } // THIS PART IS FOR TESTING + digest_block->write(s.str(), "ctrl_done"); // THIS PART IS FOR TESTING +#else + digest_block->write(hashing, "ctrl_done"); +#endif + + if (mode_dummy == 0) + { + m_state[0] = 0x6a09e667u; + m_state[1] = 0xbb67ae85u; + m_state[2] = 0x3c6ef372u; + m_state[3] = 0xa54ff53au; + m_state[4] = 0x510e527fu; + m_state[5] = 0x9b05688cu; + m_state[6] = 0x1f83d9abu; + m_state[7] = 0x5be0cd19u; + } + else if (mode_dummy == 1) + { + + m_state[0] = 0xc1059ed8u; + m_state[1] = 0x367cd507u; + m_state[2] = 0x3070dd17u; + m_state[3] = 0xf70e5939u; + m_state[4] = 0xffc00b31u; + m_state[5] = 0x68581511u; + m_state[6] = 0x64f98fa7u; + m_state[7] = 0xbefa4fa4u; + } + } + } +}; +#endif diff --git a/src/sha256/formal/model/sha256_core_generation.h b/src/sha256/formal/model/sha256_core_generation.h new file mode 100644 index 000000000..66ad266ae --- /dev/null +++ b/src/sha256/formal/model/sha256_core_generation.h @@ -0,0 +1,256 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef SHA256_CORE_H +#define SHA256_CORE_H + +#include "systemc.h" +#include "Interfaces.h" +#include +const std::array K{0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, + 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, + 0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, + 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u, + 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, + 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, + 0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, + 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u, + 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, + 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u, + 0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, + 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u, + 0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, + 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u, + 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, + 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u}; + +uint32_t rotr(uint32_t x, uint32_t n) + { + return (x >> n) | (x << (32u - n)); + } + uint32_t choose(uint32_t e, uint32_t f, uint32_t g) + { + return (e & f) ^ (~e & g); + } + uint32_t majority(uint32_t a, uint32_t b, uint32_t c) + { + return (a & (b | c)) | (b & c); + } + uint32_t sig0(uint32_t x) + { + return rotr(x, 7u) ^ rotr(x, 18u) ^ (x >> 3u); + } + uint32_t sig1(uint32_t x) + { + return rotr(x, 17u) ^ rotr(x, 19u) ^ (x >> 10u); + } + uint32_t Summ(uint32_t x, uint32_t y, uint32_t z, uint32_t m, uint32_t e) + { + return x + y + z + m + e; + } + uint32_t newe(uint32_t x, uint32_t y) + { + return x + y; + } + uint32_t newa(uint32_t x, uint32_t y, uint32_t z) + { + return x + y + z; + } + uint32_t mult_xor(uint32_t x, uint32_t a, uint32_t b,uint32_t c) { + return (rotr(x,a)^rotr(x,b)^rotr(x,c)); + } + uint32_t compute_w(uint32_t m14, uint32_t m9,uint32_t m1, uint32_t m0){ + return (sig1(m14)+m9+sig0(m1)+m0); + } +SC_MODULE(sha256_core) +{ +public: + uint32_t k_constant; + uint32_t maj, xorA, ch, xorE, sum, newA, newE, w_temp, w_data; + std::array state; + + std::array m_state; + std::array block_dummy; + std::array m; + int i, l, k; + uint32_t j; + + bool next_dummy, init_transform_dummy, mode_dummy, zeroize_dummy; + blocking_in> w_core; + shared_in mode; + sc_biguint<512> out; + + master_out> digest_block; + + shared_in next_signal, init_signal, zeroize; + + SC_CTOR(sha256_core) + { + SC_THREAD(fsm); + } + + void fsm() + { + + state[0] = 0x0u; + state[1] = 0x0u; + state[2] = 0x0u; + state[3] = 0x0u; + state[4] = 0x0u; + state[5] = 0x0u; + state[6] = 0x0u; + state[7] = 0x0u; + m_state[0] = 0x0u; + m_state[1] = 0x0u; + m_state[2] = 0x0u; + m_state[3] = 0x0u; + m_state[4] = 0x0u; + m_state[5] = 0x0u; + m_state[6] = 0x0u; + m_state[7] = 0x0u; + w_data = 0x0u; + k_constant = 0x0u; + w_temp = 0x0u; + i = 0x0u; + + while (true) + + { + + w_core->read(block_dummy, "idle"); + init_signal->get(init_transform_dummy); + next_signal->get(next_dummy); + mode->get(mode_dummy); + zeroize->get(zeroize_dummy); + + if (init_transform_dummy == true) + { + + if(mode_dummy==false){ + // 224 + m_state[0] = 0xc1059ed8; + m_state[1] = 0x367cd507; + m_state[2] = 0x3070dd17; + m_state[3] = 0xf70e5939; + m_state[4] = 0xffc00b31; + m_state[5] = 0x68581511; + m_state[6] = 0x64f98fa7; + m_state[7] = 0xbefa4fa4; + k_constant = 0u; + } + else {// 256 + m_state[0] = 0x6a09e667u; + m_state[1] = 0xbb67ae85u; + m_state[2] = 0x3c6ef372u; + m_state[3] = 0xa54ff53au; + m_state[4] = 0x510e527fu; + m_state[5] = 0x9b05688cu; + m_state[6] = 0x1f83d9abu; + m_state[7] = 0x5be0cd19u; + k_constant = 0u; + } + + + } + for (k = 0u; k < 16u; ++k) + + { + m[k] = 0; + } + + for (j = 0u; j < 16u; ++j) + { + m[j] = block_dummy[15 - j]; + } + state[7] = m_state[7]; + state[6] = m_state[6]; + state[5] = m_state[5]; + state[4] = m_state[4]; + state[3] = m_state[3]; + state[2] = m_state[2]; + state[1] = m_state[1]; + state[0] = m_state[0]; + + + // states a b c + // m_states h h h + + j = 0u; + + for (i = 0u; i < 64u; ++i) + { + insert_state("ctrl_rotationss"); + //j = i; + if (i < 16) + { + + w_data = m[i]; + } + else + { + //w_temp = sig1(m[14]) + m[9] + sig0(m[1]) + m[0]; + w_temp = compute_w(m[14],m[9],m[1],m[0]); + for (l = 0u; l < 15u; ++l) + { + m[l] = m[(l + 1)]; + } + m[15] = w_temp; + w_data = w_temp; + } + + k_constant = K[i]; + + maj = majority(state[0], state[1], state[2]); + //xorA = rotr(state[0], 2u) ^ rotr(state[0], 13u) ^ rotr(state[0], 22u); + xorA = mult_xor(state[0],2u,13u,22u); + ch = choose(state[4], state[5], state[6]); + + //xorE = rotr(state[4], 6u) ^ rotr(state[4], 11u) ^ rotr(state[4], 25u); + xorE = mult_xor(state[4],6u,11u,25u); + sum = Summ(w_data, K[i], state[7u], ch, xorE); // m + newA = newa(xorA, maj, sum); + newE = newe(state[3], sum); + + state[7] = state[6]; + state[6] = state[5]; + state[5] = state[4]; + state[4] = newE; + state[3] = state[2]; + state[2] = state[1]; + state[1] = state[0]; + state[0] = newA; + } + + i = 0; + + insert_state("ctrl_done"); + m_state[7] = (state[7] + m_state[7]); // M_statea=H[0], States=A[b] + m_state[6] = (state[6] + m_state[6]); + m_state[5] = (state[5] + m_state[5]); + m_state[4] = (state[4] + m_state[4]); + m_state[3] = (state[3] + m_state[3]); + m_state[2] = (state[2] + m_state[2]); + m_state[1] = (state[1] + m_state[1]); + m_state[0] = (state[0] + m_state[0]); + + digest_block->master_write(m_state); + } + } +}; +#endif diff --git a/src/sha256/formal/model/tb/sha256_core_tests.h b/src/sha256/formal/model/tb/sha256_core_tests.h new file mode 100644 index 000000000..148166b40 --- /dev/null +++ b/src/sha256/formal/model/tb/sha256_core_tests.h @@ -0,0 +1,983 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef SHA256_CORE_TESTS_H +#define SHA256_CORE_TESTS_H + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include +#include +#include +#include +#include + +SC_MODULE(sha256_core_tests) +{ +public: + SC_CTOR(sha256_core_tests) + { + + SC_THREAD(tests); + } + blocking_out< int> out_mode; + blocking_out in_block; // Original type: 'wire [511:0]' + blocking_in out_block; // Original type: 'wire [255:0]' + +private: + void tests() + { + std::string in, out; + out_mode->write(0); + in = "Hello world"; + in_block->write(in); + out_block->read(out); + if (out == "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Lubis EDA"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "d97541dcee8f0a27ff699624c553512f00e0d0096d1abd84e4272389d869678d") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Tu Kaiserslautern"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "28742eba07604f9d3d3b46870ab1d16225e129a86047c50d113222776de1768b") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Mostafa Elnahas"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "2f001374ae549a41a9235c4e4f4d07431219218dbe557d8f3295c6da09253cc0") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Tobias Ludwig"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "236244ccdbabb40dc5624dd44da2ea97b4aea5a950dc7ee3454d138b34bd7d9d") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Lubis EDA"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "d97541dcee8f0a27ff699624c553512f00e0d0096d1abd84e4272389d869678d") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "5145"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "766af62a6275002e9909af31d1f15e02609d9443de336c0ce13ba52cb3e56042") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + in = "Michael Shwarz"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "bd94211bd6edc570c1b6ab198b22b3562d658f1585a950a7f5d05171ba16c780") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Max"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "a1a5936d3b0f8a69fd62c91ed9990d3bd414c5e78c603e2837c65c9f46a93eb8") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Tim"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "aac09a648fc382b6f78897595486e691d00de9dfc742f3ba1930464b56eecda6") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Tom"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "81f3bf42a93cf18dece9321ac5c93313126eb5ca92164d74643e4cbf60ecde9c") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Luiz"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "0dd0029404cbe8bbad2cd84ec0f5089e4ca29d46719323b15595ffa765a88ffe") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Advaith"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "28c37e54d13bf521c4967aa26c30750b9703ba35bf27e2d2cff2933f48029abb") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Sandeep"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "b22db2a12b26ae466aa309491c247b7e517ca9502c6005310dc642eb96ab3c19") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Rohith"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "49e4d11bf1c03edc1c3804381a1fb6b9dbaa18b2264abe2ec05b91a9d633b587") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Christian"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "67e0082893e848c8706431c32dea6c3ca86c488ae24ee6b0661489cb8b3bb78a") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Kathrin"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "d89a423ad0035508ac3cc7a7525a379f28e06c3527ffa3d1562b97a074ea4472") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Fatemeh"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "6aa81ce731a2cfb14016b63d4803642a0fc616b0838892bbf77de7d12105bbdc") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Lilo"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "6ef693f0db886ad4bf27c4d0a77c7d9ad74300211c438689a70c5f0461c79694") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Stitch"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "acc870db91ebe17c3c5d593c244f9a1b1593c4d3d6509846618702f6fbf1047b") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + ; + in = "Goofy"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "ba89bbde79460200e4aeb0f6ea27e4a304adf58853f9ad124aa66726710463d8") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Pluto"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "8dad5f6a7dd2dcd8c35ec2fd7babb499bcad60d27d73fe73eca2ce025dfd3b47") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Donald duck"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "49d2118f9e78d5dcbafbdf0e6fd3979bc4d38ad26736ec2733e480e51e374778") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "aeriel"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "6179fc95ef559edb65dc55f565718c9e13167e774dc78c1f8687495ba98b8ead") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Mulan"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "cbaa9fe121b76892d534db5412b1082cf35c417ad7f2de572149a1eaf17789ac") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Woody"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "08bb39b964dcab376f5862d7e9c8f34b8f96cfaf380142246631d78178986125") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Buzz Alrdrin"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "45883804cf4f2f87688af4c94780dd4fa59a59d6f82c00ba490d4c732b6ec0e4") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Mickey Mouse"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "ac752a50e0f6d3cdecb914d6f4fe52250ac5a8ab7238e6b7b9cef0f4b6daf652") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Mini Mouse"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "b5b85dc31e212989ceef783a24098d92d98ce1d8c97e3842fc2694c514ac3cbe") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Simba"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "f9c552cca49d95db9e09a876bbd74eb833ee063e5ce058d121d53ad0271cedc4") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Mufasa"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "de83276e6b45237548b7d6c990b6fe6fd55de68a725e9ddeaf35666f7d93c475") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Scar"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "ed82f3944eeda21207da3b2214f58830ed56d728c0161297ccc03dea247102c2") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Timon"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "f2cc6496143be1714a909f7c955ccb82bf0aaefa6505a49cf3409dc1e789fdcc") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Nala"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "aa6a77d9ccef603ca1a6e07ea856d85d067f69d1fa94f01cf22cdfafd1777255") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Alaa Eldin"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "01570ab379e65f32949f55a29af26c885409e6db1b2dce9c1b6fa9f268e32df6") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Genie"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "bc8359eb1335ec654b14ddb264bdcaa1ffe6ebebe431ebb2c2ede4552026a8c2") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Winnie"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "168bb5b349fe144916def9f699ef4544353b89728aa377822a469274388b141b") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Piglet"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "d9b336af11e4299f3b75110fe04bbf8ccc99f8bd3e50f38db9614d7486bfefed") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Hercules"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "ef97a66f04394990d341c2a51eab11d6490d90f92318b50cc02988bd5fde0d88") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Zeus"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "0ff0ef099ecb754b08b36053f2a8327f0d5b470cc3656c9fd043b9d1a2d719f5") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Tigger"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "49df5f6cae1d5191dfbf17a3696ef9818ee5bc9b11e5179afe21f0a23f9e385e") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "philoctetes"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "1d321e3644f7384f47f6df2a7e8eebaf14f417d5b6d0cc20c8b1cd6d9f6b25a5") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "A"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "AB"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABC"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDE"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "f0393febe8baaa55e32f7be2a7cc180bf34e52137d99e056c817a9c07b8f239a") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEF"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "e9c0f8b575cbfcb42ab3b78ecc87efa3b011d9a5d10b09fa4e96f240bf6a82f5") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFG"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "e9a92a2ed0d53732ac13b031a27b071814231c8633c9f41844ccba884d482b16") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGH"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "9ac2197d9258257b1ae8463e4214e4cd0a578bc1517f2415928b91be4283fc48") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGHI"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "2cdf6e152315e807562e3265bea43b48fe82511242d002fc45a35d190067a3d0") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGHIJ"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "261305762671a58cae5b74990bcfc236c2336fb04a0fbac626166d9491d2884c") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGHIJK"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "62ee2337525d8cf6e6529cf8579d51191555cb32c033c903bedb8ca295e03f81") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGHIJKL"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "922429ccdb7045d11143e2e3982a11afc11b537bf259d88d2425fa8806e86e78") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "ABCDEFGHIJKLM"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "170f5660fece35db218fece184b25e99771ddb3e8852850aba6f237624341ff4") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "N"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "8ce86a6ae65d3692e7305e2c58ac62eebd97d3d943e093f577da25c36988246b") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NO"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "23794d91c53ae875c8e247d72561e35d9d06ee07c70c9e0dbcc977a6d161504a") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOP"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "692b4856a5ca2f45e38d56256b64b254865b31069ffe891f4e7876c9075f6b10") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQ"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "0006b627f94247c2991955b58be1821c649c649e4fdf445469bebc3762919d2d") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQR"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "29259343584eee776b38f7b89ddcee6b72a1aa71ee4aa9dc5d655a8ec8289ca7") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQRS"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "12be4169c73bf011b81f405d6b7f8bbf897d42a94fd4b88282efe3a2d100aa02") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQRST"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "20d5fd7f8e1f2f1b4656153a4800a04ea6d5c70dc7b24ea0b593ea13053232f8") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQRSTW"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "68201bf9788c3be4a6f411b95202ffcf3a40fa15bdd6074160a7ee1465cb25aa") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "NOPQRSTWX"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "233d4813648dd26e37304cb8c0c18ffeae60a656f6b95395a9068a6df0643149") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "XYZ"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "ade099751d2ea9f3393f0f32d20c6b980dd5d3b0989dea599b966ae0d3cd5a1e") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Super-Man"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "eef32a6ad13cd7ce249a66eedfebfdc019d3a07946029dc82bd60feff083aecf") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "BatMan"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "1175f8ee115c0a5da53eccfd2c852c4ee0c5fb513ce2d71f0c4a69c2faf370da") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "CatWoman"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "690aa6b8a7aa834ba0137fa8efbf4ce8287dbae06e2d0c1bab01142558d1a53d") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + + in = "Jadal"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "32ffebd23525c0424caa9aac71dcb26e66fd891ae28a8da6de5cf1761e00eacb") + cout << "test passed " << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + in = "Jadal"; + out_mode->write(1); + in_block->write(in); + out_block->read(out); + if (out == "5296ec14dd94b33683767b95b2d83078647f3aa082be16a8b975a9a5") + { + cout << "test passedsha224" << endl; + } + else + { + cout << out << endl; + cout << "test failed" << endl; + } + in = "Einstien"; + out_mode->write(0); + + in_block->write(in); + out_block->read(out); + if (out == "7a287e7aab0d8218a74531bdcc1ad83fd5fef954e67c66d346d1e51e6be0f66b") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } + in = "ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897"; + out_mode->write(0); + in_block->write(in); + out_block->read(out); + if (out == "126f5f6829b04b22bbe37812955030fa4bb94aad0c853356857b3d2cdd138438") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + } +/* + + in = "ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897ad9dbaff7b64c8a7124d49712c962c1adc1295c311ec04b8b013bb3ad709d897"; + out_mode->write(0); + in_block->write(in); + out_block->read(out); + if (out == "abd613f1556aa411e2008c61b3045ab1e56a798494685993ffdc66d8") + cout << "test passed" << endl; + else + { + cout << out << endl; + cout << "test failed" << endl; + }*/ + } +}; + +#endif diff --git a/src/sha256/formal/model/tb/sha256_memory.h b/src/sha256/formal/model/tb/sha256_memory.h new file mode 100644 index 000000000..4a743b6c0 --- /dev/null +++ b/src/sha256/formal/model/tb/sha256_memory.h @@ -0,0 +1,185 @@ + +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +#ifndef SHA256_MEMORY_H +#define SHA256_MEMORY_H + +#include "systemc.h" +#include "Interfaces.h" +#include +#include +#include +#include +#include +#include +#include + +SC_MODULE(sha256_memory) +{ + +public: + blocking_in block; + blocking_out> w; + blocking_out< int> next; + blocking_out< int> ctrl_done; + blocking_out< int> init_transfrom; + + SC_CTOR(sha256_memory) + { + SC_THREAD(mem); + } + +private: + uint32_t m_blocklen = 0, m[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t m_bitlen = 0; + uint8_t m_data[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::array mj = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + std::string block_dummy; + + void update(const uint8_t *data, size_t length) + { + m_bitlen = 0; + m_blocklen = 0; + + for (size_t i = 0; i < length; i++) + { + m_data[m_blocklen++] = data[i]; + + if (m_blocklen == 64) + { + + for (uint8_t i = 0, j = 0; i < 16; i++, j += 4) + { + m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]); + } + for (int i = 0; i < 16; i++) + { + + mj[i] = m[i]; + } + + if (m_bitlen < 512) + { + + ctrl_done->write(0); + next->write(0); + init_transfrom->write(1); + w->write(mj); + } + + else + { + ctrl_done->write(0); + next->write(1); + init_transfrom->write(0); + w->write(mj); + } + + m_bitlen = m_bitlen + 512; + m_blocklen = 0; + } + } + } + + void update(const std::string &data) + { + update(reinterpret_cast(data.c_str()), data.size()); + } + + void mem() + + { + + while (true) + { + + block->read(block_dummy); + + update(block_dummy); + + uint64_t i = m_blocklen; + uint8_t end = m_blocklen < 56 ? 56 : 64; + m_data[i++] = 0x80; // Append a bit 1 + while (i < end) + + { + m_data[i++] = 0x00; // Pad with zeros + } + + if (m_blocklen >= 56) + { + for (uint8_t i = 0, j = 0; i < 16; i++, j += 4) + + { + m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]); + } + + for (int i = 0; i < 16; i++) + { + + mj[i] = m[i]; + } + + if (m_bitlen < 512) + { + ctrl_done->write(0); + next->write(0); + init_transfrom->write(1); + w->write(mj); + } + + else + { + ctrl_done->write(0); + next->write(1); + init_transfrom->write(0); + w->write(mj); + } + memset(m_data, 0, 56); + } + + // Append to the padding the total message's length in bits and transform. + m_bitlen += m_blocklen * 8; + m_data[63] = m_bitlen; + m_data[62] = m_bitlen >> 8; + m_data[61] = m_bitlen >> 16; + m_data[60] = m_bitlen >> 24; + m_data[59] = m_bitlen >> 32; + m_data[58] = m_bitlen >> 40; + m_data[57] = m_bitlen >> 48; + m_data[56] = m_bitlen >> 56; + for (uint8_t i = 0, j = 0; i < 16; i++, j += 4) + + { + m[i] = (m_data[j] << 24) | (m_data[j + 1] << 16) | (m_data[j + 2] << 8) | (m_data[j + 3]); + } + for (uint32_t i = 0; i < 16; i++) + { + + mj[i] = m[i]; + } + ctrl_done->write(1); + next->write(0); + init_transfrom->write(0); + w->write(mj); + } + } +}; +#endif \ No newline at end of file diff --git a/src/sha256/formal/properties/fv_constraints.sv b/src/sha256/formal/properties/fv_constraints.sv new file mode 100644 index 000000000..a945bc1cc --- /dev/null +++ b/src/sha256/formal/properties/fv_constraints.sv @@ -0,0 +1,54 @@ + +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_constraints( init, next, reset_n, clk, mode); + input bit init, next, reset_n, clk, mode; + reg init_reg; + + default clocking default_clk @(posedge clk); endclocking + remove_int_next_together_a: assume property (remove_int_next_together); + property remove_int_next_together; + !(init && next); + endproperty + + int_next_order_a: assume property (int_next_order); + property int_next_order; + !init_reg |-> !next; + endproperty + + + + always @ (posedge clk or negedge reset_n) + begin : init_reg_order + if (!reset_n) + init_reg <= 1'b0; + else if (init) + init_reg <= 1'b1; + end + +endmodule + +bind sha256_core fv_constraints inst2( + .init(init_cmd), + .next(next_cmd), + .reset_n(reset_n), + .clk(clk), + .mode(mode) +); \ No newline at end of file diff --git a/src/sha256/formal/properties/fv_coverpoints.sv b/src/sha256/formal/properties/fv_coverpoints.sv new file mode 100644 index 000000000..f1ddeb0b7 --- /dev/null +++ b/src/sha256/formal/properties/fv_coverpoints.sv @@ -0,0 +1,48 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_coverpoints_m( + input logic clk, + input logic reset_n +); + + default clocking default_clk @(posedge clk); endclocking + + //Cover zeroize: + //Assert zeroize input and check the status of all registers. All registers/internal memories should be cleared. + cover_zeroize: cover property(disable iff(!reset_n) sha256_core.zeroize ); + cover_zeroize_after_next: cover property(disable iff(!reset_n) sha256_core.zeroize && sha256_core.next_cmd ); + + //Cover modes: + //Cover all 4 different modes for SHA512 + cover_mode_224: cover property(disable iff(!reset_n) sha256_core.mode == 0 && sha256_core.init_cmd ); + cover_mode_256: cover property(disable iff(!reset_n) sha256_core.mode == 1 && sha256_core.init_cmd ); + + + //Cover: i>16 + cover_rnd_cnt_bigger_16: cover property(disable iff(!reset_n) sha256_core.t_ctr_reg == 17 ##1 sha256_core.t_ctr_reg == 17[->1] ); + + + + +endmodule +bind sha256_core fv_coverpoints_m fv_coverpoints( + .clk(clk), + .reset_n(reset_n) +); \ No newline at end of file diff --git a/src/sha256/formal/properties/fv_sha256.sv b/src/sha256/formal/properties/fv_sha256.sv new file mode 100644 index 000000000..356e51c80 --- /dev/null +++ b/src/sha256/formal/properties/fv_sha256.sv @@ -0,0 +1,600 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + +import fv_sha256_pkg::*; + +module fv_sha_256_m( + input bit rst, + input bit clk, + input bit unsigned [31:0] digest_out_0, + input bit unsigned [31:0] digest_out_1, + input bit unsigned [31:0] digest_out_2, + input bit unsigned [31:0] digest_out_3, + input bit unsigned [31:0] digest_out_4, + input bit unsigned [31:0] digest_out_5, + input bit unsigned [31:0] digest_out_6, + input bit unsigned [31:0] digest_out_7, + input bit block_init, + input bit block_mode, + input bit block_next, + input bit unsigned [31:0] block_in_0, + input bit unsigned [31:0] block_in_1, + input bit unsigned [31:0] block_in_2, + input bit unsigned [31:0] block_in_3, + input bit unsigned [31:0] block_in_4, + input bit unsigned [31:0] block_in_5, + input bit unsigned [31:0] block_in_6, + input bit unsigned [31:0] block_in_7, + input bit unsigned [31:0] block_in_8, + input bit unsigned [31:0] block_in_9, + input bit unsigned [31:0] block_in_10, + input bit unsigned [31:0] block_in_11, + input bit unsigned [31:0] block_in_12, + input bit unsigned [31:0] block_in_13, + input bit unsigned [31:0] block_in_14, + input bit unsigned [31:0] block_in_15, + input bit block_zeroize, + input bit block_in_valid, + input bit digest_valid, + input bit block_in_ready, + input bit unsigned [5:0] i, + input bit unsigned [31:0] W_0, + input bit unsigned [31:0] W_1, + input bit unsigned [31:0] W_2, + input bit unsigned [31:0] W_3, + input bit unsigned [31:0] W_4, + input bit unsigned [31:0] W_5, + input bit unsigned [31:0] W_6, + input bit unsigned [31:0] W_7, + input bit unsigned [31:0] W_8, + input bit unsigned [31:0] W_9, + input bit unsigned [31:0] W_10, + input bit unsigned [31:0] W_11, + input bit unsigned [31:0] W_12, + input bit unsigned [31:0] W_13, + input bit unsigned [31:0] W_14, + input bit unsigned [31:0] W_15, + input bit unsigned [31:0] H_0, + input bit unsigned [31:0] H_1, + input bit unsigned [31:0] H_2, + input bit unsigned [31:0] H_3, + input bit unsigned [31:0] H_4, + input bit unsigned [31:0] H_5, + input bit unsigned [31:0] H_6, + input bit unsigned [31:0] H_7, + input bit unsigned [31:0] a, + input bit unsigned [31:0] b, + input bit unsigned [31:0] c, + input bit unsigned [31:0] d, + input bit unsigned [31:0] e, + input bit unsigned [31:0] f, + input bit unsigned [31:0] g, + input bit unsigned [31:0] h, + input bit idle, + input bit ctrl_rotationss, + input bit ctrl_done +); + + +default clocking default_clk @(posedge clk); endclocking +logic [15:0][31:0] w; +logic [3:0] j; + +assign j = i[3:0]; +assign w = {W_15,W_14,W_13,W_12,W_11,W_10,W_9,W_8,W_7,W_6,W_5,W_4,W_3,W_2,W_1,W_0}; + +sequence reset_sequence; + !rst ##1 rst; +endsequence + + +reset_a: assert property (reset_p); +property reset_p; + reset_sequence |-> + idle && + i == 'sd0 && + W_0 == 0 && + W_10 == 0 && + W_11 == 0 && + W_12 == 0 && + W_13 == 0 && + W_14 == 0 && + W_15 == 0 && + W_1 == 0 && + W_2 == 0 && + W_3 == 0 && + W_4 == 0 && + W_5 == 0 && + W_6 == 0 && + W_7 == 0 && + W_8 == 0 && + W_9 == 0 && + H_0 == 0 && + H_1 == 0 && + H_2 == 0 && + H_3 == 0 && + H_4 == 0 && + H_5 == 0 && + H_6 == 0 && + H_7 == 0 && + a == 0 && + b == 0 && + c == 0 && + d == 0 && + e == 0 && + f == 0 && + g == 0 && + h == 0 && + digest_valid == 0 && + block_in_ready == 1; +endproperty + + +DONE_to_IDLE_a: assert property (disable iff(!rst) DONE_to_IDLE_p); +property DONE_to_IDLE_p; + ctrl_done +|-> + ##1 + idle && + digest_out_0 == ($past(a, 1) + $past(H_0, 1)) && + digest_out_1 == ($past(b, 1) + $past(H_1, 1)) && + digest_out_2 == ($past(c, 1) + $past(H_2, 1)) && + digest_out_3 == ($past(d, 1) + $past(H_3, 1)) && + digest_out_4 == ($past(e, 1) + $past(H_4, 1)) && + digest_out_5 == ($past(f, 1) + $past(H_5, 1)) && + digest_out_6 == ($past(g, 1) + $past(H_6, 1)) && + digest_out_7 == ($past(h, 1) + $past(H_7, 1)) && + i == $past(i, 1) && + W_0 == $past(W_0, 1) && + W_10 == $past(W_10, 1) && + W_11 == $past(W_11, 1) && + W_12 == $past(W_12, 1) && + W_13 == $past(W_13, 1) && + W_14 == $past(W_14, 1) && + W_15 == $past(W_15, 1) && + W_1 == $past(W_1, 1) && + W_2 == $past(W_2, 1) && + W_3 == $past(W_3, 1) && + W_4 == $past(W_4, 1) && + W_5 == $past(W_5, 1) && + W_6 == $past(W_6, 1) && + W_7 == $past(W_7, 1) && + W_8 == $past(W_8, 1) && + W_9 == $past(W_9, 1) && + H_0 == ($past(a, 1) + $past(H_0, 1)) && + H_1 == ($past(b, 1) + $past(H_1, 1)) && + H_2 == ($past(c, 1) + $past(H_2, 1)) && + H_3 == ($past(d, 1) + $past(H_3, 1)) && + H_4 == ($past(e, 1) + $past(H_4, 1)) && + H_5 == ($past(f, 1) + $past(H_5, 1)) && + H_6 == ($past(g, 1) + $past(H_6, 1)) && + H_7 == ($past(h, 1) + $past(H_7, 1)) && + a == $past(a, 1) && + b == $past(b, 1) && + c == $past(c, 1) && + d == $past(d, 1) && + e == $past(e, 1) && + f == $past(f, 1) && + g == $past(g, 1) && + h == $past(h, 1) && + digest_valid == 1 && + block_in_ready == 1; +endproperty + + +SHA_Rounds_to_DONE_a: assert property (disable iff(!rst) SHA_Rounds_to_DONE_p); +property SHA_Rounds_to_DONE_p; + ctrl_rotationss && + (i >= 'sd16) && + (('sd1 + i) >= 'sd64) +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_done && + i == 'sd0 && + W_0 == $past(W_1, 1) && + W_10 == $past(W_11, 1) && + W_11 == $past(W_12, 1) && + W_12 == $past(W_13, 1) && + W_13 == $past(W_14, 1) && + W_14 == $past(W_15, 1) && + W_15 == $past(compute_w(W_14,W_9,W_1,W_0)) && + W_1 == $past(W_2, 1) && + W_2 == $past(W_3, 1) && + W_3 == $past(W_4, 1) && + W_4 == $past(W_5, 1) && + W_5 == $past(W_6, 1) && + W_6 == $past(W_7, 1) && + W_7 == $past(W_8, 1) && + W_8 == $past(W_9, 1) && + W_9 == $past(W_10, 1) && + H_0 == $past(H_0, 1) && + H_1 == $past(H_1, 1) && + H_2 == $past(H_2, 1) && + H_3 == $past(H_3, 1) && + H_4 == $past(H_4, 1) && + H_5 == $past(H_5, 1) && + H_6 == $past(H_6, 1) && + H_7 == $past(H_7, 1) && + a == $past(newa(mult_xor(a, 2, 13, 22),majority(a,b,c),Summ(compute_w(W_14,W_9,W_1,W_0),K[i],h,choose(e,f,g),mult_xor(e, 6, 11, 25)))) && + b == $past(a, 1) && + c == $past(b, 1) && + d == $past(c, 1) && + e == $past(newe(d,Summ(compute_w(W_14,W_9,W_1,W_0),K[i],h,choose(e,f,g),mult_xor(e,6,11,25)))) && + f == $past(e, 1) && + g == $past(f, 1) && + h == $past(g, 1); +endproperty + + +SHA_Rounds_to_SHA_Rounds_before_16_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_before_16_p); +property SHA_Rounds_to_SHA_Rounds_before_16_p; + ctrl_rotationss && + (i < 'sd16) +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_rotationss && + i == ('sd1 + $past(i, 1)) && + W_0 == $past(W_0, 1) && + W_10 == $past(W_10, 1) && + W_11 == $past(W_11, 1) && + W_12 == $past(W_12, 1) && + W_13 == $past(W_13, 1) && + W_14 == $past(W_14, 1) && + W_15 == $past(W_15, 1) && + W_1 == $past(W_1, 1) && + W_2 == $past(W_2, 1) && + W_3 == $past(W_3, 1) && + W_4 == $past(W_4, 1) && + W_5 == $past(W_5, 1) && + W_6 == $past(W_6, 1) && + W_7 == $past(W_7, 1) && + W_8 == $past(W_8, 1) && + W_9 == $past(W_9, 1) && + H_0 == $past(H_0, 1) && + H_1 == $past(H_1, 1) && + H_2 == $past(H_2, 1) && + H_3 == $past(H_3, 1) && + H_4 == $past(H_4, 1) && + H_5 == $past(H_5, 1) && + H_6 == $past(H_6, 1) && + H_7 == $past(H_7, 1) && + a == $past(newa(mult_xor(a, 2, 13, 22),majority(a,b,c),Summ(w[j],K[i],h,choose(e,f,g),mult_xor(e, 6, 11, 25)))) && + b == $past(a, 1) && + c == $past(b, 1) && + d == $past(c, 1) && + e == $past(newe(d,Summ(w[j],K[i],h,choose(e,f,g),mult_xor(e,6,11,25)))) && + f == $past(e, 1) && + g == $past(f, 1) && + h == $past(g, 1); +endproperty + + +SHA_Rounds_to_SHA_Rounds_after_16_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_after_16_p); +property SHA_Rounds_to_SHA_Rounds_after_16_p; + ctrl_rotationss && + (i >= 'sd16) && + (('sd1 + i) < 'sd64) +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_rotationss && + i == ('sd1 + $past(i, 1)) && + W_0 == $past(W_1, 1) && + W_10 == $past(W_11, 1) && + W_11 == $past(W_12, 1) && + W_12 == $past(W_13, 1) && + W_13 == $past(W_14, 1) && + W_14 == $past(W_15, 1) && + W_15 == $past(compute_w(W_14,W_9,W_1,W_0)) && + W_1 == $past(W_2, 1) && + W_2 == $past(W_3, 1) && + W_3 == $past(W_4, 1) && + W_4 == $past(W_5, 1) && + W_5 == $past(W_6, 1) && + W_6 == $past(W_7, 1) && + W_7 == $past(W_8, 1) && + W_8 == $past(W_9, 1) && + W_9 == $past(W_10, 1) && + H_0 == $past(H_0, 1) && + H_1 == $past(H_1, 1) && + H_2 == $past(H_2, 1) && + H_3 == $past(H_3, 1) && + H_4 == $past(H_4, 1) && + H_5 == $past(H_5, 1) && + H_6 == $past(H_6, 1) && + H_7 == $past(H_7, 1) && + a == $past(newa(mult_xor(a, 2, 13, 22),majority(a,b,c),Summ(compute_w(W_14,W_9,W_1,W_0),K[i],h,choose(e,f,g),mult_xor(e, 6, 11, 25)))) && + b == $past(a, 1) && + c == $past(b, 1) && + d == $past(c, 1) && + e == $past(newe(d,Summ(compute_w(W_14,W_9,W_1,W_0),K[i],h,choose(e,f,g),mult_xor(e,6,11,25)))) && + f == $past(e, 1) && + g == $past(f, 1) && + h == $past(g, 1); +endproperty + + +IDLE_to_SHA_Rounds_224_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_224_p); +property IDLE_to_SHA_Rounds_224_p; + idle && + block_in_valid && + block_init && + !block_mode +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_rotationss && + i == 'sd0 && + W_0 == $past(block_in_15, 1) && + W_10 == $past(block_in_5, 1) && + W_11 == $past(block_in_4, 1) && + W_12 == $past(block_in_3, 1) && + W_13 == $past(block_in_2, 1) && + W_14 == $past(block_in_1, 1) && + W_15 == $past(block_in_0, 1) && + W_1 == $past(block_in_14, 1) && + W_2 == $past(block_in_13, 1) && + W_3 == $past(block_in_12, 1) && + W_4 == $past(block_in_11, 1) && + W_5 == $past(block_in_10, 1) && + W_6 == $past(block_in_9, 1) && + W_7 == $past(block_in_8, 1) && + W_8 == $past(block_in_7, 1) && + W_9 == $past(block_in_6, 1) && + H_0 == 32'd3238371032 && + H_1 == 32'd914150663 && + H_2 == 32'd812702999 && + H_3 == 32'd4144912697 && + H_4 == 32'd4290775857 && + H_5 == 32'd1750603025 && + H_6 == 32'd1694076839 && + H_7 == 32'd3204075428 && + a == 32'd3238371032 && + b == 32'd914150663 && + c == 32'd812702999 && + d == 32'd4144912697 && + e == 32'd4290775857 && + f == 32'd1750603025 && + g == 32'd1694076839 && + h == 32'd3204075428; +endproperty + + +IDLE_to_SHA_Rounds_256_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_256_p); +property IDLE_to_SHA_Rounds_256_p; + idle && + block_in_valid && + block_init && + block_mode +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_rotationss && + i == 'sd0 && + W_0 == $past(block_in_15, 1) && + W_10 == $past(block_in_5, 1) && + W_11 == $past(block_in_4, 1) && + W_12 == $past(block_in_3, 1) && + W_13 == $past(block_in_2, 1) && + W_14 == $past(block_in_1, 1) && + W_15 == $past(block_in_0, 1) && + W_1 == $past(block_in_14, 1) && + W_2 == $past(block_in_13, 1) && + W_3 == $past(block_in_12, 1) && + W_4 == $past(block_in_11, 1) && + W_5 == $past(block_in_10, 1) && + W_6 == $past(block_in_9, 1) && + W_7 == $past(block_in_8, 1) && + W_8 == $past(block_in_7, 1) && + W_9 == $past(block_in_6, 1) && + H_0 == 32'd1779033703 && + H_1 == 32'd3144134277 && + H_2 == 32'd1013904242 && + H_3 == 32'd2773480762 && + H_4 == 32'd1359893119 && + H_5 == 32'd2600822924 && + H_6 == 32'd528734635 && + H_7 == 32'd1541459225 && + a == 32'd1779033703 && + b == 32'd3144134277 && + c == 32'd1013904242 && + d == 32'd2773480762 && + e == 32'd1359893119 && + f == 32'd2600822924 && + g == 32'd528734635 && + h == 32'd1541459225; +endproperty + + +IDLE_to_SHA_Rounds_next_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_next_p); +property IDLE_to_SHA_Rounds_next_p; + idle && + block_in_valid && + !block_init +|-> + ##1 (digest_valid == 0) and + ##1 (block_in_ready == 0) and + ##1 + ctrl_rotationss && + i == 'sd0 && + W_0 == $past(block_in_15, 1) && + W_10 == $past(block_in_5, 1) && + W_11 == $past(block_in_4, 1) && + W_12 == $past(block_in_3, 1) && + W_13 == $past(block_in_2, 1) && + W_14 == $past(block_in_1, 1) && + W_15 == $past(block_in_0, 1) && + W_1 == $past(block_in_14, 1) && + W_2 == $past(block_in_13, 1) && + W_3 == $past(block_in_12, 1) && + W_4 == $past(block_in_11, 1) && + W_5 == $past(block_in_10, 1) && + W_6 == $past(block_in_9, 1) && + W_7 == $past(block_in_8, 1) && + W_8 == $past(block_in_7, 1) && + W_9 == $past(block_in_6, 1) && + H_0 == $past(H_0, 1) && + H_1 == $past(H_1, 1) && + H_2 == $past(H_2, 1) && + H_3 == $past(H_3, 1) && + H_4 == $past(H_4, 1) && + H_5 == $past(H_5, 1) && + H_6 == $past(H_6, 1) && + H_7 == $past(H_7, 1) && + a == $past(H_0, 1) && + b == $past(H_1, 1) && + c == $past(H_2, 1) && + d == $past(H_3, 1) && + e == $past(H_4, 1) && + f == $past(H_5, 1) && + g == $past(H_6, 1) && + h == $past(H_7, 1); +endproperty + + +idle_wait_a: assert property (disable iff(!rst) idle_wait_p); +property idle_wait_p; + idle && + !block_in_valid +|-> + ##1 + idle && + i == $past(i, 1) && + W_0 == $past(W_0, 1) && + W_10 == $past(W_10, 1) && + W_11 == $past(W_11, 1) && + W_12 == $past(W_12, 1) && + W_13 == $past(W_13, 1) && + W_14 == $past(W_14, 1) && + W_15 == $past(W_15, 1) && + W_1 == $past(W_1, 1) && + W_2 == $past(W_2, 1) && + W_3 == $past(W_3, 1) && + W_4 == $past(W_4, 1) && + W_5 == $past(W_5, 1) && + W_6 == $past(W_6, 1) && + W_7 == $past(W_7, 1) && + W_8 == $past(W_8, 1) && + W_9 == $past(W_9, 1) && + H_0 == $past(H_0, 1) && + H_1 == $past(H_1, 1) && + H_2 == $past(H_2, 1) && + H_3 == $past(H_3, 1) && + H_4 == $past(H_4, 1) && + H_5 == $past(H_5, 1) && + H_6 == $past(H_6, 1) && + H_7 == $past(H_7, 1) && + a == $past(a, 1) && + b == $past(b, 1) && + c == $past(c, 1) && + d == $past(d, 1) && + e == $past(e, 1) && + f == $past(f, 1) && + g == $past(g, 1) && + h == $past(h, 1) && + digest_valid == $past(digest_valid) && + block_in_ready == 1; +endproperty + + +endmodule + + + +bind sha256_core fv_sha_256_m fv_sha256( + .rst(sha256_core.reset_n && !sha256_core.zeroize), + .clk(sha256_core.clk), + .digest_out_0(sha256_core.digest [255:224]), + .digest_out_1(sha256_core.digest [223:192]), + .digest_out_2(sha256_core.digest [191:160]), + .digest_out_3(sha256_core.digest [159:128]), + .digest_out_4(sha256_core.digest [127:96]), + .digest_out_5(sha256_core.digest [95:64]), + .digest_out_6(sha256_core.digest [63:32]), + .digest_out_7(sha256_core.digest [31:0]), + .block_init(sha256_core.init_cmd), + .block_mode(sha256_core.mode), + .block_next(sha256_core.next_cmd), + .block_in_0(sha256_core.block_msg[31:0]), + .block_in_1(sha256_core.block_msg[63:32]), + .block_in_2(sha256_core.block_msg[95:64]), + .block_in_3(sha256_core.block_msg[127:96]), + .block_in_4(sha256_core.block_msg[159:128]), + .block_in_5(sha256_core.block_msg[191:160]), + .block_in_6(sha256_core.block_msg[223:192]), + .block_in_7(sha256_core.block_msg[255:224]), + .block_in_8(sha256_core.block_msg[287:256]), + .block_in_9(sha256_core.block_msg[319:288]), + .block_in_10(sha256_core.block_msg[351:320]), + .block_in_11(sha256_core.block_msg[383:352]), + .block_in_12(sha256_core.block_msg[415:384]), + .block_in_13(sha256_core.block_msg[447:416]), + .block_in_14(sha256_core.block_msg[479:448]), + .block_in_15(sha256_core.block_msg[511:480]), + .block_zeroize(sha256_core.zeroize), + .block_in_valid((sha256_core.init_cmd) || (sha256_core.next_cmd)), + .digest_valid(sha256_core.digest_valid), + .block_in_ready(sha256_core.ready), + .i(sha256_core.t_ctr_reg), + .W_0(sha256_core.w_mem_inst.w_mem[00]), + .W_1(sha256_core.w_mem_inst.w_mem[01]), + .W_2(sha256_core.w_mem_inst.w_mem[02]), + .W_3(sha256_core.w_mem_inst.w_mem[03]), + .W_4(sha256_core.w_mem_inst.w_mem[04]), + .W_5(sha256_core.w_mem_inst.w_mem[05]), + .W_6(sha256_core.w_mem_inst.w_mem[06]), + .W_7(sha256_core.w_mem_inst.w_mem[07]), + .W_8(sha256_core.w_mem_inst.w_mem[08]), + .W_9(sha256_core.w_mem_inst.w_mem[09]), + .W_10(sha256_core.w_mem_inst.w_mem[10]), + .W_11(sha256_core.w_mem_inst.w_mem[11]), + .W_12(sha256_core.w_mem_inst.w_mem[12]), + .W_13(sha256_core.w_mem_inst.w_mem[13]), + .W_14(sha256_core.w_mem_inst.w_mem[14]), + .W_15(sha256_core.w_mem_inst.w_mem[15]), + .H_0(sha256_core.H0_reg), + .H_1(sha256_core.H1_reg), + .H_2(sha256_core.H2_reg), + .H_3(sha256_core.H3_reg), + .H_4(sha256_core.H4_reg), + .H_5(sha256_core.H5_reg), + .H_6(sha256_core.H6_reg), + .H_7(sha256_core.H7_reg), + .a(sha256_core.a_reg), + .b(sha256_core.b_reg), + .c(sha256_core.c_reg), + .d(sha256_core.d_reg), + .e(sha256_core.e_reg), + .f(sha256_core.f_reg), + .g(sha256_core.g_reg), + .h(sha256_core.h_reg), + .idle(sha256_core.sha256_ctrl_reg==2'h0), + .ctrl_rotationss(sha256_core.sha256_ctrl_reg==2'h1), + .ctrl_done(sha256_core.sha256_ctrl_reg==2'h2) +); + + + diff --git a/src/sha256/formal/properties/fv_sha256_pkg.sv b/src/sha256/formal/properties/fv_sha256_pkg.sv new file mode 100644 index 000000000..71d9803de --- /dev/null +++ b/src/sha256/formal/properties/fv_sha256_pkg.sv @@ -0,0 +1,75 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// +package fv_sha256_pkg; + +typedef bit unsigned [31:0] a_unsigned_32_64 [63:0]; + +// Constants + +parameter a_unsigned_32_64 K = '{ 0:'h428A2F98, 1:'h71374491, 2:'hB5C0FBCF, 3:'hE9B5DBA5, 4:'h3956C25B, 5:'h59F111F1, 6:'h923F82A4, 7:'hAB1C5ED5, 8:'hD807AA98, 9:'h12835B01, 10:'h243185BE, 11:'h550C7DC3, 12:'h72BE5D74, 13:'h80DEB1FE, 14:'h9BDC06A7, 15:'hC19BF174, 16:'hE49B69C1, 17:'hEFBE4786, 18:'hFC19DC6, 19:'h240CA1CC, 20:'h2DE92C6F, 21:'h4A7484AA, 22:'h5CB0A9DC, 23:'h76F988DA, 24:'h983E5152, 25:'hA831C66D, 26:'hB00327C8, 27:'hBF597FC7, 28:'hC6E00BF3, 29:'hD5A79147, 30:'h6CA6351, 31:'h14292967, 32:'h27B70A85, 33:'h2E1B2138, 34:'h4D2C6DFC, 35:'h53380D13, 36:'h650A7354, 37:'h766A0ABB, 38:'h81C2C92E, 39:'h92722C85, 40:'hA2BFE8A1, 41:'hA81A664B, 42:'hC24B8B70, 43:'hC76C51A3, 44:'hD192E819, 45:'hD6990624, 46:'hF40E3585, 47:'h106AA070, 48:'h19A4C116, 49:'h1E376C08, 50:'h2748774C, 51:'h34B0BCB5, 52:'h391C0CB3, 53:'h4ED8AA4A, 54:'h5B9CCA4F, 55:'h682E6FF3, 56:'h748F82EE, 57:'h78A5636F, 58:'h84C87814, 59:'h8CC70208, 60:'h90BEFFFA, 61:'hA4506CEB, 62:'hBEF9A3F7, 63:'hC67178F2 }; + + +// Functions + +function bit unsigned [31:0] Summ(bit unsigned [31:0] x, bit unsigned [31:0] y, bit unsigned [31:0] z, bit unsigned [31:0] m, bit unsigned [31:0] e); + return ((((x + y) + z) + m) + e); +endfunction + +function bit unsigned [31:0] choose(bit unsigned [31:0] e, bit unsigned [31:0] f, bit unsigned [31:0] g); + return ((e & f) ^ (~e & g)); +endfunction + +function bit unsigned [31:0] compute_w(bit unsigned [31:0] m14, bit unsigned [31:0] m9, bit unsigned [31:0] m1, bit unsigned [31:0] m0); + return (((sig1(m14) + m9) + sig0(m1)) + m0); +endfunction + +function bit unsigned [31:0] majority(bit unsigned [31:0] a, bit unsigned [31:0] b, bit unsigned [31:0] c); + return ((a & (b | c)) | (b & c)); +endfunction + +function bit unsigned [31:0] mult_xor(bit unsigned [31:0] x, bit unsigned [31:0] a, bit unsigned [31:0] b, bit unsigned [31:0] c); + return ((rotr(x, a) ^ rotr(x, b)) ^ rotr(x, c)); +endfunction + +function bit unsigned [31:0] newa(bit unsigned [31:0] x, bit unsigned [31:0] y, bit unsigned [31:0] z); + return ((x + y) + z); +endfunction + +function bit unsigned [31:0] newe(bit unsigned [31:0] x, bit unsigned [31:0] y); + return (x + y); +endfunction + +function bit unsigned [31:0] past_m(bit unsigned [5:0]i,bit unsigned [31:0] m_0,bit unsigned [31:0] m_1,bit unsigned [31:0] m_2,bit unsigned [31:0] m_3,bit unsigned [31:0] m_4,bit unsigned [31:0] m_5,bit unsigned [31:0] m_6,bit unsigned [31:0] m_7,bit unsigned [31:0] m_8,bit unsigned [31:0] m_9,bit unsigned [31:0] m_10,bit unsigned [31:0] m_11,bit unsigned [31:0] m_12,bit unsigned [31:0] m_13,bit unsigned [31:0] m_14,bit unsigned [31:0] m_15); + return ((i == 'sd0 ? m_0 : (i == 'sd1) ? m_1 : (i == 'sd2) ? m_2 : (i == 'sd3) ? m_3 : (i == 'sd4) ? m_4 : (i == 'sd5) ? m_5 : (i == 'sd6) ? m_6 : (i == 'sd7) ? m_7 : (i == 'sd8) ? m_8 : (i == 'sd9) ? m_9 : (i == 'sd10) ? m_10 : (i == 'sd11) ? m_11 : (i == 'sd12) ? m_12 : (i == 'sd13) ? m_13 : (i == 'sd14) ? m_14 : m_15)); +endfunction + +function bit unsigned [31:0] rotr(bit unsigned [31:0] x, bit unsigned [31:0] n); + return ((x >> n) | (x << (32 - n))); +endfunction + +function bit unsigned [31:0] sig0(bit unsigned [31:0] x); + return ((rotr(x, 7) ^ rotr(x, 18)) ^ (x >> 3)); +endfunction + +function bit unsigned [31:0] sig1(bit unsigned [31:0] x); + return ((rotr(x, 17) ^ rotr(x, 19)) ^ (x >> 10)); +endfunction + + +endpackage diff --git a/src/sha256/formal/readme.md b/src/sha256/formal/readme.md new file mode 100644 index 000000000..fbec141be --- /dev/null +++ b/src/sha256/formal/readme.md @@ -0,0 +1,61 @@ +# SHA256 +Date: 25.07.2023 + +Author: LUBIS EDA + +## Folder Structure +The following subdirectories are part of the main directory **formal** + +- model: Contains the high level abstracted model +- properties: Contains the assertion IP(AIP) named as **fv_sha256.sv** and the constraints in place for the respective AIP **fv_constraints.sv** + + +## DUT Overview + +The DUT sha256_core has the primary inputs and primary outputs as shown below. + +| S.No | Port | Direction | Description | +| ---- | ----------------- | --------- | --------------------------------------------------------------------------------- | +| 1 | clk | input | The positive edge of the clk is used for all the signals | +| 2 | reset_n | input | The reset signal is active low and resets the core | +| 3 | zeroize | input | The core is reseted when this signal is triggered. | +| 4 | init_cmd | input | The core is initialised with respective mode constants and processes the message. | +| 5 | next_cmd | input | The core processes the message block with the previously computed results | +| 6 | mode | input | Define which hash function: SHA256,SHA224. | +| 7 | block_msg[511:0] | input | The padded block message | +| 8 | ready | output | When triggered indicates that the core is ready | +| 9 | digest[255:0] | output | The hashed value of the given message block | +| 10 | digest_valid | output | When triggered indicates that the computed digest is ready | + +When the respective mode is selected and initalised the core iterates for 63 rounds to process the hash value, if the next is triggered then the previous values of the **H** registers are in place for processing the hash value. The digest is always generated of 256 bits, in which if the mode changes to 224 then from MSB 224 bits is a valid output and rest is garbage value. +## Assertion IP Overview + +The Assertion IP signals are bound with the respective signals in the dut, where for the **rst** in binded with the DUT (reset_n && !zeroize), which ensures the reset functionality. And another AIP signal block_in_valid is triggered whenever the init or next is high. + +- reset_a: Checks that all the resgiters are resetted and the state is idle, with the ready to high. + +- DONE_to_IDLE_a: Checks the necessary registers, outputs holds the values when state transits from done to idle. + +- SHA_Rounds_to_DONE_a: Checks if the rounds are done then the registers are updated correctly. + +- SHA_Rounds_to_SHA_Rounds_before_16_a: Checks if the the rounds less than 16 then the necessary registers are updated correctly and the round increments. + +- SHA_Rounds_to_SHA_Rounds_after_16_a: Checks if the rounds are greater than 16 and less than 80 then the respective registers are updated correctly and the round increments. + +- IDLE_to_SHA_Rounds_next_a: Checks if the state is in idle and there is no init signal and the next signal asserts then the register holds the past values. + +- IDLE_to_SHA_Rounds_256_a: Checks if the state is in idle and there is init signal and the mode selected is 256. + +- IDLE_to_SHA_Rounds_224_a: Checks if the state is in idle and there is init signal and the mode selected is 224. + +- IDLE_wait_a: Checks if there isn't either init or next signal triggered in idle state then the state stays in idle and holds the past values and the core is ready. +- +## Reproduce results + +The AIP has been tested with two major FV tools. For both tools proves pass in less then 2 hour and coverage is at 100%. + +For reproducing the results: +Load the AIP, sha256_core and fv_constraints together in your formal tool. + +Feel free to reach out to contact@lubis-eda.com to request the loadscripts. + diff --git a/src/sha256/rtl/sha256_reg.rdl b/src/sha256/rtl/sha256_reg.rdl index c4fe30b74..44cbf0e76 100644 --- a/src/sha256/rtl/sha256_reg.rdl +++ b/src/sha256/rtl/sha256_reg.rdl @@ -238,8 +238,10 @@ addrmap sha256_reg { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -257,8 +259,10 @@ addrmap sha256_reg { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/sha512/formal/model/SHA512.luref b/src/sha512/formal/model/SHA512.luref deleted file mode 100644 index 262cdb555..000000000 --- a/src/sha512/formal/model/SHA512.luref +++ /dev/null @@ -1,490 +0,0 @@ -{ - "version": 17, - "module": { - "name": "SHA512", - "reset_signal": { - "signal": "(sha512_core.reset_n) && !(sha512_core.zeroize)", - "is_active_low": true - }, - "clock_signal": { - "signal": "clk", - "is_falling_edge": false - }, - "next_shift_amount": 0, - "rtl_module_name": "sha512_core", - "instance_name": "inst", - "default_assertion_duration": 1, - "default_disable_iff": "", - "reset": { - "documentation_comment": "" - }, - "additional_includes": "fv_constraints.sv", - "additional_imports": "", - "sync_macros": [ - { - "name": "SHA_Input_sync", - "datatype": "bool", - "refinement": "((sha512_core.init_cmd) || (sha512_core.next_cmd))", - "create_commitments": true, - "timing": 0, - "unused": false - } - ], - "notify_macros": [ - { - "name": "out_notify", - "datatype": "bool", - "refinement": "(sha512_core.digest_valid) && ((sha512_core.sha512_ctrl_reg==2'h0) && $past(sha512_core.sha512_ctrl_reg==2'h2) )", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Input_notify", - "datatype": "bool", - "refinement": "sha512_core.ready", - "create_commitments": true, - "timing": 0, - "unused": false - } - ], - "input_datapath_macros": [ - { - "name": "SHA_Input_sig_in", - "datatype": "sc_big_unsigned_1024", - "refinement": "sha512_core.block_msg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Input_sig_init", - "datatype": "bool", - "refinement": "sha512_core.init_cmd", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Input_sig_next", - "datatype": "bool", - "refinement": "sha512_core.next_cmd", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Input_sig_SHA_Mode", - "datatype": "signed_32", - "refinement": "if(sha512_core.mode==0)\n\treturn 224;\nelse if(sha512_core.mode==1)\n\treturn 256;\nelse if(sha512_core.mode==2)\n\treturn 384;\nelse\n\treturn 512;", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Input_sig_zeroize", - "datatype": "bool", - "refinement": "sha512_core.zeroize", - "create_commitments": true, - "timing": 0, - "unused": false - } - ], - "output_datapath_macros": [ - { - "name": "out_sig", - "datatype": "sc_big_unsigned_512", - "refinement": "sha512_core.digest", - "create_commitments": true, - "timing": 0, - "unused": false - } - ], - "state_macros": [ - { - "name": "DONE", - "datatype": "bool", - "refinement": "sha512_core.sha512_ctrl_reg==2'h2", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "IDLE", - "datatype": "bool", - "refinement": "sha512_core.sha512_ctrl_reg==2'h0", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "SHA_Rounds", - "datatype": "bool", - "refinement": "sha512_core.sha512_ctrl_reg==2'h1", - "create_commitments": true, - "timing": 0, - "unused": false - } - ], - "register_macros": [ - { - "name": "a", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.a_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "b", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.b_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "c", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.c_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "d", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.d_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "e", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.e_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "f", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.f_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "g", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.g_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "h", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.h_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_0", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H0_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_1", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H1_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_2", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H2_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_3", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H3_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_4", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H4_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_5", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H5_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_6", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H6_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "H_7", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.H7_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "i", - "datatype": "signed_32", - "refinement": "sha512_core.round_ctr_reg", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_0", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[00]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_1", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[01]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_10", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[10]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_11", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[11]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_12", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[12]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_13", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[13]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_14", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[14]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_15", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[15]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_2", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[02]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_3", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[03]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_4", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[04]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_5", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[05]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_6", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[06]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_7", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[07]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_8", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[08]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "W_9", - "datatype": "sc_big_unsigned_64", - "refinement": "sha512_core.w_mem_inst.w_mem[09]", - "create_commitments": true, - "timing": 0, - "unused": false - }, - { - "name": "MSG_digest", - "datatype": "sc_big_unsigned_512", - "refinement": "", - "create_commitments": true, - "timing": 0, - "unused": true - } - ], - "assertions": [ - { - "name": "DONE_to_IDLE", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_SHA_Rounds", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_SHA_Rounds_1", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_SHA_Rounds_2", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_SHA_Rounds_3", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_SHA_Rounds_4", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "SHA_Rounds_to_DONE", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "SHA_Rounds_to_SHA_Rounds", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "SHA_Rounds_to_SHA_Rounds_1", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": false - }, - { - "name": "IDLE_to_IDLE", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": true - }, - { - "name": "IDLE_to_SHA_Rounds_5", - "disable_iff": "", - "duration": -1, - "documentation_comment": "", - "unused": true - } - ], - "waits": [ - { - "name": "IDLE_wait", - "documentation_comment": "", - "unused": false - } - ] - } -} \ No newline at end of file diff --git a/src/sha512/formal/model/refinement.luctrl b/src/sha512/formal/model/refinement.luctrl deleted file mode 100644 index 7b7979b22..000000000 --- a/src/sha512/formal/model/refinement.luctrl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": 13, - "modules": [ - { - "name": "SHA512", - "path": "SHA512.luref" - } - ] -} \ No newline at end of file diff --git a/src/sha512/formal/model/sha512.h b/src/sha512/formal/model/sha512.h index 357080d88..4bbad71a6 100644 --- a/src/sha512/formal/model/sha512.h +++ b/src/sha512/formal/model/sha512.h @@ -1,6 +1,26 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. +// + #ifndef SHA #define SHA + #include #include "systemc.h" #include "string.h" @@ -215,6 +235,7 @@ struct SHA_Args{ sc_biguint<64>(0x431d67c49c100d4c), sc_biguint<64>(0x4cc5d4becb3e42b6), sc_biguint<64>(0x597f299cfc657e2a),\ sc_biguint<64>(0x5fcb6fab3ad6faec), sc_biguint<64>(0x6c44198c4a475817)};; + SC_MODULE(SHA512) { blocking_in SHA_Input; @@ -304,30 +325,22 @@ while(true){ W = {sc_biguint<64>(0)}; } - //next(block_in); - //W_schedule(block_in); block_copy = block_in; for (j=0; j<16; ++j) { W[15-j] = slicer(block_copy, j); }; - - //copy_digest(); + a = H[0]; b = H[1];c = H[2]; d = H[3]; e = H[4]; f = H[5];g = H[6]; h = H[7]; for (i=0; i> (MSG_digest >> sc_biguint<512>(64)); MSG_digest += static_cast> (H[j] << sc_biguint<64>(448)); } - //MSG_digest = compute_dig(static_cast>(0),H[7],H[6],H[5],H[4],H[3],H[2],H[1],H[0]); - //MSG_digest = concati(MSG_digest, H, j); - /* BYME: to comply with rtl - switch (SHA_Mode_in){ - case 224: - MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(288)); - break; - case 256: - MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(256)); - break; - case 384: - MSG_digest = static_cast> (MSG_digest >> sc_biguint<512>(128)); - break; - default: - MSG_digest = static_cast> (MSG_digest); - break; - }*/ out->master_write(static_cast> (MSG_digest)); - - //}; - - //out->write(static_cast> (MSG_digest >> static_cast>(512-SHA_Mode_in))); } + }; #endif diff --git a/src/sha512/formal/model/PriniTestBench/sc_main.cpp b/src/sha512/formal/model/tb/sc_main.cpp similarity index 100% rename from src/sha512/formal/model/PriniTestBench/sc_main.cpp rename to src/sha512/formal/model/tb/sc_main.cpp diff --git a/src/sha512/formal/model/PriniTestBench/tb.cpp b/src/sha512/formal/model/tb/tb.cpp similarity index 100% rename from src/sha512/formal/model/PriniTestBench/tb.cpp rename to src/sha512/formal/model/tb/tb.cpp diff --git a/src/sha512/formal/model/PriniTestBench/tb.h b/src/sha512/formal/model/tb/tb.h similarity index 100% rename from src/sha512/formal/model/PriniTestBench/tb.h rename to src/sha512/formal/model/tb/tb.h diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/224.txt b/src/sha512/formal/model/tb/testvectors/224.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/224.txt rename to src/sha512/formal/model/tb/testvectors/224.txt diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/256.txt b/src/sha512/formal/model/tb/testvectors/256.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/256.txt rename to src/sha512/formal/model/tb/testvectors/256.txt diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/384.txt b/src/sha512/formal/model/tb/testvectors/384.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/384.txt rename to src/sha512/formal/model/tb/testvectors/384.txt diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/384_long_msg.txt b/src/sha512/formal/model/tb/testvectors/384_long_msg.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/384_long_msg.txt rename to src/sha512/formal/model/tb/testvectors/384_long_msg.txt diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/512.txt b/src/sha512/formal/model/tb/testvectors/512.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/512.txt rename to src/sha512/formal/model/tb/testvectors/512.txt diff --git a/src/sha512/formal/model/PriniTestBench/testvectors/512_long_msg.txt b/src/sha512/formal/model/tb/testvectors/512_long_msg.txt similarity index 100% rename from src/sha512/formal/model/PriniTestBench/testvectors/512_long_msg.txt rename to src/sha512/formal/model/tb/testvectors/512_long_msg.txt diff --git a/src/sha512/formal/properties/fv_constraints.sv b/src/sha512/formal/properties/fv_constraints.sv index 2ffc12032..f250ba431 100644 --- a/src/sha512/formal/properties/fv_constraints.sv +++ b/src/sha512/formal/properties/fv_constraints.sv @@ -16,6 +16,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + module fv_constraints_m(init_cmd, next_cmd, reset_n, clk); input bit init_cmd, next_cmd, reset_n, clk; reg init_reg; @@ -31,6 +32,12 @@ default clocking default_clk @(posedge clk); endclocking !init_reg |-> !next_cmd; endproperty + + property next_only_if_digest_valid; + next_cmd |-> sha512_core.digest_valid ; + endproperty + next_only_if_digtest_valid_a: assume property (next_only_if_digest_valid); + always @ (posedge clk or negedge reset_n) begin : init_reg_order if (!reset_n) diff --git a/src/sha512/formal/properties/fv_coverpoints.sv b/src/sha512/formal/properties/fv_coverpoints.sv new file mode 100644 index 000000000..a05b9c144 --- /dev/null +++ b/src/sha512/formal/properties/fv_coverpoints.sv @@ -0,0 +1,44 @@ +// ------------------------------------------------- +// Contact: contact@lubis-eda.com +// Author: Tobias Ludwig, Michael Schwarz +// ------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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 fv_coverpoints_m( + input logic clk, + input logic reset_n +); + + default clocking default_clk @(posedge clk); endclocking + + //Cover zeroize: + //Assert zeroize input and check the status of all registers. All registers/internal memories should be cleared. + cover_zeroize: cover property(disable iff(!reset_n) sha512_core.zeroize ); + cover_zeroize_after_next: cover property(disable iff(!reset_n) sha512_core.zeroize && sha512_core.next_cmd ); + + //Cover modes: + //Cover all 4 different modes for SHA512 + cover_mode_224: cover property(disable iff(!reset_n) sha512_core.mode == 0 && sha512_core.init_cmd ); + cover_mode_256: cover property(disable iff(!reset_n) sha512_core.mode == 1 && sha512_core.init_cmd ); + cover_mode_384: cover property(disable iff(!reset_n) sha512_core.mode == 2 && sha512_core.init_cmd ); + cover_mode_512: cover property(disable iff(!reset_n) sha512_core.mode == 3 && sha512_core.init_cmd ); + + +endmodule +bind sha512_core fv_coverpoints_m fv_coverpoints( + .clk(clk), + .reset_n(reset_n) +); \ No newline at end of file diff --git a/src/sha512/formal/properties/fv_sha512.sv b/src/sha512/formal/properties/fv_sha512.sv index f36f06ff0..6d3030f49 100644 --- a/src/sha512/formal/properties/fv_sha512.sv +++ b/src/sha512/formal/properties/fv_sha512.sv @@ -24,7 +24,7 @@ module fv_sha_512_m( input bit rst, input bit clk, input bit unsigned [1023:0] block_in, - input bit unsigned [31:0] block_sha_mode, + input bit signed [31:0] block_sha_mode, input bit block_init, input bit block_next, input bit block_zeroize, @@ -172,8 +172,8 @@ property DONE_to_IDLE_p; endproperty -IDLE_to_SHA_Rounds_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_p); -property IDLE_to_SHA_Rounds_p; +IDLE_to_SHA_Rounds_224_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_224_p); +property IDLE_to_SHA_Rounds_224_p; IDLE && block_in_valid && block_init && @@ -219,8 +219,8 @@ property IDLE_to_SHA_Rounds_p; endproperty -IDLE_to_SHA_Rounds_1_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_1_p); -property IDLE_to_SHA_Rounds_1_p; +IDLE_to_SHA_Rounds_256_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_256_p); +property IDLE_to_SHA_Rounds_256_p; IDLE && block_in_valid && block_init && @@ -266,8 +266,8 @@ property IDLE_to_SHA_Rounds_1_p; endproperty -IDLE_to_SHA_Rounds_2_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_2_p); -property IDLE_to_SHA_Rounds_2_p; +IDLE_to_SHA_Rounds_512_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_512_p); +property IDLE_to_SHA_Rounds_512_p; IDLE && block_in_valid && block_init && @@ -313,14 +313,12 @@ property IDLE_to_SHA_Rounds_2_p; endproperty -IDLE_to_SHA_Rounds_3_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_3_p); -property IDLE_to_SHA_Rounds_3_p; +IDLE_to_SHA_Rounds_384_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_384_p); +property IDLE_to_SHA_Rounds_384_p; IDLE && block_in_valid && block_init && - (block_sha_mode != 'sd224) && - (block_sha_mode != 'sd256) && - (block_sha_mode != 'sd512) + block_sha_mode == 'sd384 |-> ##1 (block_in_ready == 0) and ##1 (digest_valid == 0) and @@ -362,8 +360,8 @@ property IDLE_to_SHA_Rounds_3_p; endproperty -IDLE_to_SHA_Rounds_4_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_4_p); -property IDLE_to_SHA_Rounds_4_p; +IDLE_to_SHA_Rounds_next_a: assert property (disable iff(!rst) IDLE_to_SHA_Rounds_next_p); +property IDLE_to_SHA_Rounds_next_p; IDLE && block_in_valid && !block_init @@ -411,7 +409,6 @@ endproperty SHA_Rounds_to_DONE_a: assert property (disable iff(!rst) SHA_Rounds_to_DONE_p); property SHA_Rounds_to_DONE_p; SHA_Rounds && - (i >= 'sd16) && (('sd1 + i) >= 'sd80) |-> ##1 (block_in_ready == 0) and @@ -454,7 +451,7 @@ property SHA_Rounds_to_DONE_p; endproperty -SHA_Rounds_to_SHA_Rounds_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_p); +SHA_Rounds_to_SHA_Rounds_before_16_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_p); property SHA_Rounds_to_SHA_Rounds_p; SHA_Rounds && (i < 'sd16) @@ -499,7 +496,7 @@ property SHA_Rounds_to_SHA_Rounds_p; endproperty -SHA_Rounds_to_SHA_Rounds_1_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_1_p); +SHA_Rounds_to_SHA_Rounds_after_16_a: assert property (disable iff(!rst) SHA_Rounds_to_SHA_Rounds_1_p); property SHA_Rounds_to_SHA_Rounds_1_p; SHA_Rounds && (i >= 'sd16) && @@ -593,52 +590,52 @@ endproperty endmodule bind sha512_core fv_sha_512_m fv_sha512( - .rst((sha512_core.reset_n) && !(sha512_core.zeroize)), - .clk(sha512_core.clk), - .block_in(sha512_core.block_msg), - .block_sha_mode(get_block_sha_mode(sha512_core.mode)), - .block_init(sha512_core.init_cmd), - .block_next(sha512_core.next_cmd), - .block_zeroize(sha512_core.zeroize), - .digest_out(sha512_core.digest), - .block_in_valid(((sha512_core.init_cmd) || (sha512_core.next_cmd))), - .block_in_ready(sha512_core.ready), - .digest_valid((sha512_core.digest_valid) ), - .H_0(sha512_core.H0_reg), - .H_1(sha512_core.H1_reg), - .H_2(sha512_core.H2_reg), - .H_3(sha512_core.H3_reg), - .H_4(sha512_core.H4_reg), - .H_5(sha512_core.H5_reg), - .H_6(sha512_core.H6_reg), - .H_7(sha512_core.H7_reg), - .W_0(sha512_core.w_mem_inst.w_mem[00]), - .W_1(sha512_core.w_mem_inst.w_mem[01]), - .W_2(sha512_core.w_mem_inst.w_mem[02]), - .W_3(sha512_core.w_mem_inst.w_mem[03]), - .W_4(sha512_core.w_mem_inst.w_mem[04]), - .W_5(sha512_core.w_mem_inst.w_mem[05]), - .W_6(sha512_core.w_mem_inst.w_mem[06]), - .W_7(sha512_core.w_mem_inst.w_mem[07]), - .W_8(sha512_core.w_mem_inst.w_mem[08]), - .W_9(sha512_core.w_mem_inst.w_mem[09]), - .W_10(sha512_core.w_mem_inst.w_mem[10]), - .W_11(sha512_core.w_mem_inst.w_mem[11]), - .W_12(sha512_core.w_mem_inst.w_mem[12]), - .W_13(sha512_core.w_mem_inst.w_mem[13]), - .W_14(sha512_core.w_mem_inst.w_mem[14]), - .W_15(sha512_core.w_mem_inst.w_mem[15]), - .a(sha512_core.a_reg), - .b(sha512_core.b_reg), - .c(sha512_core.c_reg), - .d(sha512_core.d_reg), - .e(sha512_core.e_reg), - .f(sha512_core.f_reg), - .g(sha512_core.g_reg), - .h(sha512_core.h_reg), - .i(sha512_core.round_ctr_reg), - .IDLE(sha512_core.sha512_ctrl_reg==2'h0), - .SHA_Rounds(sha512_core.sha512_ctrl_reg==2'h1), - .DONE(sha512_core.sha512_ctrl_reg==2'h2) + .rst((reset_n) && !(zeroize)), + .clk(clk), + .block_in(block_msg), + .block_sha_mode((mode==0)?224:(mode==1)?256:(mode==2)?384:512), + .block_init(init_cmd), + .block_next(next_cmd), + .block_zeroize(zeroize), + .digest_out(digest), + .block_in_valid(((init_cmd) || (next_cmd))), + .block_in_ready(ready), + .digest_valid((digest_valid) ), + .H_0(H0_reg), + .H_1(H1_reg), + .H_2(H2_reg), + .H_3(H3_reg), + .H_4(H4_reg), + .H_5(H5_reg), + .H_6(H6_reg), + .H_7(H7_reg), + .W_0(w_mem_inst.w_mem[00]), + .W_1(w_mem_inst.w_mem[01]), + .W_2(w_mem_inst.w_mem[02]), + .W_3(w_mem_inst.w_mem[03]), + .W_4(w_mem_inst.w_mem[04]), + .W_5(w_mem_inst.w_mem[05]), + .W_6(w_mem_inst.w_mem[06]), + .W_7(w_mem_inst.w_mem[07]), + .W_8(w_mem_inst.w_mem[08]), + .W_9(w_mem_inst.w_mem[09]), + .W_10(w_mem_inst.w_mem[10]), + .W_11(w_mem_inst.w_mem[11]), + .W_12(w_mem_inst.w_mem[12]), + .W_13(w_mem_inst.w_mem[13]), + .W_14(w_mem_inst.w_mem[14]), + .W_15(w_mem_inst.w_mem[15]), + .a(a_reg), + .b(b_reg), + .c(c_reg), + .d(d_reg), + .e(e_reg), + .f(f_reg), + .g(g_reg), + .h(h_reg), + .i(round_ctr_reg), + .IDLE(sha512_ctrl_reg==2'h0), + .SHA_Rounds(sha512_ctrl_reg==2'h1), + .DONE(sha512_ctrl_reg==2'h2) ); diff --git a/src/sha512/formal/properties/fv_sha512_pkg.sv b/src/sha512/formal/properties/fv_sha512_pkg.sv index 45ab5eb0c..da402d0a2 100644 --- a/src/sha512/formal/properties/fv_sha512_pkg.sv +++ b/src/sha512/formal/properties/fv_sha512_pkg.sv @@ -38,6 +38,7 @@ function bit unsigned [63:0] Maj(bit unsigned [63:0] x, bit unsigned [63:0] y, b return (((x & y) ^ (x & z)) ^ (y & z)); endfunction + function bit unsigned [63:0] T1(bit unsigned [63:0] e, bit unsigned [63:0] f, bit unsigned [63:0] g, bit unsigned [63:0] h, bit unsigned [63:0] k, bit unsigned [63:0] w); return 64'(((((h + sigma1(e)) + Ch(e, f, g)) + k) + w)); endfunction @@ -143,41 +144,7 @@ function bit unsigned [63:0] sigma1(bit unsigned [63:0] x); endfunction function bit unsigned [63:0] slicer(bit unsigned [1023:0] block, bit signed [31:0] index); - if ((index == 'sd0)) - return 64'((block >> 1024'd0)); - else if ((index == 'sd1)) - return 64'((block >> 1024'd64)); - else if ((index == 'sd2)) - return 64'((block >> 1024'd128)); - else if ((index == 'sd3)) - return 64'((block >> 1024'd192)); - else if ((index == 'sd4)) - return 64'((block >> 1024'd256)); - else if ((index == 'sd5)) - return 64'((block >> 1024'd320)); - else if ((index == 'sd6)) - return 64'((block >> 1024'd384)); - else if ((index == 'sd7)) - return 64'((block >> 1024'd448)); - else if ((index == 'sd8)) - return 64'((block >> 1024'd512)); - else if ((index == 'sd9)) - return 64'((block >> 1024'd576)); - else if ((index == 'sd10)) - return 64'((block >> 1024'd640)); - else if ((index == 'sd11)) - return 64'((block >> 1024'd704)); - else if ((index == 'sd12)) - return 64'((block >> 1024'd768)); - else if ((index == 'sd13)) - return 64'((block >> 1024'd832)); - else if ((index == 'sd14)) - return 64'((block >> 1024'd896)); - else if ((index == 'sd15)) - return 64'((block >> 1024'd960)); - else - return 64'((block >> 1024'd960)); + return(block[(64*index)+:64]); endfunction - endpackage diff --git a/src/sha512/formal/readme.md b/src/sha512/formal/readme.md index 8bfb89433..fce56dd87 100644 --- a/src/sha512/formal/readme.md +++ b/src/sha512/formal/readme.md @@ -29,44 +29,36 @@ The DUT sha512_core has the primary inputs and primary outputs as shown below. When the respective mode is selected and initalised the core iterates for 80 rounds to process the hash value, if the next is triggered then the previous values of the **H** registers are in place for processing the hash value. The digest is always generated of 512 bits, in which if the mode changes to 384 then from MSB 384 bits is a valid output and rest is garbage value. ## Assertion IP Overview -The Assertion IP signals are bound with the respective signals in the dut, where for the **rst** reset_n && !zeroize is used, which ensures the reset functionality. And another AIP signal block_in_valid is triggered whenever the init or next is high. +The Assertion IP signals are bound with the respective signals in the dut, where for the **rst** in binded with the DUT (reset_n && !zeroize), which ensures the reset functionality. And another AIP signal block_in_valid is triggered whenever the init or next is high. - reset_a: Checks that all the resgiters are resetted and the state is idle, with the ready to high. - DONE_to_IDLE_a: Checks the necessary registers,outputs holds the values when state transits from Done to idle, -- IDLE_to_SHA_Rounds_a: Checks if the state is in idle ,the mode choosen as 224,the init is triggered then the registers should be initialised with the respective constants of 224. +- IDLE_to_SHA_Rounds_224_a: Checks if the state is in idle ,the mode choosen as 224,the init is triggered then the registers should be initialised with the respective constants of 224. -- IDLE_to_SHA_Rounds_1_a: Checks if the state is in idle ,the mode choosen as 256,the init is triggered then the registers should be initialised with the respective constants of 256. +- IDLE_to_SHA_Rounds_256_a: Checks if the state is in idle ,the mode choosen as 256,the init is triggered then the registers should be initialised with the respective constants of 256. -- IDLE_to_SHA_Rounds_2_a: Checks if the state is in idle ,the mode choosen as 512,the init is triggered then the registers should be initialised with the respective constants of 512. +- IDLE_to_SHA_Rounds_512_a: Checks if the state is in idle ,the mode choosen as 512,the init is triggered then the registers should be initialised with the respective constants of 512. -- IDLE_to_SHA_Rounds_3_a: Checks if the state is in idle ,the mode choosen is neither 512,256 nor 224,the init is triggered then the registers should be initialised with the respective constants of default, which covers 384 mode also. +- IDLE_to_SHA_Rounds_384_a: Checks if the state is in idle ,the mode choosen is neither 512,256 nor 224,the init is triggered then the registers should be initialised with the respective constants of default, which covers 384 mode also. -- IDLE_to_SHA_Rounds_4_a: Checks if the state is in idle and there is no init signal and the next signal asserts then the register holds the past values. +- IDLE_to_SHA_Rounds_next_a: Checks if the state is in idle and there is no init signal and the next signal asserts then the register holds the past values. - SHA_Rounds_to_DONE_a: Checks if the rounds are done then the registers are updated correctly. -- SHA_Rounds_to_SHA_Rounds_a: Checks if the the rounds less than 16 then the necessary registers are updated correctly and the round increments. +- SHA_Rounds_to_SHA_Rounds_before_16a: Checks if the the rounds less than 16 then the necessary registers are updated correctly and the round increments. -- SHA_Rounds_to_SHA_Rounds_1_a: Checks if the rounds are greater than 16 and less than 80 then the respective registers are updated correctly and the round increments. +- SHA_Rounds_to_SHA_Rounds_after_16a_a: Checks if the rounds are greater than 16 and less than 80 then the respective registers are updated correctly and the round increments. - IDLE_wait_a: Checks if there isn't either init or next signal triggered in idle state then the state stays in idle and holds the past values and the core is ready. -- -## Loading the AIP -For onespin:
- 1. Open onespin, select file, run source.
- 2. Select the prove.tcl in onespin folder for running the properties.
+## Reproduce results -For VCformal:
- 1. Navigate to the vcf folder containing tcl scripts.
- 2. open terminal
- 3. run the cmd vcf -f prove.tcl (for running the properties).
+The AIP has been tested with two major FV tools. For both tools proves pass in less then 2 hour and coverage is at 100%. -For JasperGold: - 1. Open Jaspergold, click on file -> Tcl scripts -> Source.
- 2. Now Navigate to the script location and select the prove.tcl.
- 3. All the checkers and constraints would be loaded to the interface, right click on them and click on prove task.
+For reproducing the results: +Load the AIP, sha512_core and fv_constraints together in your formal tool. +Feel free to reach out to contact@lubis-eda.com to request the loadscripts. diff --git a/src/sha512/rtl/sha512_reg.rdl b/src/sha512/rtl/sha512_reg.rdl index 71ec241ae..ae222e04c 100644 --- a/src/sha512/rtl/sha512_reg.rdl +++ b/src/sha512/rtl/sha512_reg.rdl @@ -280,8 +280,10 @@ addrmap sha512_reg { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -299,8 +301,10 @@ addrmap sha512_reg { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -467,4 +471,4 @@ addrmap sha512_reg { * Register File instance * ----------------------- */ intr_block_t intr_block_rf @0x800; -}; \ No newline at end of file +}; diff --git a/src/sha512/uvmf_sha512/config/uvmf_sha512.vf b/src/sha512/uvmf_sha512/config/uvmf_sha512.vf new file mode 100644 index 000000000..595312dde --- /dev/null +++ b/src/sha512/uvmf_sha512/config/uvmf_sha512.vf @@ -0,0 +1,135 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512/coverage ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/../rtl ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/../../libs/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/src ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/src ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/environment_packages/SHA512_env_pkg ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/tests ++incdir+${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_if.sv +${CALIPTRA_ROOT}/src/sha512/coverage/sha512_ctrl_cov_bind.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/SHA512_in_pkg_hdl.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/SHA512_in_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/src/SHA512_in_driver_bfm.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/src/SHA512_in_if.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_in_pkg/src/SHA512_in_monitor_bfm.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/SHA512_out_pkg_hdl.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/SHA512_out_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/src/SHA512_out_driver_bfm.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/src/SHA512_out_if.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/interface_packages/SHA512_out_pkg/src/SHA512_out_monitor_bfm.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/verification_ip/environment_packages/SHA512_env_pkg/SHA512_env_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/parameters/SHA512_parameters_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/sequences/SHA512_sequences_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/tests/SHA512_tests_pkg.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv \ No newline at end of file diff --git a/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hdl_top.sv b/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hdl_top.sv index bf5448523..ff20cae1d 100644 --- a/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hdl_top.sv +++ b/src/sha512/uvmf_sha512/uvmf_template_output/project_benches/SHA512/tb/testbench/hdl_top.sv @@ -110,6 +110,8 @@ import uvmf_base_pkg_hdl::*; .notif_intr(), .debugUnlock_or_scan_mode_switch('0) ); + +sha512_ctrl_cov_bind i_sha512_ctrl_cov_bind(); // pragma uvmf custom dut_instantiation end initial begin // tbx vif_binding_block diff --git a/src/soc_ifc/coverage/soc_ifc_cov_if.sv b/src/soc_ifc/coverage/soc_ifc_cov_if.sv index 74d9d4177..52eac09ae 100644 --- a/src/soc_ifc/coverage/soc_ifc_cov_if.sv +++ b/src/soc_ifc/coverage/soc_ifc_cov_if.sv @@ -189,12 +189,14 @@ interface soc_ifc_cov_if soc_mbox_addr_cp: coverpoint i_soc_ifc_arb.soc_req_data.addr inside {[MBOX_REG_START_ADDR:MBOX_REG_END_ADDR]}; soc_mbox_req_ip_cp: coverpoint i_soc_ifc_arb.soc_mbox_req_ip; - soc_reg_req_ip_cp: coverpoint i_soc_ifc_arb.soc_reg_req_ip; soc_sha_req_ip_cp: coverpoint i_soc_ifc_arb.soc_sha_req_ip; + //No stall here, so arbiter never hits these. We can put these back if we ever introduce a stall + //soc_reg_req_ip_cp: coverpoint i_soc_ifc_arb.soc_reg_req_ip; uc_mbox_req_ip_cp: coverpoint i_soc_ifc_arb.uc_mbox_req_ip; - uc_reg_req_ip_cp: coverpoint i_soc_ifc_arb.uc_reg_req_ip; uc_sha_req_ip_cp: coverpoint i_soc_ifc_arb.uc_sha_req_ip; + //No stall here, so arbiter never hits these. We can put these back if we ever introduce a stall + //uc_reg_req_ip_cp: coverpoint i_soc_ifc_arb.uc_reg_req_ip; uc_mbox_reg_req_cp: coverpoint i_soc_ifc_arb.uc_mbox_reg_req; uc_mbox_dir_req_cp: coverpoint i_soc_ifc_arb.uc_mbox_dir_req; @@ -218,7 +220,8 @@ interface soc_ifc_cov_if boot_fsm_ps_cp: coverpoint i_soc_ifc_boot_fsm.boot_fsm_ps; arc_BOOT_FUSE_BOOT_DONE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_FUSE_BOOT_DONE; arc_BOOT_FUSE_BOOT_WAIT_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_FUSE_BOOT_WAIT; - arc_BOOT_DONE_BOOT_IDLE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_DONE_BOOT_IDLE; + //Not a real arc - tied off to zero + //arc_BOOT_DONE_BOOT_IDLE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_DONE_BOOT_IDLE; arc_BOOT_DONE_BOOT_FWRST_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_DONE_BOOT_FWRST; arc_BOOT_WAIT_BOOT_DONE_cp: coverpoint i_soc_ifc_boot_fsm.arc_BOOT_WAIT_BOOT_DONE; fsm_iccm_unlock_cp: coverpoint i_soc_ifc_boot_fsm.fsm_iccm_unlock; @@ -290,8 +293,8 @@ interface soc_ifc_cov_if sram_double_ecc_error_cp: coverpoint i_mbox.sram_double_ecc_error; //req hold varieties - req_hold0_cp: coverpoint i_mbox.req_dv & (i_mbox.dir_req_dv_q & ~i_mbox.req_data.write); - req_hold1_cp: coverpoint i_mbox.req_dv & (i_mbox.dir_req_dv & i_mbox.sha_sram_req_dv); + req_hold0_cp: coverpoint i_mbox.req_dv & (i_mbox.dir_req_dv_q & ~i_mbox.sha_sram_req_dv & ~i_mbox.req_data.write); + req_hold1_cp: coverpoint i_mbox.req_dv & (i_mbox.dir_req_dv & ~i_mbox.dir_req_rd_phase & i_mbox.sha_sram_req_dv); req_hold2_cp: coverpoint i_mbox.req_dv & (i_mbox.hwif_out.mbox_dataout.dataout.swacc & i_mbox.mbox_protocol_sram_rd_f); sha_sram_hold_cp: coverpoint i_mbox.sha_sram_hold; diff --git a/src/soc_ifc/rtl/caliptra_top_reg.h b/src/soc_ifc/rtl/caliptra_top_reg.h index e2c597f16..553225858 100644 --- a/src/soc_ifc/rtl/caliptra_top_reg.h +++ b/src/soc_ifc/rtl/caliptra_top_reg.h @@ -15,6 +15,7 @@ #ifndef CALIPTRA_TOP_REG_HEADER #define CALIPTRA_TOP_REG_HEADER + #define CALIPTRA_TOP_REG_BASE_ADDR (0x0) #define CALIPTRA_TOP_REG_MBOX_CSR_BASE_ADDR (0x30020000) #define CALIPTRA_TOP_REG_MBOX_CSR_MBOX_LOCK (0x30020000) @@ -542,4 +543,3 @@ #endif - diff --git a/src/soc_ifc/rtl/mbox.sv b/src/soc_ifc/rtl/mbox.sv index 2413f6954..52181b2bd 100644 --- a/src/soc_ifc/rtl/mbox.sv +++ b/src/soc_ifc/rtl/mbox.sv @@ -269,14 +269,13 @@ always_comb begin : mbox_fsm_combo end if (arc_FORCE_MBOX_UNLOCK) begin mbox_fsm_ns = MBOX_IDLE; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end MBOX_RDY_FOR_DLEN: begin if (arc_MBOX_RDY_FOR_DLEN_MBOX_RDY_FOR_DATA) begin mbox_fsm_ns = MBOX_RDY_FOR_DATA; + rst_mbox_wrptr = 1; end else if (arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR) begin mbox_fsm_ns = MBOX_ERROR; @@ -284,8 +283,6 @@ always_comb begin : mbox_fsm_combo end if (arc_FORCE_MBOX_UNLOCK) begin mbox_fsm_ns = MBOX_IDLE; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end @@ -312,8 +309,6 @@ always_comb begin : mbox_fsm_combo mbox_fsm_ns = MBOX_IDLE; inc_wrptr = 0; inc_rdptr = 0; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end @@ -326,8 +321,6 @@ always_comb begin : mbox_fsm_combo inc_wrptr = hwif_out.mbox_datain.datain.swmod & ~req_data.soc_req; if (arc_MBOX_EXECUTE_UC_MBOX_IDLE) begin mbox_fsm_ns = MBOX_IDLE; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; end else if (arc_MBOX_EXECUTE_UC_MBOX_EXECUTE_SOC) begin mbox_fsm_ns = MBOX_EXECUTE_SOC; @@ -342,8 +335,6 @@ always_comb begin : mbox_fsm_combo mbox_fsm_ns = MBOX_IDLE; inc_wrptr = 0; inc_rdptr = 0; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end @@ -356,8 +347,6 @@ always_comb begin : mbox_fsm_combo inc_rdptr = (dmi_inc_rdptr | (hwif_out.mbox_dataout.dataout.swacc & req_data.soc_req & valid_receiver)); if (arc_MBOX_EXECUTE_SOC_MBOX_IDLE) begin mbox_fsm_ns = MBOX_IDLE; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; end else if (arc_MBOX_EXECUTE_SOC_MBOX_EXECUTE_UC) begin mbox_fsm_ns = MBOX_EXECUTE_UC; @@ -372,8 +361,6 @@ always_comb begin : mbox_fsm_combo mbox_fsm_ns = MBOX_IDLE; inc_wrptr = 0; inc_rdptr = 0; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end @@ -381,8 +368,6 @@ always_comb begin : mbox_fsm_combo mbox_protocol_error_nxt = '{default: 0}; if (arc_FORCE_MBOX_UNLOCK) begin mbox_fsm_ns = MBOX_IDLE; - rst_mbox_wrptr = 1; - rst_mbox_rdptr = 1; mbox_protocol_error_nxt = '{default: 0}; end end @@ -415,6 +400,7 @@ always_ff @(posedge clk or negedge rst_b) begin mbox_wr_full <= '0; mbox_rdptr <= '0; mbox_rd_full <= '0; + mbox_rd_valid_f <= '0; mbox_protocol_sram_rd_f <= '0; dlen_in_dws <= '0; mbox_protocol_error <= '0; @@ -451,8 +437,11 @@ always_comb dir_req_dv_q = (dir_req_dv & ~dir_req_rd_phase & hwif_out.mbox_lock. always_comb dir_req_wr_ph = dir_req_dv_q & ~sha_sram_req_dv & req_data.write; always_comb dir_req_addr = sha_sram_req_dv ? sha_sram_req_addr : req_data.addr[$clog2(DEPTH)+1:2]; -always_comb req_hold = (dir_req_dv_q & ~req_data.write) | - (dir_req_dv & sha_sram_req_dv) | + //Direct read from uC, stall 1 clock dv_q will be de-asserted second clock +always_comb req_hold = (dir_req_dv_q & ~sha_sram_req_dv & ~req_data.write) | + //Direct access from uC while sha accelerator is reading + (dir_req_dv & ~dir_req_rd_phase & sha_sram_req_dv) | + //in an update cycle for dataout register (hwif_out.mbox_dataout.dataout.swacc & mbox_protocol_sram_rd_f); always_comb sha_sram_hold = 1'b0; @@ -598,7 +587,7 @@ mbox_csr1( ); `CALIPTRA_ASSERT_MUTEX(ERR_MBOX_ACCESS_MUTEX, {dir_req_dv_q , mbox_protocol_sram_we , mbox_protocol_sram_rd }, clk, rst_b) -`CALIPTRA_ASSERT_MUTEX(ERR_MBOX_DIR_SHA_COLLISION, {dir_req_dv, sha_sram_req_dv}, clk, rst_b) +//`CALIPTRA_ASSERT_MUTEX(ERR_MBOX_DIR_SHA_COLLISION, {dir_req_dv, sha_sram_req_dv}, clk, rst_b) `CALIPTRA_ASSERT_NEVER(ERR_MBOX_DIR_REQ_FROM_SOC, (dir_req_dv & req_data.soc_req), clk, rst_b) endmodule diff --git a/src/soc_ifc/rtl/sha512_acc_csr.rdl b/src/soc_ifc/rtl/sha512_acc_csr.rdl index 4d8479077..903d247cd 100644 --- a/src/soc_ifc/rtl/sha512_acc_csr.rdl +++ b/src/soc_ifc/rtl/sha512_acc_csr.rdl @@ -125,8 +125,10 @@ addrmap sha512_acc_csr { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -145,8 +147,10 @@ addrmap sha512_acc_csr { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv b/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv index e5b522184..e0efcfad1 100644 --- a/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +++ b/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv @@ -230,9 +230,9 @@ always_ff @(posedge clk or negedge cptra_pwrgood) begin end //protect resets during scan mode -//TODO dft override for reset? -assign cptra_noncore_rst_b = cptra_noncore_rst_b_nq | scan_mode; -assign cptra_uc_rst_b = cptra_uc_rst_b_nq | scan_mode; +//utilize warm reset pin to drive reset during scan mode +assign cptra_noncore_rst_b = scan_mode ? cptra_rst_b : cptra_noncore_rst_b_nq; +assign cptra_uc_rst_b = scan_mode ? cptra_rst_b : cptra_uc_rst_b_nq; //uC reset generation always_ff @(posedge clk or negedge cptra_rst_b) begin @@ -269,7 +269,7 @@ caliptra_2ff_sync #(.WIDTH(1), .RST_VAL('d1)) i_rst_window_sync (.clk(clk), .rst `CALIPTRA_ASSERT_KNOWN(ERR_UC_FWRST_X, cptra_uc_rst_b, clk, cptra_rst_b) //Reset got asserted, but cptra rst window wasn't asserted to protect RDC -`CALIPTRA_ASSERT_NEVER(ERR_RST_ASSERT_NO_WINDOW, $fell(cptra_noncore_rst_b) && ~rdc_clk_dis, clk, cptra_pwrgood) -`CALIPTRA_ASSERT_NEVER(ERR_UC_RST_ASSERT_NO_WINDOW, $fell(cptra_uc_rst_b) && ~(fw_update_rst_window || rdc_clk_dis), clk, cptra_pwrgood) +`CALIPTRA_ASSERT_NEVER(ERR_RST_ASSERT_NO_WINDOW, $fell(cptra_noncore_rst_b) && ~rdc_clk_dis, clk, (cptra_pwrgood && ~scan_mode)) +`CALIPTRA_ASSERT_NEVER(ERR_UC_RST_ASSERT_NO_WINDOW, $fell(cptra_uc_rst_b) && ~(fw_update_rst_window || rdc_clk_dis), clk, (cptra_pwrgood && ~scan_mode)) endmodule diff --git a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl index bd3aa0ac3..e4a50e083 100644 --- a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl +++ b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl @@ -16,7 +16,12 @@ // SOC-Facing Registers reg { name = "Hardware Error Fatal"; - desc = "Indicates fatal hardware error. + desc = "Indicates fatal hardware error. Assertion of any bit in this + register results in the assertion of the SoC interrupt pin, + cptra_error_fatal, unless that bit is masked using the internal + mask register. After the output interrupt is asserted, clearing + the bit in this register will not cause the interrupt to deassert. + Only a Caliptra reset will clear the fatal error interrupt. [br]Caliptra Access: RW1C [br]SOC Access: RW1C"; rw_rw_sticky_hw iccm_ecc_unc=0; /* Uncorrectable double-bit error in ICCM */ @@ -25,7 +30,21 @@ reg { } CPTRA_HW_ERROR_FATAL; reg { name = "Hardware Error Non-Fatal"; - desc = "Indicates non-fatal hardware error. + desc = "Indicates non-fatal hardware error. Assertion of any bit in this + register results in the assertion of the SoC interrupt pin, + cptra_error_non_fatal, unless that bit is masked using the internal + mask register. After the output interrupt is asserted, any + change by firmware that results in all set non-fatal errors + being masked will immediately deassert the interrupt output. This means + that firmware may cause the cptra_error_non_fatal signal to deassert by + writing to any of these registers, if the write results in all error + bits being cleared or masked: + [br][list] + [br] [*] CPTRA_HW_ERROR_NON_FATAL + [br] [*] CPTRA_FW_ERROR_NON_FATAL + [br] [*] internal_hw_error_non_fatal_mask + [br] [*] internal_fw_error_non_fatal_mask + [/list] [br]Caliptra Access: RW1C [br]SOC Access: RW1C"; rw_rw_sticky_hw mbox_prot_no_lock=0; /* SOC access while not locked */ @@ -34,14 +53,33 @@ reg { } CPTRA_HW_ERROR_NON_FATAL; reg { name = "Firmware Error Fatal"; - desc = "Indicates fatal firmware error. + desc = "Indicates fatal firmware error. Assertion of any bit in this + register results in the assertion of the SoC interrupt pin, + cptra_error_fatal, unless that bit is masked using the internal + mask register. After the output interrupt is asserted, clearing + the bit in this register will not cause the interrupt to deassert. + Only a Caliptra reset will clear the fatal error interrupt. [br]Caliptra Access: RW [br]SOC Access: RW"; rw_rw_sticky error_code[32]=0; } CPTRA_FW_ERROR_FATAL; reg { name = "Firmware Error Non-Fatal"; - desc = "Indicates non-fatal firmware error. + desc = "Indicates non-fatal firmware error. Assertion of any bit in this + register results in the assertion of the SoC interrupt pin, + cptra_error_non_fatal, unless that bit is masked using the internal + mask register. After the output interrupt is asserted, any + change by firmware that results in all set non-fatal errors + being masked will immediately deassert the interrupt output. This means + that firmware may cause the cptra_error_non_fatal signal to deassert by + writing to any of these registers, if the write results in all error + bits being cleared or masked: + [br][list] + [br] [*] CPTRA_HW_ERROR_NON_FATAL + [br] [*] CPTRA_FW_ERROR_NON_FATAL + [br] [*] internal_hw_error_non_fatal_mask + [br] [*] internal_fw_error_non_fatal_mask + [/list] [br]Caliptra Access: RW [br]SOC Access: RW"; rw_rw_sticky error_code[32]=0; @@ -226,6 +264,14 @@ reg { reg { name = "DEBUG & MANUF SERVICE REG"; desc = "JTAG in debug/manuf mode or SOC can write to this register for ROM/FW defined skips or services; ROM/FW maintains the defintion of these bits. + [br] + [br]Field decode: + [br] [lb]0[rb] MFG_FLAG_GEN_IDEV_CSR: Enable bit for Caliptra to generate an IDEV CSR + [br] [lb]1[rb] MFG_FLAG_RNG_UNAVAIL: Random Number Generator Unavailable + [br] [lb]15:2[rb] MFG_FLAG_RSVD + [br] [lb]30:16[rb] FAKE_ROM_RSVD + [br] [lb]31[rb] FAKE_ROM_IMAGE_VERIFY_EN: Enable bit to perform image verification within the fake-rom feature + [br] [br]Caliptra Access: RW [br]SOC Access: RW [br]TAP Access [in debug/manuf mode]: RW"; @@ -388,4 +434,4 @@ reg { name = "Caliptra Reserved Registers"; desc = "Set of reserved registers for survivability"; field {sw=rw; resetsignal=cptra_rst_b;} RSVD[32]=0; - } CPTRA_RSVD_REG[2]; \ No newline at end of file + } CPTRA_RSVD_REG[2]; diff --git a/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl b/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl index 47d8b1c75..7db011708 100644 --- a/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl +++ b/src/soc_ifc/rtl/soc_ifc_internal_reg.rdl @@ -70,9 +70,16 @@ reg { desc = "Bit mask for the register CPTRA_HW_ERROR_FATAL to determine which bits are disabled for interrupt generation on the cptra_error_fatal output signal. - A value of 1 in a field of this register means the corresponding bit + [br]A value of 1 in a field of this register means the corresponding bit position in CPTRA_HW_ERROR_FATAL will not produce an interrupt - output assertion. + output assertion. If a hardware error bit is set and was previously + masked, and firmware performs a write to clear the corresponding mask + bit in this register, the interrupt output will not be asserted. Only + the same error condition reoccurring while it is unmasked will cause + a new assertion of the interrupt output. + [br]Firmware can not cause the interrupt output to deassert by setting + mask bits for fatal error conditions that have already triggered the + interrupt. [br]Caliptra Access: RW [br]SOC Access: RO"; rw_ro_hw mask_iccm_ecc_unc=0; /* Uncorrectable double-bit error in ICCM */ @@ -84,9 +91,24 @@ reg { desc = "Bit mask for the register CPTRA_HW_ERROR_NON_FATAL to determine which bits are disabled for interrupt generation on the cptra_error_non_fatal output signal. - A value of 1 in a field of this register means the corresponding bit + [br]A value of 1 in a field of this register means the corresponding bit position in CPTRA_HW_ERROR_NON_FATAL will not produce an interrupt - output assertion. + output assertion. If a hardware error bit is set that was previously + masked, and firmware performs a write to clear the corresponding mask + bit in this register, the interrupt output will not be asserted. Only + the same error condition reoccurring while it is unmasked will cause + a new assertion of the interrupt output. + [br]Any change by firmware that results in all set non-fatal errors + being masked will immediately deassert the interrupt output. This means + that firmware may cause the cptra_error_non_fatal signal to deassert by + writing to any of these registers, if the write results in all error + bits being cleared or masked: + [br][list] + [br] [*] CPTRA_HW_ERROR_NON_FATAL + [br] [*] CPTRA_FW_ERROR_NON_FATAL + [br] [*] internal_hw_error_non_fatal_mask + [br] [*] internal_fw_error_non_fatal_mask + [/list] [br]Caliptra Access: RW [br]SOC Access: RO"; rw_ro_hw mask_mbox_prot_no_lock=0; /* SOC access while not locked */ @@ -98,9 +120,16 @@ reg { desc = "Bit mask for the register CPTRA_FW_ERROR_FATAL to determine which bits are disabled for interrupt generation on the cptra_error_fatal output signal. - A value of 1 in a field of this register means the corresponding bit + [br]A value of 1 in a field of this register means the corresponding bit position in CPTRA_FW_ERROR_FATAL will not produce an interrupt - output assertion. + output assertion. If a firmware error bit is set and was previously + masked, and firmware performs a write to clear the corresponding mask + bit in this register, the interrupt output will not be asserted. Only + the same error bit being cleared then set again while it is unmasked will cause + a new assertion of the interrupt output. + [br]Firmware can not cause the interrupt output to deassert by setting + mask bits for fatal error conditions that have already triggered the + interrupt. [br]Caliptra Access: RW [br]SOC Access: RO"; rw_ro_hw mask[32]=0; @@ -110,9 +139,24 @@ reg { desc = "Bit mask for the register CPTRA_FW_ERROR_NON_FATAL to determine which bits are disabled for interrupt generation on the cptra_error_non_fatal output signal. - A value of 1 in a field of this register means the corresponding bit + [br]A value of 1 in a field of this register means the corresponding bit position in CPTRA_FW_ERROR_NON_FATAL will not produce an interrupt - output assertion. + output assertion. If a firmware error bit is set that was previously + masked, and firmware performs a write to clear the corresponding mask + bit in this register, the interrupt output will not be asserted. Only + the same error bit being cleared then set again while it is unmasked will cause + a new assertion of the interrupt output. + [br]Any change by firmware that results in all set non-fatal errors + being masked will immediately deassert the interrupt output. This means + that firmware may cause the cptra_error_non_fatal signal to deassert by + writing to any of these registers, if the write results in all error + bits being cleared or masked: + [br][list] + [br] [*] CPTRA_HW_ERROR_NON_FATAL + [br] [*] CPTRA_FW_ERROR_NON_FATAL + [br] [*] internal_hw_error_non_fatal_mask + [br] [*] internal_fw_error_non_fatal_mask + [/list] [br]Caliptra Access: RW [br]SOC Access: RO"; rw_ro_hw mask[32]=0; @@ -306,8 +350,10 @@ regfile intr_block_t { reg error_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; @@ -329,8 +375,10 @@ regfile intr_block_t { reg notif_intr_trig_t { name = "Interrupt Trigger Register type definition"; desc = "Single bit for each interrupt event allows SW to manually - trigger occurrence of that event. Upon SW write, the bit - will pulse for 1 cycle then clear to 0."; + trigger occurrence of that event. Upon SW write, the trigger bit + will pulse for 1 cycle then clear to 0. The pulse on the + trigger register bit results in the corresponding interrupt + status bit being set to 1."; default hw = na; default sw = rw; diff --git a/src/soc_ifc/rtl/soc_ifc_top.sv b/src/soc_ifc/rtl/soc_ifc_top.sv index 5629dd4b5..02ac2942d 100644 --- a/src/soc_ifc/rtl/soc_ifc_top.sv +++ b/src/soc_ifc/rtl/soc_ifc_top.sv @@ -94,7 +94,7 @@ module soc_ifc_top //Obfuscated UDS and FE input logic clear_obf_secrets, - input logic scan_mode_f, + input logic scan_mode, input logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key, output logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg, output logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy, @@ -174,7 +174,7 @@ logic uc_mbox_data_avail_d; logic uc_cmd_avail_p; logic security_state_debug_locked_d; logic security_state_debug_locked_p; -logic scan_mode_d; +logic scan_mode_f; logic scan_mode_p; logic sram_single_ecc_error; logic sram_double_ecc_error; @@ -235,7 +235,7 @@ soc_ifc_boot_fsm i_soc_ifc_boot_fsm ( .clk(clk), .cptra_pwrgood(cptra_pwrgood), .cptra_rst_b (cptra_rst_b), - .scan_mode(scan_mode_f), + .scan_mode(scan_mode), .fw_update_rst (soc_ifc_reg_hwif_out.internal_fw_update_reset.core_rst.value), .fw_update_rst_wait_cycles (soc_ifc_reg_hwif_out.internal_fw_update_reset_wait_cycles.wait_cycles.value), .ready_for_fuses(ready_for_fuses), @@ -376,13 +376,15 @@ soc_ifc_arb #( .sha_error(sha_error), //FUNC reg inf .soc_ifc_reg_req_dv(soc_ifc_reg_req_dv), - .soc_ifc_reg_req_hold(1'b0), + .soc_ifc_reg_req_hold(soc_ifc_reg_req_hold), .soc_ifc_reg_req_data(soc_ifc_reg_req_data), .soc_ifc_reg_rdata(soc_ifc_reg_rdata), .soc_ifc_reg_error(soc_ifc_reg_error) ); +always_comb soc_ifc_reg_req_hold = 1'b0; + //Functional Registers and Fuses //This module contains the functional registers maintained by the Caliptra Mailbox @@ -442,7 +444,7 @@ always_comb begin soc_ifc_reg_hwif_in.CPTRA_FLOW_STATUS.boot_fsm_ps.next = boot_fsm_ps; soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.device_lifecycle.next = security_state.device_lifecycle; soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.debug_locked.next = security_state.debug_locked; - soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.scan_mode.next = scan_mode_f; + soc_ifc_reg_hwif_in.CPTRA_SECURITY_STATE.scan_mode.next = scan_mode; //generic wires for (int i = 0; i < 2; i++) begin generic_output_wires[i] = soc_ifc_reg_hwif_out.CPTRA_GENERIC_OUTPUT_WIRES[i].generic_wires.value; @@ -531,14 +533,14 @@ always_comb security_state_debug_locked_p = security_state.debug_locked ^ securi // Generate a pulse to set the interrupt bit always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin if (~cptra_noncore_rst_b) begin - scan_mode_d <= '0; + scan_mode_f <= '0; end else begin - scan_mode_d <= scan_mode_f; + scan_mode_f <= scan_mode; end end -always_comb scan_mode_p = scan_mode_f & ~scan_mode_d; +always_comb scan_mode_p = scan_mode & ~scan_mode_f; //Filtering by PAUSER always_comb begin diff --git a/src/soc_ifc/tb/soc_ifc_tb.sv b/src/soc_ifc/tb/soc_ifc_tb.sv index 7a50704d0..46cd5641a 100644 --- a/src/soc_ifc/tb/soc_ifc_tb.sv +++ b/src/soc_ifc/tb/soc_ifc_tb.sv @@ -137,7 +137,7 @@ module soc_ifc_tb logic [31:0] generic_input_wires1; logic clear_obf_secrets; - logic scan_mode_f; + logic scan_mode; // obfuscation, uds and field entropy for observation logic [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg; @@ -265,7 +265,7 @@ module soc_ifc_tb .rv_ecc_sts(rv_ecc_sts_t'{default:1'b0}), .clear_obf_secrets(clear_obf_secrets), - .scan_mode_f(scan_mode_f), + .scan_mode(scan_mode), .cptra_obf_key('0), .cptra_obf_key_reg(cptra_obf_key_reg), .obf_field_entropy(obf_field_entropy), @@ -327,7 +327,7 @@ module soc_ifc_tb // Tie-offs - assign scan_mode_f = 1'b0; + assign scan_mode = 1'b0; assign clear_obf_secrets = 1'b0; @@ -422,7 +422,7 @@ module soc_ifc_tb // CPTRA SECUIRTY_STATE, FLOW_STATUS, GENERIC_INPUT_WIRES //---------------------------------------------------------------- - always_comb update_CPTRA_SECURITY_STATE(scan_mode_f, security_state.debug_locked, security_state.device_lifecycle); + always_comb update_CPTRA_SECURITY_STATE(scan_mode, security_state.debug_locked, security_state.device_lifecycle); always_comb update_CPTRA_FLOW_STATUS(ready_for_fuses, `REG_HIER_BOOT_FSM_PS); always_comb update_CPTRA_GENERIC_INPUT_WIRES(generic_input_wires1_q, 1'b1); always_comb update_CPTRA_GENERIC_INPUT_WIRES(generic_input_wires0_q, 1'b0); diff --git a/src/soc_ifc/tb/soc_reg_intrblk_test.svh b/src/soc_ifc/tb/soc_reg_intrblk_test.svh index 85e92c8ef..6bc281cfc 100644 --- a/src/soc_ifc/tb/soc_reg_intrblk_test.svh +++ b/src/soc_ifc/tb/soc_reg_intrblk_test.svh @@ -70,20 +70,20 @@ dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value}; assign error_global_intr_r = dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_global_intr_r.agg_sts.value; // *RO* assign notif_global_intr_r = dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value; // *RO* - assign error_internal_intr_r = {dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value, + assign error_internal_intr_r = {dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value, dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value}; - assign notif_internal_intr_r = {dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value}; + assign notif_internal_intr_r = {dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value, dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value, - dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value}; + dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value, + dut.i_soc_ifc_reg.field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value}; assign error_intr_trig_r = {dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value, dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value, dut.i_soc_ifc_reg.field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value, @@ -246,7 +246,7 @@ foreach (wo_associated_regnames[i]) begin rname = wo_associated_regnames[i]; addr = socregs.get_addr(rname); - $display ("\n-- Handling WO register 0x%08x (%s) --", addr, rname); + $display ("\n-- Handling WO associated register 0x%08x (%s) --", addr, rname); $display ("\n -- First clear register and check --"); wrtrans.update_byname(rname, 32'hffff_ffff, tid); @@ -263,38 +263,32 @@ end end - // Repeat. Longer squence for WO_REGNAMES. + // Repeat. Longer squence for WO_REGNAMES (Trigger registers). // First expect to clear all write-to-clear data (check it too) - // Then randomly set bits and ensure only those bits are cleared. + // Then randomly set bits and ensure only those bits are 1. foreach (wo_regnames[i]) begin + word_addr_t associated_addr; + rname = wo_regnames[i]; + associated_rname = rname == "INTR_BRF_ERROR_INTR_TRIG_R" ? "INTR_BRF_ERROR_INTERNAL_INTR_R" : + rname == "INTR_BRF_NOTIF_INTR_TRIG_R" ? "INTR_BRF_NOTIF_INTERNAL_INTR_R" : + "UNDEFINED"; addr = socregs.get_addr(rname); - $display ("\n-- Handling WO register 0x%08x (%s) --", addr, rname); + associated_addr = socregs.get_addr(associated_rname); - $display ("\n -- First clear register and check --"); - wrtrans.update_byname(rname, 32'hffff_ffff, tid); - write_reg_trans(SET_AHB, wrtrans); - repeat (5) @(posedge clk_tb); + $display ("\n-- Handling WO register 0x%08x (%s) --", socregs.get_addr(rname), rname); - rdtrans.update_byname(rname, 0, tid); - read_reg_trans(GET_AHB, rdtrans); - if (rdtrans.data != '0) begin - $display("TB ERROR. Expected a write ones to clear register for addr 0x%08x (%s). Instead received 0x%08x", - addr, rname, rdtrans.data); - error_ctr += 1; - continue; - end - // Now randomly set bits after reg is all clear wrtrans.update_byname(rname, 0, tid); - wrtrans.randomize(); + wrtrans.randomize() with {wrtrans.data & get_mask(rname) != 0;}; // Require some nonzero value after masking ahb_wrdata = wrtrans.data & get_mask(rname); // $display ("TB DEBUG. Now randomly set bits to write 0x%08x; w/masking expect to write 0x%08x", // wrtrans.data, ahb_wrdata); - $display ("\n -- Finally check for non-zero value and then transition to 0 --"); + $display ("\n -- Write random trigger data and check for non-zero value, then transition to 0 --"); + nonzero_regval = 0; fork begin : writing_over_ahb write_reg_trans(SET_AHB, wrtrans); @@ -310,13 +304,11 @@ $display ("TB DEBUG. All said and done; from addr 0x%08x (%s). Directly probed non-zero val = 0x%08x and final val = 0x%08x| expected non-zero = 0x%08x", addr, rname, nonzero_regval, final_regval, ahb_wrdata); - associated_rname = "INTR_BRF_ERROR_INTR_TRIG_R" ? "INTR_BRF_ERROR_INTERNAL_INTR_R" : - "INTR_BRF_NOTIF_INTR_TRIG_R" ? "INTR_BRF_NOTIF_INTERNAL_INTR_R" : - "UNDEFINED"; - associated_regval = probe_reg(associated_rname); - $display ("TB INFO. Checking associated address %s related to trigger %s; associaated value = 0x%08x, trigger value %08x", + $display ("TB INFO. Checking associated address %s related to trigger %s; associated value = 0x%08x, trigger value %08x", associated_rname, rname, associated_regval, nonzero_regval); + if (associated_regval != ahb_wrdata) + $display("TB ERROR value 0x%08x in associated register 0x%08x (%s) does not match trigger value 0x%08x", associated_regval, socregs.get_addr(associated_rname), associated_rname, ahb_wrdata); if (changeup && changedn && (nonzero_regval == ahb_wrdata) && (final_regval == '0)) @@ -330,6 +322,21 @@ if (nonzero_regval != ahb_wrdata) $display("TB ERROR Nonzero value noted for addr 0x%08x (%s) is 0x%08x | expected 0x%08x", addr, rname, nonzero_regval, ahb_wrdata); end + + $display ("\n -- Finally clear associated register 0x%08x (%s) and check --", associated_addr, associated_rname); + wrtrans.update_byname(associated_rname, ahb_wrdata, tid); + write_reg_trans(SET_AHB, wrtrans); + repeat (5) @(posedge clk_tb); + + rdtrans.update_byname(associated_rname, 0, tid); + read_reg_trans(GET_AHB, rdtrans); + if (rdtrans.data != '0) begin + $display("TB ERROR. Expected a write value of 0x%08x to clear register for addr 0x%08x (%s). Instead received 0x%08x", + ahb_wrdata, associated_addr, associated_rname, rdtrans.data); + error_ctr += 1; + continue; + end + end end @@ -378,9 +385,9 @@ function automatic dword_t probe_reg(string regname); return (regname == "INTR_BRF_ERROR_INTERNAL_INTR_R") ? error_internal_intr_r : - (regname == "INTR_BRF_NOTIF_INTERNAL_INTR_R") ? notif_internal_intr_r : - (regname == "INTR_BRF_ERROR_INTR_TRIG_R") ? error_intr_trig_r : - (regname == "INTR_BRF_NOTIF_INTR_TRIG_R") ? notif_intr_trig_r : 32'hdead_face; + (regname == "INTR_BRF_NOTIF_INTERNAL_INTR_R") ? notif_internal_intr_r : + (regname == "INTR_BRF_ERROR_INTR_TRIG_R") ? error_intr_trig_r : + (regname == "INTR_BRF_NOTIF_INTR_TRIG_R") ? notif_intr_trig_r : 32'hdead_face; endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/config/compile.yml b/src/soc_ifc/uvmf_soc_ifc/config/compile.yml index 1f9cf8295..ebf9d8986 100644 --- a/src/soc_ifc/uvmf_soc_ifc/config/compile.yml +++ b/src/soc_ifc/uvmf_soc_ifc/config/compile.yml @@ -53,6 +53,7 @@ provides: [uvmf_soc_ifc] schema_version: 2.4.0 requires: - uvmf_soc_ifc_vip + - soc_ifc_coverage targets: tb: directories: diff --git a/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc.vf b/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc.vf new file mode 100644 index 000000000..46168ac64 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc.vf @@ -0,0 +1,178 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/coverage ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/include/el2_def.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/common_defines.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_bind.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters/soc_ifc_parameters_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hvl_top.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_arb.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/wdt.sv \ No newline at end of file diff --git a/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc_vip.vf b/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc_vip.vf new file mode 100644 index 000000000..8f85c734a --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/config/uvmf_soc_ifc_vip.vf @@ -0,0 +1,166 @@ ++define+MAP_PROT_ATTR ++incdir+${UVM_HOME}/src ++incdir+${UVM_HOME}/src/dpi ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3 ++incdir+${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules ++incdir+${UVMF_HOME}/common/mgc_vip/ahb ++incdir+${UVMF_HOME}/common/mgc_vip/apb ++incdir+${UVMF_HOME}/common/modules ++incdir+${UVMF_HOME}/common/utility_packages/qvip_utils_pkg ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload ++incdir+${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset ++incdir+${UVMF_HOME}/uvmf_base_pkg ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf ++incdir+${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/rtl ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg ++incdir+${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl +${UVM_HOME}/src/uvm_pkg.sv +${QUESTA_MVC_HOME}/include/questa_mvc_svapi.svh +${QUESTA_MVC_HOME}/questa_mvc_src/sv/mvc_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/mgc_apb3_v1_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/mgc_ahb_v2_0_pkg.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_slave.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/ahb/modules/ahb_lite_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_master.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb_monitor.sv +${QUESTA_MVC_HOME}/questa_mvc_src/sv/apb3/modules/apb5_monitor.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg_hdl.sv +${UVMF_HOME}/uvmf_base_pkg/uvmf_base_pkg.sv +${UVMF_HOME}/common/utility_packages/qvip_utils_pkg/qvip_utils_pkg.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_master_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_module_hvl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_signal_if.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hdl.sv +${UVMF_HOME}/common/mgc_vip/ahb/mgc_ahb_slave_hvl.sv +${UVMF_HOME}/common/modules/ahb_master.v +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hdl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module_hvl.sv +${UVMF_HOME}/common/modules/ahb_memory_slave_module.sv +${UVMF_HOME}/common/modules/ahb_slave.v +${UVMF_HOME}/common/modules/apb3_memory_slave_module.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_master_hvl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hdl_wrapper.sv +${UVMF_HOME}/common/mgc_vip/apb/apb_monitor_hvl_wrapper.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/clock/clock_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/memload/memload_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/reset_pkg.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/async_reset_bfm.sv +${UVMF_HOME}/common/uvm_co_emulation_utilities/uvm_co-emulation_utilities/utils/reset/sync_reset_bfm.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/config_policies/qvip_ahb_lite_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/hdl_qvip_ahb_lite_slave.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_clk_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/default_reset_gen.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/config_policies/qvip_apb5_slave_params_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/qvip_apb5_slave_pkg.sv +${CALIPTRA_ROOT}/src/libs/uvmf/qvip_apb5_slave_dir/uvmf/hdl_qvip_apb5_slave.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_uvm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/include/el2_def.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/common_defines.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/soc_ifc_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_ctrl_pkg/src/cptra_ctrl_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/cptra_status_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr_pkg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr_pkg.sv +${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/lib/beh_lib.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_arb.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/mbox_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_top.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/sha512_acc_csr.sv +${CALIPTRA_ROOT}/src/soc_ifc/rtl/wdt.sv \ No newline at end of file diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv index 621ee5af9..dbc11dfbd 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv @@ -201,7 +201,7 @@ import uvmf_base_pkg_hdl::*; .rv_ecc_sts(cptra_ctrl_agent_bus.rv_ecc_sts), //Obfuscated UDS and FE .clear_obf_secrets(cptra_ctrl_agent_bus.clear_obf_secrets), - .scan_mode_f (1'b0), + .scan_mode (1'b0), .cptra_obf_key(soc_ifc_ctrl_agent_bus.cptra_obf_key), .cptra_obf_key_reg(cptra_status_agent_bus.cptra_obf_key_reg), .obf_field_entropy(cptra_status_agent_bus.obf_field_entropy), @@ -253,6 +253,9 @@ import uvmf_base_pkg_hdl::*; assign uvm_test_top_environment_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PSLVERRCHK = 0; assign uvm_test_top_environment_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PRUSERCHK = 0; assign uvm_test_top_environment_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PBUSERCHK = 0; + + + soc_ifc_cov_bind i_soc_ifc_cov_bind(); // pragma uvmf custom dut_instantiation end initial begin // tbx vif_binding_block diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh index 0e27ee264..e5e19fe41 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh @@ -32,7 +32,15 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_status_status extends soc_ifc_reg_dela return; end end - if (rm.mbox_lock.lock.get_mirrored_value()) begin + if (rm.mbox_fn_state_sigs.mbox_error) begin + // NOTE: This is due to a logic bug in mbox.sv. Regular state transitions + // take priority over error state transitions, so if an arc_..._ERROR state + // goes high at the same time as that state's normal arc_ signal, + // RTL won't go to the ERROR state as predicted. + // Flag this as an error here, that will cause regression failures until fixed. + `uvm_error("SOC_IFC_REG_DELAY_JOB", $sformatf("While running [%s] (scheduled due to access against mbox_status on map [%p]), functional state value detected as: %p. Skipping delay job state transitions. This is a known RTL bug in mbox.sv", this.get_type_name(), map.get_name(), rm.mbox_fn_state_sigs)) + end + else if (rm.mbox_lock.lock.get_mirrored_value()) begin rm.mbox_status.mbox_fsm_ps.predict(state_nxt, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); if (state_nxt == MBOX_EXECUTE_SOC) begin rm.mbox_fn_state_sigs = '{soc_done_stage: 1'b1, default: 1'b0}; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh index bc8f55aaf..c5b982007 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh @@ -36,6 +36,10 @@ class soc_ifc_reg_delay_job_intr_block_rf_ext extends soc_ifc_reg_delay_job; // Wait for all predictor callbacks to run for every intr bit accessed // during the current clock cycle, so mirrors are up to date uvm_wait_for_nba_region(); + // There might be delay_jobs running additional bit updates + // at this point, so wait again + // FIXME -- find a better way to capture field updates at each clock edge + uvm_wait_for_nba_region(); // Snapshot of current value, since next cycle may see value changes again val_sts_reg = sts_reg.get_mirrored_value(); val_en_reg = en_reg .get_mirrored_value(); @@ -47,7 +51,7 @@ class soc_ifc_reg_delay_job_intr_block_rf_ext extends soc_ifc_reg_delay_job; virtual task do_job(); `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("Running delayed job for %s", req_fld.get_full_name()), UVM_MEDIUM) - if (!/*val_sts_glb*/sts_glb.get_mirrored_value() && |(val_sts_reg/*sts_reg.get_mirrored_value()*/ & val_en_reg/*en_reg.get_mirrored_value()*/) /*&& val_en_glb / * en_glb.get_mirrored_value()*/) begin + if (!sts_glb.get_mirrored_value() && |(val_sts_reg & val_en_reg)) begin sts_glb.predict(1'b1); `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being set to 0x%0x. Values: en_reg(latched) [0x%0x(0x%0x)] sts_reg [0x%0x(0x%0x)] en_glb [0x%0x(0x%0x)] sts_glb [0x%0x(0x%0x)]", @@ -58,7 +62,7 @@ class soc_ifc_reg_delay_job_intr_block_rf_ext extends soc_ifc_reg_delay_job; sts_glb.get_mirrored_value(), val_sts_glb), UVM_MEDIUM) end - else if (/*val_sts_glb*/sts_glb.get_mirrored_value() && !(|(val_sts_reg/*sts_reg.get_mirrored_value()*/ & val_en_reg/*en_reg.get_mirrored_value()*/) /*&& val_en_glb / * en_glb.get_mirrored_value()*/)) begin + else if (sts_glb.get_mirrored_value() && !(|(val_sts_reg & val_en_reg))) begin sts_glb.predict(1'b0); `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being cleared to 0x%0x. Values: en_reg(latched) [0x%0x(0x%0x)] sts_reg [0x%0x(0x%0x)] en_glb [0x%0x(0x%0x)] sts_glb [0x%0x(0x%0x)]", diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh index bd57d181e..49bbfb779 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh @@ -18,6 +18,7 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error extends soc_ifc_reg_delay_job; `uvm_object_utils( soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error ) mbox_csr_ext rm; /* mbox_csr_rm */ + soc_ifc_reg_ext sir_rm; /* soc_ifc_reg_rm */ uvm_reg_field fld; mbox_fsm_state_e state_nxt; uvm_reg_map map; @@ -32,29 +33,51 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error extends soc_ifc_reg_delay_j end else if (error.axs_without_lock) begin uvm_reg_block top; + uvm_reg_block blk; uvm_reg_field intr_fld; uvm_reg_field non_fatal_fld; top = rm.get_parent(); - intr_fld = top.get_block_by_name("soc_ifc_reg_rm").get_block_by_name("intr_block_rf_ext").get_field_by_name("error_cmd_fail_sts"); - non_fatal_fld = top.get_block_by_name("soc_ifc_reg_rm").get_reg_by_name("CPTRA_HW_ERROR_NON_FATAL").get_field_by_name("mbox_prot_no_lock"); + blk = top.get_block_by_name("soc_ifc_reg_rm"); + $cast(sir_rm, blk); + intr_fld = sir_rm.get_block_by_name("intr_block_rf_ext").get_field_by_name("error_cmd_fail_sts"); + non_fatal_fld = sir_rm.get_reg_by_name("CPTRA_HW_ERROR_NON_FATAL").get_field_by_name("mbox_prot_no_lock"); intr_fld .predict(1'b1, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map.get_parent().get_map_by_name("soc_ifc_AHB_map"))); + sir_rm.hwset_active.cptra_hw_error_non_fatal |= 1 << non_fatal_fld.get_lsb_pos(); non_fatal_fld.predict(1'b1, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); + fork + uvm_reg_data_t hwset_msk = ~(1 << non_fatal_fld.get_lsb_pos()); + begin + uvm_wait_for_nba_region(); + sir_rm.hwset_active.cptra_hw_error_non_fatal &= hwset_msk; + end + join_none `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("delay_job scheduled for access through map [%p] on [%s] results in Access Without Lock Error, and no state change. Functional state tracker: [%p] mbox_fsm_ps transition (ignored) [%p]", map.get_name(), fld.get_full_name(), rm.mbox_fn_state_sigs, state_nxt), UVM_FULL) end else if (error.axs_incorrect_order && rm.mbox_lock.lock.get_mirrored_value() && !rm.mbox_unlock.unlock.get_mirrored_value()) begin uvm_reg_block top; + uvm_reg_block blk; uvm_reg_field intr_fld; uvm_reg_field non_fatal_fld; top = rm.get_parent(); - intr_fld = top.get_block_by_name("soc_ifc_reg_rm").get_block_by_name("intr_block_rf_ext").get_field_by_name("error_cmd_fail_sts"); - non_fatal_fld = top.get_block_by_name("soc_ifc_reg_rm").get_reg_by_name("CPTRA_HW_ERROR_NON_FATAL").get_field_by_name("mbox_prot_ooo"); + blk = top.get_block_by_name("soc_ifc_reg_rm"); + $cast(sir_rm, blk); + intr_fld = sir_rm.get_block_by_name("intr_block_rf_ext").get_field_by_name("error_cmd_fail_sts"); + non_fatal_fld = sir_rm.get_reg_by_name("CPTRA_HW_ERROR_NON_FATAL").get_field_by_name("mbox_prot_ooo"); intr_fld .predict(1'b1, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map.get_parent().get_map_by_name("soc_ifc_AHB_map"))); + sir_rm.hwset_active.cptra_hw_error_non_fatal |= 1 << non_fatal_fld.get_lsb_pos(); non_fatal_fld.predict(1'b1, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); + fork + uvm_reg_data_t hwset_msk = ~(1 << non_fatal_fld.get_lsb_pos()); + begin + uvm_wait_for_nba_region(); + sir_rm.hwset_active.cptra_hw_error_non_fatal &= hwset_msk; + end + join_none rm.mbox_status.mbox_fsm_ps.predict(state_nxt, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("delay_job scheduled for access through map [%p] on [%s] results in state transition. Functional state tracker: [%p] mbox_fsm_ps transition [%p]", map.get_name(), fld.get_full_name(), rm.mbox_fn_state_sigs, state_nxt), UVM_FULL) diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv index ed868206a..add769657 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv @@ -228,10 +228,17 @@ package soc_ifc_reg_model_top_pkg; // the value read from CPTRA_FLOW_STATUS boot_fn_state_s boot_fn_state_sigs; + // Tracks when a register field is being actively updated by hardware, so + // prediction and scoreboard logic can detect transitions + struct { + uvm_reg_data_t cptra_hw_error_non_fatal; + } hwset_active; + extern virtual function void reset(string kind = "HARD"); function new(string name = "soc_ifc_reg_ext"); super.new(name); boot_fn_state_sigs = '{boot_idle: 1'b1, default: 1'b0}; + hwset_active = '{default: '0}; endfunction : new // FIXME Manually maintaining a list here of registers that are configured @@ -377,6 +384,11 @@ package soc_ifc_reg_model_top_pkg; if (kind inside {"HARD", "SOFT"}) begin boot_fn_state_sigs = '{boot_idle: 1'b1, default: 1'b0}; end + if (kind inside {"HARD"}) begin + // Some signals may also be reset by a noncore reset, but all of the + // initial hwset_active members may be driven during warm resets + hwset_active = '{default: '0}; + end endfunction class mbox_csr_ext extends mbox_csr; @@ -386,6 +398,13 @@ package soc_ifc_reg_model_top_pkg; uvm_event mbox_lock_clr_miss; uvm_event mbox_datain_to_dataout_predict; + // This semaphore is a necessary workaround for a known bug in the UVM + // library uvm_reg class, as described here: + // https://forums.accellera.org/topic/7037-register-write-clobbers-simultaneous-access-in-multi-threaded-testbench/ + // Essentially, the uvm_reg native atomic fails to correctly arbitrate + // between multiple contending accessors in separate threads. + semaphore mbox_datain_sem; + // This tracks expected functionality of the mailbox in a way that is // agnostic to the internal state machine implementation and strictly // observes the mailbox specification. This is what a more rigorous @@ -403,6 +422,7 @@ package soc_ifc_reg_model_top_pkg; mbox_fn_state_sigs = '{mbox_idle: 1'b1, default: 1'b0}; mbox_lock_clr_miss = new("mbox_lock_clr_miss"); mbox_datain_to_dataout_predict = new("mbox_datain_to_dataout_predict"); + mbox_datain_sem = new(1); endfunction : new // FIXME Manually maintaining a list here of registers that are configured @@ -459,6 +479,9 @@ package soc_ifc_reg_model_top_pkg; mbox_resp_q.delete(); mbox_lock_clr_miss.reset(); mbox_datain_to_dataout_predict.reset(); + // In case any active sequences claimed the semaphore but didn't relinquish it. + void'(mbox_datain_sem.try_get()); + mbox_datain_sem.put(); // Mailbox State Changes // TODO what to do for FW update? diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh index 608f241e2..028f82379 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh @@ -219,7 +219,7 @@ task soc_ifc_env_cptra_mbox_handler_sequence::handler_setup(); report_reg_sts(reg_sts, "notif_internal_intr_r"); // Clear errors if (err_rsp_count) begin - `uvm_warning("CPTRA_MBOX_HANDLER", "Did not expect to receive any new cptra_status err interrupt transactions at sequence entry!") + `uvm_info("CPTRA_MBOX_HANDLER", "Received new cptra_status err interrupt transactions at sequence entry! Is this run in a multi-agent context?", UVM_LOW) err_rsp_count = 0; end reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); @@ -454,6 +454,7 @@ task soc_ifc_env_cptra_mbox_handler_sequence::report_reg_sts(uvm_status_e reg_st // This prevents further bus transfers from being initiated, so the AHB // sequencer is in a clean state when we kill the ALL_TIME_CONSUMING_TASKS // process. + `uvm_info("CPTRA_MBOX_HANDLER", "in report_reg_sts: waiting due to seq_done = 1", UVM_DEBUG) in_report_reg_sts.wait_off(); end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh index 755c60628..8bb5490d6 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh @@ -33,7 +33,7 @@ class soc_ifc_env_cptra_mbox_interference_handler_sequence extends soc_ifc_env_c extern virtual task mbox_wait_for_command(output op_sts_e op_sts); extern virtual task mbox_wait_and_force_unlock(); - extern virtual task burst_random_reg_accesses(uvm_event stop); + extern virtual task burst_random_reg_accesses(uvm_event stop, ref process this_proc); rand uvm_reg_data_t data; rand uvm_reg_addr_t mem_offset; @@ -120,29 +120,39 @@ endtask task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_and_force_unlock(); uvm_reg_data_t data; mbox_fsm_state_e state; - uvm_event force_unlock_delay_complete = new("force_unlock_delay_complete"); + process rand_reg_axs_proc; + uvm_event halt_rand_reg_accesses = new("halt_rand_reg_accesses"); // Start the unlock proc prior to burst accesses so that the parent // sequence knows to wait for AHB traffic to complete before ending the // sequence unlock_proc_active = 1'b1; + `uvm_info("CPTRA_MBOX_HANDLER", $sformatf("Starting mbox_wait_and_force_unlock with inject_force_unlock [%d] force_unlock_delay_cycles [%0d]", inject_force_unlock, force_unlock_delay_cycles), UVM_MEDIUM) // Wait... // If force unlock is disabled, this task will only exit upon detecting // an ERROR that requires servicing, whereupon force_unlock will still // be set to recover. In either case, only an event resulting in force // unlock causes this routine to break - force_unlock_delay_complete.reset(); + halt_rand_reg_accesses.reset(); fork begin + wait(rand_reg_axs_proc != null); if (inject_force_unlock) begin configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(force_unlock_delay_cycles); + halt_rand_reg_accesses.trigger(); + while(halt_rand_reg_accesses.get_num_waiters() == 0) + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); end else begin `uvm_info("CPTRA_MBOX_HANDLER", "Not injecting force unlock - burst random reg accesses until any err interrupt is observed", UVM_HIGH) forever begin if (err_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) begin `uvm_info("CPTRA_MBOX_HANDLER", "Received soc_ifc_err_intr, clearing and (if needed) proceeding to mbox_unlock", UVM_MEDIUM) + // Pause rand reg accesses while servicing interrupt + halt_rand_reg_accesses.trigger(); + while(halt_rand_reg_accesses.get_num_waiters() == 0) + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); // Read and clear any error interrupts reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "error_internal_intr_r"); @@ -152,6 +162,7 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_and_force_u err_rsp_count = 0; // Next, check if we need to proceed to mbox_unlock step if (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]) begin + halt_rand_reg_accesses.reset(); continue; end reg_model.mbox_csr_rm.mbox_status.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); @@ -168,9 +179,9 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_and_force_u end end end - force_unlock_delay_complete.trigger(); + rand_reg_axs_proc.kill(); end - burst_random_reg_accesses(force_unlock_delay_complete); + burst_random_reg_accesses(halt_rand_reg_accesses, rand_reg_axs_proc); join // After waiting the requisite number of cycles, check mbox_status. @@ -211,7 +222,7 @@ endtask // intermixed with random delays, until the input event // is triggered. //========================================== -task soc_ifc_env_cptra_mbox_interference_handler_sequence::burst_random_reg_accesses(uvm_event stop); +task soc_ifc_env_cptra_mbox_interference_handler_sequence::burst_random_reg_accesses(uvm_event stop, ref process this_proc); int unsigned burst_length; int unsigned delay_cycles; @@ -225,6 +236,7 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::burst_random_reg_acce uvm_reg_data_t rand_data; uvm_status_e rand_sts; + this_proc = process::self(); reg_model.soc_ifc_AHB_map.get_registers(regs, UVM_HIER); // Registers we won't randomly access due to side-effects @@ -249,6 +261,7 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::burst_random_reg_acce delay_cycles inside {[1:500]};}) `uvm_error("CPTRA_MBOX_HANDLER", "Failed to randomize burst_length and delay_cycles") else begin + `uvm_info("CPTRA_MBOX_HANDLER", $sformatf("Beginning random AHB burst with delay_cycles [%d] burst_length [%d]", delay_cycles, burst_length), UVM_HIGH) for (ii=0; ii 0; ii--) begin configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); - if (stop.is_on()) return; + if (stop.is_on()) stop.wait_off(); end end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh index 46863df42..3b720ac5e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh @@ -40,6 +40,7 @@ class soc_ifc_env_cptra_mbox_req_sequence_base extends soc_ifc_env_sequence_base int sts_rsp_count; uvm_status_e reg_sts; bit mbox_sts_is_error = 0; + bit mbox_sts_exp_error = 0; // Indicates the SoC handler sequence will inject an error, which this sequence should expect to observe rand bit do_ahb_lock_check; rand bit retry_failed_reg_axs; // Certain random sequences force the command to be outside of the defined @@ -391,6 +392,9 @@ task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_poll_status(); if (data == DATA_READY) begin `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received status %p when not expecting any bytes of response data!", data), UVM_LOW) end + else if (data == CMD_FAILURE && !mbox_sts_exp_error) begin + `uvm_error("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data)) + end else if (data == CMD_FAILURE) begin `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data), UVM_LOW) end @@ -410,31 +414,79 @@ endtask //========================================== task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_clr_execute(); uvm_reg_data_t data; + bit error_intr_cmd_fail = 0; // We have to stall a couple clocks to allow interrupts to assert in case // we read the MBOX_ERROR status, since there is a small delay as the signal // propagates through registers. configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(2); - // Now, check for the expected error interrupt + + // Catch the possibility that MBOX_ERROR was not yet observed by waiting for + // the associated interrupt to arrive (the SoC sequence may have a delay + // before injecting the error) + // If Caliptra already detected a MBOX_ERROR state, but did not see an + // error interrupt, that's an error condition that will be reported + // later on in the sequence with uvm_error + if (mbox_sts_exp_error && !mbox_sts_is_error) begin + fork + begin: WAIT_ERR_INTR + wait(sts_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending); + disable WAIT_ERR_INTR_TIMEOUT; + end + begin: WAIT_ERR_INTR_TIMEOUT + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(131072); + disable WAIT_ERR_INTR; + end + join + end + + // Now, do some error checking and handling if (sts_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) begin reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "error_internal_intr_r"); reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "error_internal_intr_r"); - if (data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]) begin - // Force unlock to recover from error and reset mailbox to IDLE state - reg_model.mbox_csr_rm.mbox_unlock.write(reg_sts, uvm_reg_data_t'(1 << reg_model.mbox_csr_rm.mbox_unlock.unlock.get_lsb_pos()), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); - report_reg_sts(reg_sts, "mbox_unlock"); - return; /* force unlock trumps the write to mbox_execute, so we're done at this point */ + error_intr_cmd_fail = data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]; + if (error_intr_cmd_fail) begin + if (!mbox_sts_is_error) begin + mbox_status_e data; + mbox_fsm_state_e state; + // Re-check mbox_status to see if FSM has changed to MBOX_ERROR since last check + mbox_check_status(data, state); + if (state == MBOX_ERROR) + mbox_sts_is_error = 1; + end end else if (mbox_sts_is_error) begin `uvm_error("CPTRA_MBOX_SEQ", "Error interrupt following cmd failure does not have cmd_fail bit set!") end end - else if (mbox_sts_is_error) begin - `uvm_error("CPTRA_MBOX_SEQ", "Error encountered but no interrupt received") + + // Error reporting based on sequence configuration and outcome + case ({mbox_sts_is_error,mbox_sts_exp_error,error_intr_cmd_fail}) inside + 3'b111: `uvm_info("CPTRA_MBOX_SEQ", "MBOX_ERROR state encountered as expected, along with the required error_interrupt", UVM_MEDIUM) + 3'b110: `uvm_error("CPTRA_MBOX_SEQ", "Mailbox error state encountered but no interrupt received") + 3'b10?: `uvm_error("CPTRA_MBOX_SEQ", "Mailbox error state encountered unexpectedly (the test case should not have an error injection)") + 3'b011: `uvm_error("CPTRA_MBOX_SEQ", "Invalid register access injection was expected for the test case, and error_interrupt was received, but MBOX_ERROR state was not observed") + // This case is acceptable, as the 'expected error' (such as invalid register accesses in the + // soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence) might either be clobbered in + // arb, or be an actual legal access (like a duplicate dataout read), + // neither of which will actually cause the MBOX_ERROR transition/error_interrupt combo. + 3'b010: `uvm_info("CPTRA_MBOX_SEQ", "Invalid register access injection was expected for the test case but MBOX_ERROR state was not observed - this might be OK", UVM_LOW) + 3'b001: `uvm_error("CPTRA_MBOX_SEQ", "Test case did not expect any error injection, but observed a command failure interrupt") + 3'b000: `uvm_info("CPTRA_MBOX_SEQ", "Test case completed normally as expected, with no observed failures or error_interrupt", UVM_MEDIUM) + endcase + + // Cmd failure interrupt triggers the force unlock, and + // force unlock trumps the write to mbox_execute + if (error_intr_cmd_fail && mbox_sts_is_error) begin + // Force unlock to recover from error and reset mailbox to IDLE state + reg_model.mbox_csr_rm.mbox_unlock.write(reg_sts, uvm_reg_data_t'(1 << reg_model.mbox_csr_rm.mbox_unlock.unlock.get_lsb_pos()), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "mbox_unlock"); + end + else begin + reg_model.mbox_csr_rm.mbox_execute.write(reg_sts, uvm_reg_data_t'(0), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "mbox_execute"); end - reg_model.mbox_csr_rm.mbox_execute.write(reg_sts, uvm_reg_data_t'(0), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); - report_reg_sts(reg_sts, "mbox_execute"); endtask //========================================== diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_sequence.svh index 9f06602ab..f30a64077 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_sequence.svh @@ -63,11 +63,15 @@ task soc_ifc_env_mbox_dlen_overflow_sequence::mbox_push_datain(); if (!std::randomize(data)) `uvm_error("MBOX_SEQ", "Failed to randomize data") end `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii/4, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); if (!pauser_used_is_valid() && retry_failed_reg_axs) begin `uvm_info("MBOX_SEQ", "Re-do datain write with valid PAUSER", UVM_HIGH) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh index 1777a7d57..70c1aed9e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_underflow_sequence.svh @@ -61,11 +61,15 @@ task soc_ifc_env_mbox_dlen_underflow_sequence::mbox_push_datain(); if (!std::randomize(data)) `uvm_error("MBOX_SEQ", "Failed to randomize data") end `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii/4, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); if (!pauser_used_is_valid() && retry_failed_reg_axs) begin `uvm_info("MBOX_SEQ", "Re-do datain write with valid PAUSER", UVM_HIGH) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_max_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_max_sequence.svh index a57976374..f53828d64 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_max_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_max_sequence.svh @@ -52,12 +52,16 @@ task soc_ifc_env_mbox_max_sequence::mbox_push_datain(); if (!std::randomize(data)) `uvm_error("MBOX_SEQ", "Failed to randomize data") `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii/4, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); if (!pauser_used_is_valid() && retry_failed_reg_axs) begin `uvm_info("MBOX_SEQ", "Re-do datain write with valid PAUSER", UVM_HIGH) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end end -endtask \ No newline at end of file +endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_min_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_min_sequence.svh index 1cb78434c..3f74c7fe3 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_min_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_min_sequence.svh @@ -51,12 +51,16 @@ task soc_ifc_env_mbox_min_sequence::mbox_push_datain(); if (!std::randomize(data)) `uvm_error("MBOX_SEQ", "Failed to randomize data") `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii/4, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); if (!pauser_used_is_valid() && retry_failed_reg_axs) begin `uvm_info("MBOX_SEQ", "Re-do datain write with valid PAUSER", UVM_HIGH) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end end -endtask \ No newline at end of file +endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_real_fw_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_real_fw_sequence.svh index 3b8134b3f..45d4bd280 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_real_fw_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_real_fw_sequence.svh @@ -77,7 +77,9 @@ task soc_ifc_env_mbox_real_fw_sequence::mbox_push_datain(); for (ii=0; ii < firmware_end_dw; ii++) begin data = uvm_reg_data_t'({fw_img[ii][3],fw_img[ii][2],fw_img[ii][1],fw_img[ii][0]}); `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_sequence.svh index e0112ea05..2cde1d81f 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_sequence.svh @@ -70,7 +70,7 @@ class soc_ifc_env_mbox_reg_axs_invalid_sequence extends soc_ifc_env_mbox_sequenc mbox_set_cmd(mbox_op_rand); if (rand_delay_en) do_rand_delay(1, step_delay); mbox_push_datain(); if (rand_delay_en) do_rand_delay(1, step_delay); mbox_execute(); if (rand_delay_en) do_rand_delay(1, step_delay); - mbox_poll_status(); if (rand_delay_en) do_rand_delay(1, step_delay); + mbox_poll_status(); end begin: ERR_INJECT_FLOW wait(mbox_flow_proc != null); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh index 5e265b325..d269ac052 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_rom_fw_sequence.svh @@ -67,7 +67,9 @@ task soc_ifc_env_mbox_rom_fw_sequence::mbox_push_datain(); `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii, data), UVM_LOW) else `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh index 166e40bc7..ceaee7f2a 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh @@ -439,12 +439,16 @@ task soc_ifc_env_mbox_sequence_base::mbox_push_datain(); if (!std::randomize(data)) `uvm_error("MBOX_SEQ", "Failed to randomize data") end `uvm_info("MBOX_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii/4, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); if (!pauser_used_is_valid() && retry_failed_reg_axs) begin if (rand_delay_en) do_rand_delay(1, data_delay); `uvm_info("MBOX_SEQ", "Re-do datain write with valid PAUSER", UVM_HIGH) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end if (rand_delay_en) do_rand_delay(1, data_delay); @@ -523,7 +527,7 @@ task soc_ifc_env_mbox_sequence_base::mbox_read_resp_data(); reg_model.mbox_csr_rm.mbox_dataout.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(FORCE_VALID_PAUSER))); report_reg_sts(reg_sts, "mbox_dataout"); end - if (rand_delay_en) do_rand_delay(1, data_delay); + if (rand_delay_en && (ii+4) < dlen) do_rand_delay(1, data_delay); end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sha_accel_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sha_accel_sequence.svh index aa6f609cf..3a88f712d 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sha_accel_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sha_accel_sequence.svh @@ -53,9 +53,14 @@ class soc_ifc_env_mbox_sha_accel_sequence extends soc_ifc_env_mbox_sequence_base extern virtual task mbox_push_datain(); extern virtual task mbox_read_resp_data(); - constraint sha_accel_op_c { sha_accel_op_rand.mailbox_mode == 1'b1; } - constraint mbox_cmd_c { sha_accel_op_rand.sha512_mode == 1'b0 -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA384_REQ; - sha_accel_op_rand.sha512_mode == 1'b1 -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA512_REQ; + constraint sha_accel_op_c { sha_accel_op_rand.mailbox_mode dist {1 := 10, + 0 := 1}; } + + constraint mbox_cmd_c { (sha_accel_op_rand.sha512_mode == 1'b0 & sha_accel_op_rand.mailbox_mode == 1'b1) -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA384_REQ; + (sha_accel_op_rand.sha512_mode == 1'b1 & sha_accel_op_rand.mailbox_mode == 1'b1) -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA512_REQ; + (sha_accel_op_rand.sha512_mode == 1'b0 & sha_accel_op_rand.mailbox_mode == 1'b0) -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA384_STREAM_REQ; + (sha_accel_op_rand.sha512_mode == 1'b1 & sha_accel_op_rand.mailbox_mode == 1'b0) -> mbox_op_rand.cmd.cmd_e == MBOX_CMD_SHA512_STREAM_REQ; + solve sha_accel_op_rand before mbox_op_rand; } constraint mbox_resp_dlen_c {sha_accel_op_rand.sha512_mode == 1'b0 -> mbox_resp_expected_dlen == 32'd48; sha_accel_op_rand.sha512_mode == 1'b1 -> mbox_resp_expected_dlen == 32'd64; @@ -167,7 +172,9 @@ task soc_ifc_env_mbox_sha_accel_sequence::mbox_push_datain(); //sha_block_start_dw = this.start_addr >> 2; //write the start address into the first dword + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(this.start_addr), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); //pad the data until start address @@ -183,7 +190,9 @@ task soc_ifc_env_mbox_sha_accel_sequence::mbox_push_datain(); for (ii=most_sig_dword; ii >= 0 ; ii--) begin data = sha_block_data[ii]; `uvm_info("SHA_ACCEL_SEQ", $sformatf("[Iteration: %0d] Sending datain: 0x%x", ii, data), UVM_DEBUG) + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_uc_reg_access_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_uc_reg_access_sequence.svh index 6b46cd035..49b827b0c 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_uc_reg_access_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_uc_reg_access_sequence.svh @@ -109,7 +109,9 @@ task soc_ifc_env_mbox_uc_reg_access_sequence::mbox_push_datain(); uvm_reg_data_t data; for (int i = 0; i < num_reg; i++) begin data = uvm_reg_data_t'(reg_addr[i]); + reg_model.mbox_csr_rm.mbox_datain_sem.get(); reg_model.mbox_csr_rm.mbox_datain.write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(PAUSER_PROB_DATAIN))); + reg_model.mbox_csr_rm.mbox_datain_sem.put(); report_reg_sts(reg_sts, "mbox_datain"); end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_handler_sequence.svh index 028e280af..0a9217136 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_handler_sequence.svh @@ -156,8 +156,10 @@ task soc_ifc_env_soc_mbox_handler_sequence::mbox_setup(); end // Pick a user and use throughout sequence - // FIXME randomize? - apb_user_obj.set_addr_user(mbox_valid_users[0]); + if (!apb_user_obj.randomize() with {addr_user inside {mbox_valid_users};}) + `uvm_error("SOC_MBOX_HANDLER", "Failed to randomize APB PAUSER override value") + else + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Randomized APB PAUSER override value to 0x%x", apb_user_obj.addr_user), UVM_HIGH) endtask @@ -251,9 +253,6 @@ endtask task soc_ifc_env_soc_mbox_handler_sequence::mbox_set_status(); mbox_status_e status; uvm_reg_data_t data; - // Set mbox_dlen to resp size of 0 - reg_model.mbox_csr_rm.mbox_dlen.write(reg_sts, uvm_reg_data_t'(0), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); - report_reg_sts(reg_sts,"mbox_dlen"); // Determine which status to set and perform the write status = CMD_COMPLETE; data = uvm_reg_data_t'(status) << reg_model.mbox_csr_rm.mbox_status.status.get_lsb_pos(); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence.svh index 9c5b1a209..16f79abe4 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence.svh @@ -120,9 +120,19 @@ task soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence::mbox_do_random_reg_w if (!std::randomize(rand_idx) with {rand_idx < mbox_regs.size(); }) `uvm_fatal("SOC_MBOX_HANDLER", "Failed to randomize reg idx") - // Wait to do the reg write at some random point in the sequence + // Wait to do the reg write at some random point in the sequence, or do it + // very soon after the normal operation ends std::randomize(rand_delay) with {rand_delay dist {[1:255] :/ 5, [256:1023] :/ 3, [1024:65535] :/ 1};}; - configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(rand_delay); + fork + automatic int unsigned dly = rand_delay; + begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(dly); + end + begin + mainline.await(); + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks((dly % 25)+1); + end + join_any // Data used depends on which reg is being accessed to force invalid contents rand_wr_data = get_rand_wr_data(mbox_regs[rand_idx]); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh index e97196520..f2370c915 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh @@ -32,6 +32,7 @@ class soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence extends soc_ifc_ `uvm_object_utils( soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence ) extern virtual function create_seqs(); + extern virtual function randomize_seqs(); endclass @@ -42,3 +43,11 @@ function soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::create_seqs( obj = soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence_t::get_type().create_object("soc_ifc_env_soc_handler_seq"); if(!$cast(soc_ifc_env_soc_handler_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID_SMALL", "soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::create_seqs() - .create_object() failed") endfunction + +function soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::randomize_seqs(); + if(!soc_ifc_env_cptra_mbox_seq.randomize()) + `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID_SMALL", $sformatf("soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::body() - %s randomization failed", soc_ifc_env_cptra_mbox_seq.get_type_name())); + soc_ifc_env_cptra_mbox_seq.mbox_sts_exp_error = 1; + if(!soc_ifc_env_soc_handler_seq.randomize()) + `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID_SMALL", $sformatf("soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::body() - %s randomization failed", soc_ifc_env_soc_handler_seq.get_type_name())); +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh index bcc8dd5d8..be9f70abb 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh @@ -55,6 +55,8 @@ MBOX_CMD_RT_UPDATE = 32'hbabecafe, MBOX_CMD_SHA384_REQ = 32'h40C0FFEE, MBOX_CMD_SHA512_REQ = 32'h41C0FFEE, + MBOX_CMD_SHA384_STREAM_REQ = 32'h42C0FFEE, + MBOX_CMD_SHA512_STREAM_REQ = 32'h43C0FFEE, MBOX_CMD_ROM_FW_UPD = 32'h46574C44 } mbox_cmd_e; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh index 9e1465f0f..8ea5ce3e5 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh @@ -663,6 +663,7 @@ class soc_ifc_predictor #( ahb_master_burst_transfer #(ahb_lite_slave_0_params::AHB_NUM_MASTERS, ahb_lite_slave_0_params::AHB_NUM_MASTER_BITS, ahb_lite_slave_0_params::AHB_NUM_SLAVES, ahb_lite_slave_0_params::AHB_ADDRESS_WIDTH, ahb_lite_slave_0_params::AHB_WDATA_WIDTH, ahb_lite_slave_0_params::AHB_RDATA_WIDTH) ahb_txn; uvm_reg axs_reg; uvm_mem axs_mem; + uvm_reg_data_t previous_mirror; bit do_reg_prediction = 1; bit [SOC_IFC_DATA_W-1:0] data_active; bit [ahb_lite_slave_0_params::AHB_WDATA_WIDTH-1:0] address_aligned; @@ -720,8 +721,14 @@ class soc_ifc_predictor #( do_reg_prediction = 1'b0; end else if (axs_reg != null) begin - // Mailbox accesses are discarded based on valid_requester/valid_receiver case (axs_reg.get_name()) inside + // CPTRA_FW_ERROR__FATAL writes only trigger interrupt when + // setting a new bit, so we need the previous value to catch the edges + "CPTRA_FW_ERROR_FATAL", + "CPTRA_FW_ERROR_NON_FATAL": begin + previous_mirror = axs_reg.get_mirrored_value(); + end + // Mailbox accesses are discarded based on valid_requester/valid_receiver "mbox_lock": begin if (ahb_txn.RnW == AHB_READ && ahb_txn.resp[0] != AHB_OKAY) begin do_reg_prediction = 1'b0; @@ -1093,27 +1100,34 @@ class soc_ifc_predictor #( `uvm_info("PRED_AHB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_FULL) end "CPTRA_HW_ERROR_FATAL": begin - if (ahb_txn.RnW == AHB_WRITE && |data_active && (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.get_mirrored_value() == 0)) begin + if (ahb_txn.RnW == AHB_WRITE && |data_active && ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_fatal_mask.get_mirrored_value()) == 0)) begin `uvm_info("PRED_AHB", $sformatf("Write to %s results in all bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) end end "CPTRA_HW_ERROR_NON_FATAL": begin - if (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() == 0) begin + if ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin cptra_error_non_fatal = 1'b0; end end "CPTRA_FW_ERROR_FATAL": begin - if (ahb_txn.RnW == AHB_WRITE && |(data_active && ~p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_FATAL.get_mirrored_value())) begin + if (ahb_txn.RnW == AHB_WRITE && |(~previous_mirror & data_active & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_fatal_mask.get_mirrored_value())) begin `uvm_info("PRED_AHB", $sformatf("Write to %s set a new bit, trigger cptra_error_fatal interrupt", axs_reg.get_name()), UVM_MEDIUM) cptra_error_fatal = 1'b1; send_soc_ifc_sts_txn = 1'b1; end - if (ahb_txn.RnW == AHB_WRITE && |data_active && (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_FATAL.get_mirrored_value() == 0)) begin + else if (ahb_txn.RnW == AHB_WRITE && ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_fatal_mask.get_mirrored_value()) == 0)) begin `uvm_info("PRED_AHB", $sformatf("Write to %s results in all bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) end end "CPTRA_FW_ERROR_NON_FATAL": begin - if (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() == 0) begin + if (ahb_txn.RnW == AHB_WRITE && |(~previous_mirror & data_active & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value())) begin + `uvm_info("PRED_AHB", $sformatf("Write to %s set a new bit, trigger cptra_error_non_fatal interrupt", axs_reg.get_name()), UVM_MEDIUM) + cptra_error_non_fatal = 1'b1; + send_soc_ifc_sts_txn = 1'b1; + end + else if ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin cptra_error_non_fatal = 1'b0; end end @@ -1388,9 +1402,7 @@ class soc_ifc_predictor #( end end "internal_hw_error_fatal_mask", - "internal_hw_error_non_fatal_mask", - "internal_fw_error_fatal_mask", - "internal_fw_error_non_fatal_mask": begin + "internal_fw_error_fatal_mask": begin if (ahb_txn.RnW == AHB_WRITE) begin `uvm_error("PRED_AHB", $sformatf("FIXME - need to add logic for error mask register %s", axs_reg.get_name())) // TODO end @@ -1398,6 +1410,28 @@ class soc_ifc_predictor #( `uvm_info("PRED_AHB", {"Read from ", axs_reg.get_name(), " has no effect"}, UVM_DEBUG) end end + "internal_hw_error_non_fatal_mask": begin + if (ahb_txn.RnW == AHB_WRITE && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin + `uvm_info("PRED_AHB", $sformatf("Write to %s results in deassertion of cptra_error_non_fatal", axs_reg.get_name()), UVM_HIGH) + cptra_error_non_fatal = 1'b0; + end + else begin + `uvm_info("PRED_AHB", {"Access to ", axs_reg.get_name(), " of type ", ahb_txn.RnW.name(), " has no effect"}, UVM_DEBUG) + end + end + "internal_fw_error_non_fatal_mask": begin + if (ahb_txn.RnW == AHB_WRITE && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin + `uvm_info("PRED_AHB", $sformatf("Write to %s results in deassertion of cptra_error_non_fatal", axs_reg.get_name()), UVM_HIGH) + cptra_error_non_fatal = 1'b0; + end + else begin + `uvm_info("PRED_AHB", {"Access to ", axs_reg.get_name(), " of type ", ahb_txn.RnW.name(), " has no effect"}, UVM_DEBUG) + end + end "internal_rv_mtime_l", "internal_rv_mtime_h", "internal_rv_mtimecmp_l", @@ -1646,6 +1680,7 @@ class soc_ifc_predictor #( // pragma uvmf custom apb5_slave_0_ae_predictor begin apb3_host_apb3_transaction #(apb5_master_0_params::APB3_SLAVE_COUNT, apb5_master_0_params::APB3_PADDR_BIT_WIDTH, apb5_master_0_params::APB3_PWDATA_BIT_WIDTH, apb5_master_0_params::APB3_PRDATA_BIT_WIDTH) apb_txn; uvm_reg axs_reg; + uvm_reg_data_t previous_mirror; bit do_reg_prediction = 1; // Flags control whether each transaction is sent to scoreboard @@ -1679,10 +1714,15 @@ class soc_ifc_predictor #( soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end else begin - // Mailbox accesses are discarded based on valid_requester/valid_receiver - // (i.e. PAUSER + state info) - // SHA Accelerator Functions also screened based on PAUSER case (axs_reg.get_name()) inside + // CPTRA_FW_ERROR__FATAL writes only trigger interrupt when + // setting a new bit, so we need the previous value to catch the edges + "CPTRA_FW_ERROR_FATAL", + "CPTRA_FW_ERROR_NON_FATAL": begin + previous_mirror = axs_reg.get_mirrored_value(); + end + // Mailbox accesses are discarded based on valid_requester/valid_receiver + // (i.e. PAUSER + state info) "mbox_lock": begin // RS access policy wants to update lock to 1 on a read, but if the PAUSER value is invalid // lock will not be set. It will hold the previous value. @@ -1784,7 +1824,7 @@ class soc_ifc_predictor #( end end end - //SHA Accelerator Functions + // SHA Accelerator Functions are screened based on PAUSER "LOCK", "USER": begin if (apb_txn.read_or_write == APB3_TRANS_READ && apb_txn.slave_err) begin @@ -1954,6 +1994,10 @@ class soc_ifc_predictor #( next_step = '{dlen_wr: 1'b1, default: 1'b0}; else if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_receive_stage) next_step = '{resp_dlen_wr: 1'b1, default: 1'b0}; + else begin + next_step = '{null_action: 1'b1, default: 1'b0}; + `uvm_info("PRED_APB", $sformatf("Logging unexpected step %p; access to %s while in state %p", next_step, axs_reg.get_name(), p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs), UVM_LOW) + end `uvm_info("PRED_APB", $sformatf("Logged mailbox step [%p]", next_step), UVM_HIGH) end else if (apb_txn.read_or_write == APB3_TRANS_READ) begin @@ -2106,22 +2150,36 @@ class soc_ifc_predictor #( `uvm_info("PRED_APB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_FULL) end "CPTRA_HW_ERROR_FATAL": begin - if (apb_txn.read_or_write == APB3_TRANS_WRITE && |apb_txn.wr_data && (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.get_mirrored_value() == 0)) begin - `uvm_info("PRED_APB", $sformatf("Write to %s results in all bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) + if (apb_txn.read_or_write == APB3_TRANS_WRITE && |apb_txn.wr_data && ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_fatal_mask.get_mirrored_value()) == 0)) begin + `uvm_info("PRED_APB", $sformatf("Write to %s results in all unmasked bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) end end "CPTRA_HW_ERROR_NON_FATAL": begin - if (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() == 0) begin + if ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin + `uvm_info("PRED_APB", $sformatf("Access to %s results in all unmasked bits cleared, which causes deassertion of cptra_error_non_fatal", axs_reg.get_name()), UVM_MEDIUM) cptra_error_non_fatal = 1'b0; end end "CPTRA_FW_ERROR_FATAL": begin - if (apb_txn.read_or_write == APB3_TRANS_WRITE && |apb_txn.wr_data && (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_FATAL.get_mirrored_value() == 0)) begin - `uvm_info("PRED_APB", $sformatf("Write to %s results in all bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) + if (apb_txn.read_or_write == APB3_TRANS_WRITE && |(~previous_mirror & apb_txn.wr_data & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_fatal_mask.get_mirrored_value())) begin + `uvm_info("PRED_APB", $sformatf("Write to %s set a new bit, trigger cptra_error_fatal interrupt", axs_reg.get_name()), UVM_MEDIUM) + cptra_error_fatal = 1'b1; + send_soc_ifc_sts_txn = 1'b1; + end + else if (apb_txn.read_or_write == APB3_TRANS_WRITE && ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_fatal_mask.get_mirrored_value()) == 0)) begin + `uvm_info("PRED_APB", $sformatf("Write to %s results in all unmasked bits cleared, but has no effect on cptra_error_fatal (requires reset)", axs_reg.get_name()), UVM_MEDIUM) end end "CPTRA_FW_ERROR_NON_FATAL": begin - if (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() == 0) begin + if (apb_txn.read_or_write == APB3_TRANS_WRITE && |(~previous_mirror & apb_txn.wr_data & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value())) begin + `uvm_info("PRED_APB", $sformatf("Write to %s set a new bit, trigger cptra_error_non_fatal interrupt", axs_reg.get_name()), UVM_MEDIUM) + cptra_error_non_fatal = 1'b1; + send_soc_ifc_sts_txn = 1'b1; + end + else if ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value()) == 0 && + (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FW_ERROR_NON_FATAL.get_mirrored_value() & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_error_non_fatal_mask.get_mirrored_value()) == 0) begin + `uvm_info("PRED_APB", $sformatf("Access to %s results in all unmasked bits cleared, which causes deassertion of cptra_error_non_fatal", axs_reg.get_name()), UVM_MEDIUM) cptra_error_non_fatal = 1'b0; end end @@ -2493,9 +2551,11 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); // send_soc_ifc_sts_txn = 1'b1; // end // mbox protocol violations - // TODO The interrupt is cleared by warm reset even though reg values are not - the assertion - // should be tied directly to the event detection instead of comparing the interrupt value with the reg mirror value - if (!cptra_error_non_fatal && |p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value()) begin + // The interrupt is cleared by warm reset even though reg values are not - the assertion + // should be tied directly to the event detection instead of comparing the interrupt value with the reg mirror value. + // The difficulty with doing this is that the mbox protocol error delay job doesn't have access to this + // cptra_error_non_fatal signal... solution is to use the hwset_active signal + if (!cptra_error_non_fatal && |(p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.get_mirrored_value() & p_soc_ifc_rm.soc_ifc_reg_rm.hwset_active.cptra_hw_error_non_fatal & ~p_soc_ifc_rm.soc_ifc_reg_rm.internal_hw_error_non_fatal_mask.get_mirrored_value())) begin `uvm_info("PRED_DLY", "Delay job triggers cptra_error_non_fatal output", UVM_HIGH) cptra_error_non_fatal = 1; send_soc_ifc_sts_txn = 1'b1; @@ -2609,8 +2669,8 @@ task soc_ifc_predictor::poll_and_run_delay_jobs(); int idx[$]; time end_time; running_dly_jobs.push_back(process::self()); // This tracks all the delay_jobs that are pending so they can be clobbered on rst - `uvm_info("PRED_DLY", $sformatf("Doing delay of %0d cycles before running delay job with signature: %s", job.get_delay_cycles(), job.get_name()), UVM_HIGH/*UVM_FULL*/) - end_time = $time + 10*job.get_delay_cycles(); + `uvm_info("PRED_DLY", $sformatf("Doing delay of %0d cycles before running delay job with signature: %s", job.get_delay_cycles(), job.get_type_name()), UVM_HIGH/*UVM_FULL*/) + end_time = $time + 10*job.get_delay_cycles(); // FIXME 100MHz implicit clock frequency job_end_count[end_time] += 1; // delay cycles reported as 0's based value, since 1-cycle delay // is inherent to this forever loop @@ -2951,34 +3011,36 @@ task soc_ifc_predictor::wdt_counter_task(); this.t2_count++; if (!($time % 500)) `uvm_info("PRED_WDT", $sformatf("In cascade mode. t2_count increments to 0x%x, wdt_to_period is 0x%x", this.t2_count, wdt_t2_period), UVM_DEBUG) - end - else begin - if (!this.wdt_nmi_intr_sent) begin - `uvm_info("PRED_WDT", "Timer2 expired in cascade mode. Expecting NMI to be handled", UVM_MEDIUM); - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.nmi_pin.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); //TODO: use default map? - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_STATUS.t2_timeout.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); - - //Sending cptra_status_txn in the same clock as NMI - nmi_intr_pending = 1'b1; - populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); - cptra_sb_ap.write(local_cptra_sb_ap_txn); - `uvm_info("PRED_WDT", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) - - // Fatal error interrupt is delayed by 1 cycle due to reg state - fork - configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); - if (!noncore_rst_out_asserted) begin - `uvm_info("PRED_WDT", "Watchdog timeout triggers cptra_error_fatal output", UVM_HIGH) - cptra_error_fatal = 1; - populate_expected_soc_ifc_status_txn(local_soc_ifc_sb_ap_txn); - soc_ifc_sb_ap.write(local_soc_ifc_sb_ap_txn); - `uvm_info("PRED_WDT", "Transaction submitted through soc_ifc_sb_ap", UVM_MEDIUM) - end - join_none - //Set a flag so we don't keep sending transactions while the timer holds value until interrupt - //is serviced or reset - this.wdt_nmi_intr_sent = 1'b1; + //If t2 count expires, send cptra_status_txn in the same clk + if (this.t2_count == wdt_t2_period) begin + if (!this.wdt_nmi_intr_sent) begin + `uvm_info("PRED_WDT", "Timer2 expired in cascade mode. Expecting NMI to be handled", UVM_MEDIUM); + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.nmi_pin.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); //TODO: use default map? + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_STATUS.t2_timeout.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); + + //Sending cptra_status_txn in the same clock as NMI + nmi_intr_pending = 1'b1; + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); + cptra_sb_ap.write(local_cptra_sb_ap_txn); + `uvm_info("PRED_WDT", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) + + // Fatal error interrupt is delayed by 1 cycle due to reg state + fork + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + if (!noncore_rst_out_asserted) begin + `uvm_info("PRED_WDT", "Watchdog timeout triggers cptra_error_fatal output", UVM_HIGH) + cptra_error_fatal = 1; + populate_expected_soc_ifc_status_txn(local_soc_ifc_sb_ap_txn); + soc_ifc_sb_ap.write(local_soc_ifc_sb_ap_txn); + `uvm_info("PRED_WDT", "Transaction submitted through soc_ifc_sb_ap", UVM_MEDIUM) + end + join_none + + //Set a flag so we don't keep sending transactions while the timer holds value until interrupt + //is serviced or reset + this.wdt_nmi_intr_sent = 1'b1; + end end end end diff --git a/src/uart/config/uart.vf b/src/uart/config/uart.vf index 469205a79..5fb62f4db 100644 --- a/src/uart/config/uart.vf +++ b/src/uart/config/uart.vf @@ -63,7 +63,6 @@ ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_sum_tree.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_ext.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_edge_detector.sv ${CALIPTRA_ROOT}/src/uart/rtl/uart_tx.sv -${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_pkg.sv ${CALIPTRA_ROOT}/src/uart/rtl/uart_reg_top.sv ${CALIPTRA_ROOT}/src/uart/rtl/uart_rx.sv ${CALIPTRA_ROOT}/src/uart/rtl/uart.sv diff --git a/tools/scripts/Makefile b/tools/scripts/Makefile old mode 100755 new mode 100644 index 6a7efb724..03c9b10c5 --- a/tools/scripts/Makefile +++ b/tools/scripts/Makefile @@ -16,9 +16,6 @@ PLAYBOOK_RANDOM_SEED ?= $(shell date +%s) BUILD_CFLAGS ?= TEST_CFLAGS = -g -O3 -DMY_RANDOM_SEED=$(PLAYBOOK_RANDOM_SEED) $(BUILD_CFLAGS) - -ABI = -mabi=ilp32 -march=rv32imc - VERILATOR = verilator GCC_PREFIX = riscv64-unknown-elf BUILD_DIR = $(CURDIR) @@ -56,7 +53,8 @@ COMP_LIB_NAMES := aes \ sha256 \ sha512 \ soc_ifc \ - clk_gate + clk_gate \ + wdt COMP_LIBS := $(foreach name, $(COMP_LIB_NAMES), $(CALIPTRA_ROOT)/src/integration/test_suites/libs/$(name)) HEADER_FILES := $(INCLUDES_DIR)/caliptra_defines.h \ $(INCLUDES_DIR)/defines.h \ @@ -69,6 +67,9 @@ HEADER_FILES := $(INCLUDES_DIR)/caliptra_defines.h \ $(ISR_DIR)/veer-csr.h \ $(foreach comp_lib, $(COMP_LIBS), $(wildcard $(comp_lib)/*.h)) +TEST_GEN_FILES := $(CALIPTRA_ROOT)/src/ecc/tb/ecdsa_secp384r1.exe \ + $(CALIPTRA_ROOT)/src/doe/tb/doe_test_gen.py + # Separate OFILE variable since this is not used to build remote images # (i.e. FMC or RunTime) ifeq (0,$(shell test -e $(TEST_DIR)/$(TESTNAME).c && echo $$?)) @@ -165,33 +166,35 @@ CFLAGS += -std=c++17 # compiles), or -O for balance. VERILATOR_MAKE_FLAGS = OPT_FAST="-Os" -# Testbench libs -VERILATOR_TB_LIBS = jtagdpi/jtagdpi.c \ - tcp_server/tcp_server.c +# Testbench DPI sources +TB_DPI_SRCS = jtagdpi/jtagdpi.c \ + tcp_server/tcp_server.c + +TB_DPI_INCS := $(addprefix -I$(CALIPTRA_ROOT)/src/integration/test_suites/libs/,$(dir $(TB_DPI_SRCS))) +TB_DPI_SRCS := $(addprefix $(CALIPTRA_ROOT)/src/integration/test_suites/libs/,$(TB_DPI_SRCS)) # Testbench sources -VERILATOR_TB_SRCS = $(TBDIR)/test_caliptra_top_tb.cpp \ - $(addprefix $(CALIPTRA_ROOT)/src/integration/test_suites/libs/,$(VERILATOR_TB_LIBS)) +TB_VERILATOR_SRCS = $(TBDIR)/test_caliptra_top_tb.cpp $(TB_DPI_SRCS) # Testbench defs -VERILATOR_TB_DEFS = +define+CALIPTRA_INTERNAL_QSPI+CALIPTRA_INTERNAL_TRNG+CALIPTRA_INTERNAL_UART +TB_DEFS = +define+CALIPTRA_INTERNAL_QSPI+CALIPTRA_INTERNAL_TRNG+CALIPTRA_INTERNAL_UART # By default debugging (JTAG) is locked in Caliptra. Add "DEBUG_UNLOCKED=1" to # enable it. ifdef DEBUG_UNLOCKED - VERILATOR_TB_DEFS += +define+CALIPTRA_DEBUG_UNLOCKED + TB_DEFS += +define+CALIPTRA_DEBUG_UNLOCKED endif # To enforce holding the RISC-V core in reset add "FORCE_CPU_RESET=1". ifdef FORCE_CPU_RESET - VERILATOR_TB_DEFS += +define+CALIPTRA_FORCE_CPU_RESET + TB_DEFS += +define+CALIPTRA_FORCE_CPU_RESET endif # Run time arguments from command line VERILATOR_RUN_ARGS ?= "" # Add testbench lib include paths -CFLAGS += $(addprefix -I$(CALIPTRA_ROOT)/src/integration/test_suites/libs/,$(dir $(VERILATOR_TB_LIBS))) +CFLAGS += $(TB_DPI_INCS) # Targets all: clean verilator @@ -207,8 +210,8 @@ clean_fw: ############ Model Builds ############################### -verilator-build: $(TBFILES) $(INCLUDES_DIR)/defines.h $(VERILATOR_TB_SRCS) - $(VERILATOR) $(VERILATOR_TB_SRCS) --cc -CFLAGS "$(CFLAGS)" \ +verilator-build: $(TBFILES) $(INCLUDES_DIR)/defines.h $(TB_VERILATOR_SRCS) + $(VERILATOR) $(TB_VERILATOR_SRCS) --cc -CFLAGS "$(CFLAGS)" \ +libext+.v+.sv +define+RV_OPENSOURCE \ --timescale 1ns/1ps \ --timing \ @@ -217,16 +220,16 @@ verilator-build: $(TBFILES) $(INCLUDES_DIR)/defines.h $(VERILATOR_TB_SRCS) -f $(TBDIR)/../config/caliptra_top_tb.vf --top-module caliptra_top_tb \ -f $(TBDIR)/../config/caliptra_top_tb.vlt \ -exe test_caliptra_top_tb.cpp --autoflush $(VERILATOR_DEBUG) \ - $(VERILATOR_TB_DEFS) + $(TB_DEFS) $(MAKE) -j`nproc` -e -C obj_dir/ -f Vcaliptra_top_tb.mk $(VERILATOR_MAKE_FLAGS) VM_PARALLEL_BUILDS=1 touch verilator-build -vcs-build: $(TBFILES) $(INCLUDES_DIR)/defines.h +vcs-build: $(TBFILES) $(INCLUDES_DIR)/defines.h $(TB_DPI_SRCS) vlogan -full64 -sverilog -kdb -incr_vlogan +lint=IA_CHECKFAIL -assert svaext \ - +define+CLP_ASSERT_ON -noinherit_timescale=1ns/1ps \ + +define+CLP_ASSERT_ON $(TB_DEFS) -noinherit_timescale=1ns/1ps \ -f $(TBDIR)/../config/caliptra_top_tb.vf vcs -full64 -kdb -lca -debug_access+all -j8 +vcs+lic+wait -partcomp -fastpartcomp=j8 \ - -assert enable_hier caliptra_top_tb -o simv.caliptra_top_tb + -assert enable_hier caliptra_top_tb -o simv.caliptra_top_tb +dpi -cflags "$(TB_DPI_INCS)" $(TB_DPI_SRCS) ############ TEST Simulation ############################### @@ -234,6 +237,7 @@ verilator: program.hex verilator-build ./obj_dir/Vcaliptra_top_tb $(VERILATOR_RUN_ARGS) vcs: program.hex vcs-build + cp $(TEST_GEN_FILES) $(BUILD_DIR) ./simv.caliptra_top_tb ############ TEST build ############################### diff --git a/tools/scripts/openocd/target/veer-el2-rst.cfg b/tools/scripts/openocd/target/veer-el2-rst.cfg index 0f4c86fde..c90f24266 100644 --- a/tools/scripts/openocd/target/veer-el2-rst.cfg +++ b/tools/scripts/openocd/target/veer-el2-rst.cfg @@ -4,13 +4,7 @@ if { [info exists CHIPNAME] } { set _CHIPNAME riscv } -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1000008b -} - -jtag newtap $_CHIPNAME tap -irlen 5 -expected-id $_CPUTAPID +jtag newtap $_CHIPNAME tap -irlen 5 set _TARGETNAME $_CHIPNAME.tap target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -rtos hwthread diff --git a/tools/scripts/openocd/target/veer-el2.cfg b/tools/scripts/openocd/target/veer-el2.cfg index 45374886d..a8c092f2a 100644 --- a/tools/scripts/openocd/target/veer-el2.cfg +++ b/tools/scripts/openocd/target/veer-el2.cfg @@ -4,13 +4,7 @@ if { [info exists CHIPNAME] } { set _CHIPNAME riscv } -if { [info exists CPUTAPID ] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1000008b -} - -jtag newtap $_CHIPNAME tap -irlen 5 -expected-id $_CPUTAPID +jtag newtap $_CHIPNAME tap -irlen 5 set _TARGETNAME $_CHIPNAME.tap target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -rtos hwthread