From 02a85d1ab9ff24c5b71d6e6e4d613d4e12ecf999 Mon Sep 17 00:00:00 2001 From: Guillermo Maturana Date: Thu, 19 Dec 2024 01:05:01 +0000 Subject: [PATCH] [ipgen,otp_ctrl] Remove legacy files Fixes #25019 Signed-off-by: Guillermo Maturana --- hw/ip/otp_ctrl/BUILD | 12 - hw/ip/otp_ctrl/README.md | 63 - hw/ip/otp_ctrl/data/BUILD | 32 - hw/ip/otp_ctrl/data/dif_otp_ctrl.c.tpl | 685 -- hw/ip/otp_ctrl/data/dif_otp_ctrl.h.tpl | 615 -- .../data/dif_otp_ctrl_unittest.cc.tpl | 790 --- hw/ip/otp_ctrl/data/otp_ctrl.hjson | 3318 --------- hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl | 1533 ---- hw/ip/otp_ctrl/data/otp_ctrl_base_vseq.sv.tpl | 645 -- hw/ip/otp_ctrl/data/otp_ctrl_cov_bind.sv.tpl | 84 - .../data/otp_ctrl_dai_lock_vseq.sv.tpl | 90 - hw/ip/otp_ctrl/data/otp_ctrl_env_cov.sv.tpl | 358 - hw/ip/otp_ctrl/data/otp_ctrl_env_pkg.sv.tpl | 265 - hw/ip/otp_ctrl/data/otp_ctrl_if.sv.tpl | 350 - hw/ip/otp_ctrl/data/otp_ctrl_part_pkg.sv.tpl | 353 - .../otp_ctrl/data/otp_ctrl_scoreboard.sv.tpl | 1476 ---- .../data/otp_ctrl_sec_cm_testplan.hjson | 303 - .../otp_ctrl/data/otp_ctrl_smoke_vseq.sv.tpl | 255 - hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson | 404 -- hw/ip/otp_ctrl/doc/checklist.md | 271 - hw/ip/otp_ctrl/doc/interfaces.md | 303 - .../doc/otp_ctrl_behavioral_model.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_blockdiag.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_buf_part_fsm.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_dai_fsm.svg | 1 - .../doc/otp_ctrl_digest_mechanism.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_digests.md | 17 - .../doc/otp_ctrl_field_descriptions.md | 101 - hw/ip/otp_ctrl/doc/otp_ctrl_kdi_fsm.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_key_req_ack.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_lci_fsm.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_mmap.md | 122 - hw/ip/otp_ctrl/doc/otp_ctrl_overview.svg | 1 - hw/ip/otp_ctrl/doc/otp_ctrl_partitions.md | 57 - hw/ip/otp_ctrl/doc/otp_ctrl_prim_otp.svg | 1 - .../otp_ctrl/doc/otp_ctrl_unbuf_part_fsm.svg | 1 - hw/ip/otp_ctrl/doc/programmers_guide.md | 261 - hw/ip/otp_ctrl/doc/registers.md | 1043 --- hw/ip/otp_ctrl/doc/theory_of_operation.md | 514 -- hw/ip/otp_ctrl/dv/README.md | 146 - hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov.core | 24 - hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_bind.sv | 93 - .../dv/cov/otp_ctrl_cov_fsm_unr_excl.el | 199 - hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_if.sv | 113 - .../otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el | 6133 ----------------- hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg | 14 - hw/ip/otp_ctrl/dv/doc/tb.svg | 1 - .../dv/env/otp_ctrl_ast_inputs_cfg.sv | 35 - hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core | 59 - hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv | 106 - hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv | 106 - hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv | 389 -- hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv | 266 - hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv | 369 - hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv | 1699 ----- .../dv/env/otp_ctrl_virtual_sequencer.sv | 19 - .../seq_lib/otp_ctrl_background_chks_vseq.sv | 73 - .../dv/env/seq_lib/otp_ctrl_base_vseq.sv | 705 -- .../dv/env/seq_lib/otp_ctrl_callback_vseq.sv | 22 - .../env/seq_lib/otp_ctrl_check_fail_vseq.sv | 32 - .../dv/env/seq_lib/otp_ctrl_common_vseq.sv | 232 - .../dv/env/seq_lib/otp_ctrl_dai_errs_vseq.sv | 51 - .../dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv | 107 - .../dv/env/seq_lib/otp_ctrl_init_fail_vseq.sv | 235 - .../seq_lib/otp_ctrl_low_freq_read_vseq.sv | 68 - .../env/seq_lib/otp_ctrl_macro_errs_vseq.sv | 21 - .../seq_lib/otp_ctrl_parallel_base_vseq.sv | 42 - .../seq_lib/otp_ctrl_parallel_key_req_vseq.sv | 56 - .../seq_lib/otp_ctrl_parallel_lc_esc_vseq.sv | 110 - .../seq_lib/otp_ctrl_parallel_lc_req_vseq.sv | 51 - .../seq_lib/otp_ctrl_partition_walk_vseq.sv | 50 - .../dv/env/seq_lib/otp_ctrl_regwen_vseq.sv | 69 - .../dv/env/seq_lib/otp_ctrl_smoke_vseq.sv | 268 - .../env/seq_lib/otp_ctrl_stress_all_vseq.sv | 81 - .../env/seq_lib/otp_ctrl_test_access_vseq.sv | 44 - .../dv/env/seq_lib/otp_ctrl_vseq_list.sv | 24 - .../dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv | 56 - hw/ip/otp_ctrl/dv/otp_ctrl_sim.core | 34 - hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson | 179 - hw/ip/otp_ctrl/dv/sva/otp_ctrl_bind.sv | 32 - hw/ip/otp_ctrl/dv/sva/otp_ctrl_sva.core | 38 - hw/ip/otp_ctrl/dv/tb.sv | 238 - hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv | 51 - hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core | 19 - hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv | 22 - hw/ip/otp_ctrl/lint/otp_ctrl.vbl | 8 - hw/ip/otp_ctrl/lint/otp_ctrl.vlt | 21 - hw/ip/otp_ctrl/lint/otp_ctrl.waiver | 26 - hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vbl | 8 - hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vlt | 5 - hw/ip/otp_ctrl/lint/otp_ctrl_pkg.waiver | 9 - hw/ip/otp_ctrl/otp_ctrl.core | 103 - hw/ip/otp_ctrl/otp_ctrl_pkg.core | 71 - hw/ip/otp_ctrl/otp_ctrl_prim_reg_top.core | 26 - hw/ip/otp_ctrl/rtl/otp_ctrl.sv | 1570 ----- hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv | 2579 ------- hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv | 858 --- hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv | 105 - hw/ip/otp_ctrl/rtl/otp_ctrl_kdi.sv | 603 -- hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv | 298 - hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv | 397 -- hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv | 821 --- hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv | 667 -- hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv | 531 -- hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv | 327 - hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv | 1467 ---- hw/ip/otp_ctrl/rtl/otp_ctrl_reg_pkg.sv | 1161 ---- hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv | 510 -- hw/ip/otp_ctrl/rtl/otp_ctrl_token_const.sv | 65 - hw/ip/otp_ctrl/syn/constraints.sdc | 50 - .../otp_ctrl/syn/otp_ctrl_gtech_syn_cfg.hjson | 24 - hw/ip/otp_ctrl/syn/otp_ctrl_syn_cfg.hjson | 26 - hw/ip/otp_ctrl/syn/post_elab_gtech.tcl | 9 - 113 files changed, 39457 deletions(-) delete mode 100644 hw/ip/otp_ctrl/BUILD delete mode 100644 hw/ip/otp_ctrl/README.md delete mode 100644 hw/ip/otp_ctrl/data/BUILD delete mode 100644 hw/ip/otp_ctrl/data/dif_otp_ctrl.c.tpl delete mode 100644 hw/ip/otp_ctrl/data/dif_otp_ctrl.h.tpl delete mode 100644 hw/ip/otp_ctrl/data/dif_otp_ctrl_unittest.cc.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl.hjson delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_base_vseq.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_cov_bind.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_dai_lock_vseq.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_env_cov.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_env_pkg.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_if.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_part_pkg.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_scoreboard.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_sec_cm_testplan.hjson delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_smoke_vseq.sv.tpl delete mode 100644 hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson delete mode 100644 hw/ip/otp_ctrl/doc/checklist.md delete mode 100644 hw/ip/otp_ctrl/doc/interfaces.md delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_behavioral_model.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_blockdiag.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_buf_part_fsm.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_dai_fsm.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_digest_mechanism.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_digests.md delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_field_descriptions.md delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_kdi_fsm.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_key_req_ack.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_lci_fsm.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_mmap.md delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_overview.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_partitions.md delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_prim_otp.svg delete mode 100644 hw/ip/otp_ctrl/doc/otp_ctrl_unbuf_part_fsm.svg delete mode 100644 hw/ip/otp_ctrl/doc/programmers_guide.md delete mode 100644 hw/ip/otp_ctrl/doc/registers.md delete mode 100644 hw/ip/otp_ctrl/doc/theory_of_operation.md delete mode 100644 hw/ip/otp_ctrl/dv/README.md delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov.core delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_bind.sv delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_fsm_unr_excl.el delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_if.sv delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el delete mode 100644 hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg delete mode 100644 hw/ip/otp_ctrl/dv/doc/tb.svg delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_ast_inputs_cfg.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_background_chks_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_callback_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_common_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_errs_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_init_fail_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_low_freq_read_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_macro_errs_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_parallel_base_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_parallel_key_req_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_parallel_lc_esc_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_parallel_lc_req_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_partition_walk_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_regwen_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_stress_all_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_test_access_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv delete mode 100644 hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv delete mode 100644 hw/ip/otp_ctrl/dv/otp_ctrl_sim.core delete mode 100644 hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson delete mode 100644 hw/ip/otp_ctrl/dv/sva/otp_ctrl_bind.sv delete mode 100644 hw/ip/otp_ctrl/dv/sva/otp_ctrl_sva.core delete mode 100644 hw/ip/otp_ctrl/dv/tb.sv delete mode 100644 hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv delete mode 100644 hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core delete mode 100644 hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl.vbl delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl.vlt delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl.waiver delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vbl delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vlt delete mode 100644 hw/ip/otp_ctrl/lint/otp_ctrl_pkg.waiver delete mode 100644 hw/ip/otp_ctrl/otp_ctrl.core delete mode 100644 hw/ip/otp_ctrl/otp_ctrl_pkg.core delete mode 100644 hw/ip/otp_ctrl/otp_ctrl_prim_reg_top.core delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_kdi.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_reg_pkg.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv delete mode 100644 hw/ip/otp_ctrl/rtl/otp_ctrl_token_const.sv delete mode 100644 hw/ip/otp_ctrl/syn/constraints.sdc delete mode 100644 hw/ip/otp_ctrl/syn/otp_ctrl_gtech_syn_cfg.hjson delete mode 100644 hw/ip/otp_ctrl/syn/otp_ctrl_syn_cfg.hjson delete mode 100644 hw/ip/otp_ctrl/syn/post_elab_gtech.tcl diff --git a/hw/ip/otp_ctrl/BUILD b/hw/ip/otp_ctrl/BUILD deleted file mode 100644 index a62d75c1b6c99..0000000000000 --- a/hw/ip/otp_ctrl/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "all_files", - srcs = glob(["**"]) + [ - "//hw/ip/otp_ctrl/data:all_files", - ], -) diff --git a/hw/ip/otp_ctrl/README.md b/hw/ip/otp_ctrl/README.md deleted file mode 100644 index 343f2d3a2e499..0000000000000 --- a/hw/ip/otp_ctrl/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# OTP Controller Technical Specification - -[`otp_ctrl`](https://reports.opentitan.org/hw/ip/otp_ctrl/dv/latest/report.html): -![](https://dashboards.lowrisc.org/badges/dv/otp_ctrl/test.svg) -![](https://dashboards.lowrisc.org/badges/dv/otp_ctrl/passing.svg) -![](https://dashboards.lowrisc.org/badges/dv/otp_ctrl/functional.svg) -![](https://dashboards.lowrisc.org/badges/dv/otp_ctrl/code.svg) - -# Overview - -This document specifies the functionality of the one time programmable (OTP) memory controller. -The OTP controller is a module that is a peripheral on the chip interconnect bus, and thus follows the [Comportability Specification](../../../doc/contributing/hw/comportability/README.md). - -The OTP is a module that provides a device with one-time-programming functionality. -The result of this programming is non-volatile, and unlike flash, cannot be reversed. -The OTP functionality is constructed through an open-source OTP controller and a proprietary OTP IP. - -The OTP controller provides: -- An open-source abstraction interface that software can use to interact with a proprietary OTP block underneath. -- An open-source abstraction interface that hardware components (for example [life cycle controller](../lc_ctrl/README.md) and [key manager](../keymgr/README.md)) can use to interact with a proprietary OTP block underneath. -- High level logical security protection, such as integrity checks and scrambling of sensitive content. -- Software isolation for when OTP contents are readable and programmable. - -The proprietary OTP IP provides: -- Reliable, non-volatile storage. -- Technology-specific redundancy or error correction mechanisms. -- Physical defensive features such as SCA and FI resistance. -- Visual and electrical probing resistance. - -Together, the OTP controller and IP provide secure one-time-programming functionality that is used throughout the life cycle (LC) of a device. - -## Features - -- Multiple logical partitions of the underlying OTP IP - - Each partition is lockable and integrity checked - - Integrity digests are stored alongside each logical bank -- Periodic / persistent checks of OTP values - - Periodic checks of shadowed content vs digests - - Periodic checks of OTP stored content and shadowed content - - Persistent checks for immediate errors -- Separate life cycle partition and interface to life cycle controller - - Supports life cycle functions, but cannot be integrity locked -- Lightweight scrambling of secret OTP partition using a global netlist constant -- Lightweight ephemeral key derivation function for RAM scrambling mechanisms -- Lightweight key derivation function for FLASH scrambling mechanism - -## OTP Controller Overview - -The functionality of OTP is split into an open-source and a closed-source part, with a clearly defined boundary in between, as illustrated in the simplified high-level block diagram below. - -![OTP Controller Overview](./doc/otp_ctrl_overview.svg) - -It is the task of the open-source controller to provide a common, non-technology specific interface to OTP users with a common register interface and a clearly defined I/O interface to hardware. -The open-source controller implements logical isolation and partitioning of OTP storage that enables users to separate different functions of the OTP into "partitions" with different properties. -Finally, the open-source controller provides a high level of security for specific partitions by provisioning integrity digests for each partition, and scrambling of partitions where required. - -The proprietary IP on the other hand translates a common access interface to the technology-specific OTP interface, both for functional and debug accesses (for example register accesses to the macro-internal control structure). - -This split implies that every proprietary OTP IP must implement a translation layer from a standardized OpenTitan interface to the module underneath. -It also implies that no matter how the OTP storage or word size may change underneath, the open-source controller must present a consistent and coherent software and hardware interface. -This standardized interface is defined further below, and the wrapper leverages the same [technology primitive mechanism](../prim/README.md) that is employed in other parts of OpenTitan in order to wrap and abstract technology-specific macros (such as memories and clocking cells) that are potentially closed-source. - -In order to enable simulation and FPGA emulation of the OTP controller even without access to the proprietary OTP IP, a generalized and synthesizable model of the OTP IP is provided in the form of a [generic technology primitive](https://github.com/lowRISC/opentitan/blob/master/hw/ip/prim_generic/rtl/prim_generic_otp.sv). diff --git a/hw/ip/otp_ctrl/data/BUILD b/hw/ip/otp_ctrl/data/BUILD deleted file mode 100644 index c8cacec5b985d..0000000000000 --- a/hw/ip/otp_ctrl/data/BUILD +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -load( - "//rules:autogen.bzl", - "autogen_hjson_c_header", - "autogen_hjson_rust_header", -) - -autogen_hjson_c_header( - name = "otp_ctrl_c_regs", - srcs = [ - "otp_ctrl.hjson", - ], - node = "core", -) - -autogen_hjson_rust_header( - name = "otp_ctrl_rust_regs", - srcs = [ - "otp_ctrl.hjson", - ], - node = "core", -) - -filegroup( - name = "all_files", - srcs = glob(["**"]), -) diff --git a/hw/ip/otp_ctrl/data/dif_otp_ctrl.c.tpl b/hw/ip/otp_ctrl/data/dif_otp_ctrl.c.tpl deleted file mode 100644 index 24266ccbdaff1..0000000000000 --- a/hw/ip/otp_ctrl/data/dif_otp_ctrl.c.tpl +++ /dev/null @@ -1,685 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -parts = otp_mmap.config["partitions"] -digest_parts = [part for part in parts if - part["hw_digest"] or part["sw_digest"]] -read_locked_csr_parts = [part for part in parts if part["read_lock"] == "CSR"] -secret_parts = [part for part in parts if part["secret"]] -%>\ -#include "sw/device/lib/dif/dif_otp_ctrl.h" - -#include - -#include "sw/device/lib/base/bitfield.h" -#include "sw/device/lib/base/macros.h" -#include "sw/device/lib/dif/dif_base.h" - -#include "otp_ctrl_regs.h" // Generated. - -/** - * Checks if integrity/consistency-check-related operations are locked. - * - * This is a convenience function to avoid superfluous error-checking in all the - * functions that can be locked out by this register. - * - * @param check_config True to check the config regwen. False to check the - * trigger regwen. - */ -static bool checks_are_locked(const dif_otp_ctrl_t *otp, bool check_config) { - ptrdiff_t reg_offset = check_config - ? OTP_CTRL_CHECK_REGWEN_REG_OFFSET - : OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET; - size_t regwen_bit = - check_config ? OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT - : OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT; - uint32_t locked = mmio_region_read32(otp->base_addr, reg_offset); - return !bitfield_bit32_read(locked, regwen_bit); -} - -dif_result_t dif_otp_ctrl_configure(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_config_t config) { - if (otp == NULL) { - return kDifBadArg; - } - if (checks_are_locked(otp, /*check_config=*/true)) { - return kDifLocked; - } - - mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TIMEOUT_REG_OFFSET, - config.check_timeout); - mmio_region_write32(otp->base_addr, - OTP_CTRL_INTEGRITY_CHECK_PERIOD_REG_OFFSET, - config.integrity_period_mask); - mmio_region_write32(otp->base_addr, - OTP_CTRL_CONSISTENCY_CHECK_PERIOD_REG_OFFSET, - config.consistency_period_mask); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_check_integrity(const dif_otp_ctrl_t *otp) { - if (otp == NULL) { - return kDifBadArg; - } - if (checks_are_locked(otp, /*check_config=*/false)) { - return kDifLocked; - } - - uint32_t reg = - bitfield_bit32_write(0, OTP_CTRL_CHECK_TRIGGER_INTEGRITY_BIT, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_check_consistency(const dif_otp_ctrl_t *otp) { - if (otp == NULL) { - return kDifBadArg; - } - if (checks_are_locked(otp, /*check_config=*/false)) { - return kDifLocked; - } - - uint32_t reg = - bitfield_bit32_write(0, OTP_CTRL_CHECK_TRIGGER_CONSISTENCY_BIT, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_lock(const dif_otp_ctrl_t *otp) { - if (otp == NULL) { - return kDifBadArg; - } - - uint32_t reg = bitfield_bit32_write( - 0, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, false); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, - reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked) { - if (otp == NULL || is_locked == NULL) { - return kDifBadArg; - } - - uint32_t reg = mmio_region_read32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET); - *is_locked = !bitfield_bit32_read( - reg, OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp) { - if (otp == NULL) { - return kDifBadArg; - } - - uint32_t reg = - bitfield_bit32_write(0, OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false); - mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_REGWEN_REG_OFFSET, reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_config_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked) { - if (otp == NULL || is_locked == NULL) { - return kDifBadArg; - } - - *is_locked = checks_are_locked(otp, /*check_config=*/true); - return kDifOk; -} - -dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp) { - if (otp == NULL) { - return kDifBadArg; - } - - uint32_t reg = bitfield_bit32_write( - 0, OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false); - mmio_region_write32(otp->base_addr, OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked) { - if (otp == NULL || is_locked == NULL) { - return kDifBadArg; - } - - *is_locked = checks_are_locked(otp, /*check_config=*/false); - return kDifOk; -} - -static bool sw_read_lock_reg_offset(dif_otp_ctrl_partition_t partition, - ptrdiff_t *reg_offset, - bitfield_bit32_index_t *index) { - switch (partition) { -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_define = part_name.as_c_define() - index_line = f"*index = OTP_CTRL_{part_name_define}_READ_LOCK_{part_name_define}_READ_LOCK_BIT;" -%>\ - case kDifOtpCtrlPartition${part_name.as_camel_case()}: - *reg_offset = OTP_CTRL_${part_name_define}_READ_LOCK_REG_OFFSET; - % if len(index_line) > 80 - 6: - *index = - OTP_CTRL_${part_name_define}_READ_LOCK_${part_name_define}_READ_LOCK_BIT; - % else: - ${index_line} - % endif - break; -% endfor - default: - return false; - } - return true; -} - -dif_result_t dif_otp_ctrl_lock_reading(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition) { - if (otp == NULL) { - return kDifBadArg; - } - - ptrdiff_t offset; - bitfield_bit32_index_t index; - if (!sw_read_lock_reg_offset(partition, &offset, &index)) { - return kDifBadArg; - } - - uint32_t reg = bitfield_bit32_write(0, index, false); - mmio_region_write32(otp->base_addr, offset, reg); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_reading_is_locked(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - bool *is_locked) { - if (otp == NULL || is_locked == NULL) { - return kDifBadArg; - } - - ptrdiff_t offset; - bitfield_bit32_index_t index; - if (!sw_read_lock_reg_offset(partition, &offset, &index)) { - return kDifBadArg; - } - - uint32_t reg = mmio_region_read32(otp->base_addr, offset); - *is_locked = !bitfield_bit32_read(reg, index); - return kDifOk; -} - -dif_result_t dif_otp_ctrl_get_status(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_status_t *status) { - if (otp == NULL || status == NULL) { - return kDifBadArg; - } - - static const bitfield_bit32_index_t kIndices[] = { -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - lhs = f'[kDifOtpCtrlStatusCode{part_name.as_camel_case()}Error]' - rhs = f'OTP_CTRL_STATUS_{part_name.as_c_define()}_ERROR_BIT' - line = f'{lhs} = {rhs},' -%>\ - % if len(line) > 80 - 6: - ${lhs} = - ${rhs}, - % else: - ${line} - % endif -% endfor - [kDifOtpCtrlStatusCodeDaiError] = OTP_CTRL_STATUS_DAI_ERROR_BIT, - [kDifOtpCtrlStatusCodeLciError] = OTP_CTRL_STATUS_LCI_ERROR_BIT, - [kDifOtpCtrlStatusCodeTimeoutError] = OTP_CTRL_STATUS_TIMEOUT_ERROR_BIT, - [kDifOtpCtrlStatusCodeLfsrError] = OTP_CTRL_STATUS_LFSR_FSM_ERROR_BIT, - [kDifOtpCtrlStatusCodeScramblingError] = - OTP_CTRL_STATUS_SCRAMBLING_FSM_ERROR_BIT, - [kDifOtpCtrlStatusCodeKdfError] = OTP_CTRL_STATUS_KEY_DERIV_FSM_ERROR_BIT, - [kDifOtpCtrlStatusCodeBusIntegError] = - OTP_CTRL_STATUS_BUS_INTEG_ERROR_BIT, - [kDifOtpCtrlStatusCodeDaiIdle] = OTP_CTRL_STATUS_DAI_IDLE_BIT, - [kDifOtpCtrlStatusCodeCheckPending] = OTP_CTRL_STATUS_CHECK_PENDING_BIT, - }; - - status->codes = 0; - uint32_t status_code = - mmio_region_read32(otp->base_addr, OTP_CTRL_STATUS_REG_OFFSET); - for (int i = 0; i < ARRAYSIZE(kIndices); ++i) { - // If the error is not present at all, we clear its cause bit if relevant, - // and bail immediately. - if (!bitfield_bit32_read(status_code, kIndices[i])) { - if (i <= kDifOtpCtrlStatusCodeHasCauseLast) { - status->causes[i] = kDifOtpCtrlErrorOk; - } - continue; - } - - status->codes = - bitfield_bit32_write(status->codes, (bitfield_bit32_index_t)i, true); - - if (i <= kDifOtpCtrlStatusCodeHasCauseLast) { - bitfield_field32_t field; - field = (bitfield_field32_t){ - .mask = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_MASK, - .index = OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET, - }; - - ptrdiff_t address = - OTP_CTRL_ERR_CODE_0_REG_OFFSET + i * (ptrdiff_t)sizeof(uint32_t); - uint32_t error_code = mmio_region_read32(otp->base_addr, address); - - dif_otp_ctrl_error_t err; - switch (bitfield_field32_read(error_code, field)) { - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_NO_ERROR: - err = kDifOtpCtrlErrorOk; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR: - err = kDifOtpCtrlErrorMacroUnspecified; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR: - err = kDifOtpCtrlErrorMacroRecoverableRead; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_UNCORR_ERROR: - err = kDifOtpCtrlErrorMacroUnrecoverableRead; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_WRITE_BLANK_ERROR: - err = kDifOtpCtrlErrorMacroBlankCheckFailed; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_ACCESS_ERROR: - err = kDifOtpCtrlErrorLockedAccess; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_CHECK_FAIL_ERROR: - err = kDifOtpCtrlErrorBackgroundCheckFailed; - break; - case OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_FSM_STATE_ERROR: - err = kDifOtpCtrlErrorFsmBadState; - break; - default: - return kDifError; - } - status->causes[i] = err; - } - } - - return kDifOk; -} - -typedef struct partition_info { - /** - * The absolute OTP address at which this partition starts. - */ - uint32_t start_addr; - /** - * The length of this partition, in bytes, including the digest. - * - * If the partition has a digest, it is expected to be at address - * `start_addr + len - sizeof(uint64_t)`. - */ - uint32_t len; - /** - * The alignment mask for this partition. - * - * A valid address for this partition must be such that - * `addr & align_mask == 0`. - */ - uint32_t align_mask; - - /** - * Whether this is a software-managed partition with a software-managed - * digest. - */ - bool is_software; - - /** - * Whether this partition has a digest field. - */ - bool has_digest; - - /** - * Whether this partition is the lifecycle partition. - */ - bool is_lifecycle; -} partition_info_t; - -// This is generates too many lines with different formatting variants, so -// We opt to just disable formatting. -// clang-format off -static const partition_info_t kPartitions[] = { -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() - has_digest = part["hw_digest"] or part["sw_digest"] - is_lifecycle = part["variant"] == "LifeCycle" - is_software = part["variant"] == "Unbuffered" -%>\ - [kDifOtpCtrlPartition${part_name_camel}] = { - .start_addr = OTP_CTRL_PARAM_${part_name_define}_OFFSET, - .len = OTP_CTRL_PARAM_${part_name_define}_SIZE, - .align_mask = ${"0x7" if part in secret_parts else "0x3"}, - .is_software = ${"true" if is_software else "false"}, - .has_digest = ${"true" if has_digest else "false"}, - .is_lifecycle = ${"true" if is_lifecycle else "false"}}, -% endfor -}; -// clang-format on - -dif_result_t dif_otp_ctrl_relative_address(dif_otp_ctrl_partition_t partition, - uint32_t abs_address, - uint32_t *relative_address) { - *relative_address = 0; - - if (partition >= ARRAYSIZE(kPartitions)) { - return kDifBadArg; - } - - if ((abs_address & kPartitions[partition].align_mask) != 0) { - return kDifUnaligned; - } - - if (abs_address < kPartitions[partition].start_addr) { - return kDifOutOfRange; - } - - *relative_address = abs_address - kPartitions[partition].start_addr; - if (*relative_address >= kPartitions[partition].len) { - *relative_address = 0; - return kDifOutOfRange; - } - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_read_start(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address) { - if (otp == NULL || partition >= ARRAYSIZE(kPartitions)) { - return kDifBadArg; - } - - if ((address & kPartitions[partition].align_mask) != 0) { - return kDifUnaligned; - } - - if (address >= kPartitions[partition].len) { - return kDifOutOfRange; - } - - address += kPartitions[partition].start_addr; - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - address); - - uint32_t cmd = - bitfield_bit32_write(0, OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - cmd); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp, - uint32_t *value) { - if (otp == NULL || value == NULL) { - return kDifBadArg; - } - - *value = mmio_region_read32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET); - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp, - uint64_t *value) { - if (otp == NULL || value == NULL) { - return kDifBadArg; - } - - *value = mmio_region_read32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET); - *value <<= 32; - *value |= mmio_region_read32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET); - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_program32(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint32_t value) { - if (otp == NULL || partition >= ARRAYSIZE(kPartitions)) { - return kDifBadArg; - } - - // Ensure that we are writing to a 32-bit-access partition by checking that - // the alignment mask is 0b11. - // - // Note furthermore that the LC partition is *not* writeable, so we eject - // here. - if (kPartitions[partition].align_mask != 0x3 || - kPartitions[partition].is_lifecycle) { - return kDifError; - } - - if ((address & kPartitions[partition].align_mask) != 0) { - return kDifUnaligned; - } - - // NOTE: The bounds check is tightened here, since we disallow writing the - // digest directly. If the partition does not have a digest, no tightening is - // needed. - size_t digest_size = kPartitions[partition].has_digest * sizeof(uint64_t); - if (address >= kPartitions[partition].len - digest_size) { - return kDifOutOfRange; - } - - address += kPartitions[partition].start_addr; - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - address); - - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, - value); - - uint32_t cmd = - bitfield_bit32_write(0, OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - cmd); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_program64(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint64_t value) { - if (otp == NULL || partition >= ARRAYSIZE(kPartitions)) { - return kDifBadArg; - } - - // Ensure that we are writing to a 64-bit-access partition by checking that - // the alignment mask is 0b111. - if (kPartitions[partition].align_mask != 0x7) { - return kDifError; - } - - if ((address & kPartitions[partition].align_mask) != 0) { - return kDifUnaligned; - } - - // NOTE: The bounds check is tightened here, since we disallow writing the - // digest directly. - size_t digest_size = sizeof(uint64_t); - if (address >= kPartitions[partition].len - digest_size) { - return kDifOutOfRange; - } - - address += kPartitions[partition].start_addr; - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - address); - - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, - value & UINT32_MAX); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, - value >> 32); - - uint32_t cmd = - bitfield_bit32_write(0, OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - cmd); - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_dai_digest(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint64_t digest) { - if (otp == NULL || partition >= ARRAYSIZE(kPartitions)) { - return kDifBadArg; - } - - // Not all partitions have a digest. - if (!kPartitions[partition].has_digest) { - return kDifError; - } - - // For software partitions, the digest must be nonzero; for all other - // partitions it must be zero. - bool is_sw = kPartitions[partition].is_software; - if (is_sw == (digest == 0)) { - return kDifBadArg; - } - - uint32_t address = kPartitions[partition].start_addr; - if (is_sw) { - address += kPartitions[partition].len - sizeof(digest); - } - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - address); - - if (digest != 0) { - mmio_region_write32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, - digest & 0xffffffff); - mmio_region_write32(otp->base_addr, - OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, - digest >> 32); - } - - bitfield_bit32_index_t cmd_bit = is_sw - ? OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT - : OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT; - uint32_t cmd = bitfield_bit32_write(0, cmd_bit, true); - mmio_region_write32(otp->base_addr, OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - cmd); - - return kDifOk; -} - -static bool get_digest_regs(dif_otp_ctrl_partition_t partition, ptrdiff_t *reg0, - ptrdiff_t *reg1) { - switch (partition) { -% for part in digest_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_define = part_name.as_c_define() -%>\ - case kDifOtpCtrlPartition${part_name.as_camel_case()}: - *reg0 = OTP_CTRL_${part_name_define}_DIGEST_0_REG_OFFSET; - *reg1 = OTP_CTRL_${part_name_define}_DIGEST_1_REG_OFFSET; - break; -% endfor - default: - return false; - } - - return true; -} - -dif_result_t dif_otp_ctrl_is_digest_computed(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - bool *is_computed) { - if (otp == NULL || is_computed == NULL) { - return kDifBadArg; - } - - ptrdiff_t reg0, reg1; - if (!get_digest_regs(partition, ®0, ®1)) { - return kDifBadArg; - } - - uint64_t value = mmio_region_read32(otp->base_addr, reg1); - value <<= 32; - value |= mmio_region_read32(otp->base_addr, reg0); - - *is_computed = value != 0; - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_get_digest(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint64_t *digest) { - if (otp == NULL || digest == NULL) { - return kDifBadArg; - } - - ptrdiff_t reg0, reg1; - if (!get_digest_regs(partition, ®0, ®1)) { - return kDifBadArg; - } - - uint64_t value = mmio_region_read32(otp->base_addr, reg1); - value <<= 32; - value |= mmio_region_read32(otp->base_addr, reg0); - - if (value == 0) { - return kDifError; - } - *digest = value; - - return kDifOk; -} - -dif_result_t dif_otp_ctrl_read_blocking(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint32_t *buf, - size_t len) { - if (otp == NULL || partition >= ARRAYSIZE(kPartitions) || buf == NULL) { - return kDifBadArg; - } - - if (!kPartitions[partition].is_software) { - return kDifError; - } - - if ((address & kPartitions[partition].align_mask) != 0) { - return kDifUnaligned; - } - - if (address + len >= kPartitions[partition].len) { - return kDifOutOfRange; - } - - uint32_t reg_offset = OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET + - kPartitions[partition].start_addr + address; - mmio_region_memcpy_from_mmio32(otp->base_addr, reg_offset, buf, - len * sizeof(uint32_t)); - return kDifOk; -} diff --git a/hw/ip/otp_ctrl/data/dif_otp_ctrl.h.tpl b/hw/ip/otp_ctrl/data/dif_otp_ctrl.h.tpl deleted file mode 100644 index 7699db5f2912e..0000000000000 --- a/hw/ip/otp_ctrl/data/dif_otp_ctrl.h.tpl +++ /dev/null @@ -1,615 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -parts = otp_mmap.config["partitions"] -digest_parts = [part for part in parts if - part["hw_digest"] == "true" or part["sw_digest"] == "true"] -read_locked_csr_parts = [part for part in parts if part["read_lock"] == "CSR"] -secret_parts = [part for part in parts if part["secret"] == "true"] -%>\ -#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_ -#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_ - -/** - * @file - * @brief OTP Controller Device Interface - * Functions - */ - -#include - -#include "sw/device/lib/base/macros.h" -#include "sw/device/lib/base/mmio.h" -#include "sw/device/lib/dif/dif_base.h" - -#include "sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h" - -// Header Extern Guard (so header can be used from C and C++) -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * A partition within OTP memory. - */ -typedef enum dif_otp_ctrl_partition { -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - short_desc = part["desc"].split(".")[0].strip().replace("\n", " ") - long_desc_lines = part["desc"].split(".", 1)[1].strip().splitlines() - long_desc = "\n".join([" *" + (" " if line else "") + line for - line in long_desc_lines]) -%>\ - /** - * ${short_desc}. - * - % if long_desc: -${long_desc} - %endif - */ - kDifOtpCtrlPartition${part_name.as_camel_case()}, -% endfor -} dif_otp_ctrl_partition_t; - -/** - * Runtime configuration for OTP. - * - * This struct describes runtime information for one-time configuration of the - * hardware. - */ -typedef struct dif_otp_ctrl_config { - /** - * The timeout for an integrity or consistency check to succeed, in cycles. - * - * 100'000 is recommended as a minimum safe value. - */ - uint32_t check_timeout; - /** - * A mask for the pseudo-random integrity check period. - * - * The value of this mask limits the period of the integrity check; when the - * pseudo-random period is computed, this mask is applied to limit it. For - * example, a value of 0x3'ffff would correspond to a maximum period of about - * 2.8s at 24MHz. - * - * A value of zero disables the check. - */ - uint32_t integrity_period_mask; - /** - * A mask for the pseudo-random consistency check period. - * - * The value of this mask limits the period of the consistency check; when the - * pseudo-random period is computed, this mask is applied to limit it. For - * example, a value of 0x3ff'ffff would correspond to a maximum period of - * about 716s at 24MHz. - * - * A value of zero disables the check. - */ - uint32_t consistency_period_mask; -} dif_otp_ctrl_config_t; - -/** - * A hardware-level status code. - */ -typedef enum dif_otp_ctrl_status_code { - // NOTE: This enum's API *requires* that all "error"-like codes (that is, - // those which have associated cause registers) be a prefix of the enum - // values. - // - // Note furthermore that these enum variants are intended as bit indices, so - // their values should not be randomized. -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - /** - * Indicates an error occurred in the `${part_name_camel}` partition. - */ - kDifOtpCtrlStatusCode${part_name_camel}Error${" = 0" if loop.first else ""}, -% endfor - /** - * Indicates an error occurred in the direct access interface. - */ - kDifOtpCtrlStatusCodeDaiError, - /** - * Indicates an error occurred in the lifecycle interface. - */ - kDifOtpCtrlStatusCodeLciError, - /** - * This is not a status code; rather, it represents the last error code which - * has a corresponding "cause" register. - * - * See `dif_otp_ctrl_status_t` for information on how to use this. - */ - kDifOtpCtrlStatusCodeHasCauseLast = kDifOtpCtrlStatusCodeLciError, - /** - * Indicates that an integrity or consistency check has timed out. - * - * This error is unrecoverable. - */ - kDifOtpCtrlStatusCodeTimeoutError, - /** - * Indicates that the LFSR that generates pseudo-random integrity and - * consistency checks is in a bad state. - * - * This error is unrecoverable. - */ - kDifOtpCtrlStatusCodeLfsrError, - /** - * Indicates that the scrambling hardware is in a bad state. - * - * This error is unrecoverable. - */ - kDifOtpCtrlStatusCodeScramblingError, - /** - * Indicates that the key derivation hardware is in a bad state. - * - * This error is unrecoverable. - */ - kDifOtpCtrlStatusCodeKdfError, - /** - * Indicates a bus integrity error. - * - * This error will raise an alert. - */ - kDifOtpCtrlStatusCodeBusIntegError, - /** - * Indicates that the direct access interface is idle. - */ - kDifOtpCtrlStatusCodeDaiIdle, - /** - * Indicates that an integrity or consistency check is currently pending. - */ - kDifOtpCtrlStatusCodeCheckPending, -} dif_otp_ctrl_status_code_t; - -/** - * A hardware-level error code, associated with a particular error defined in - * `dif_otp_ctrl_status_t`. - */ -typedef enum dif_otp_ctrl_error { - /** - * Indicates no error. - */ - kDifOtpCtrlErrorOk, - /** - * Indicates that an OTP macro command was invalid or did not - * complete successfully. - * - * This error indicates non-recoverable hardware malfunction. - */ - kDifOtpCtrlErrorMacroUnspecified, - /** - * Indicates a recoverable error during a read operation. - * - * A followup read should work as expected. - */ - kDifOtpCtrlErrorMacroRecoverableRead, - /** - * Indicates an unrecoverable error during a read operation. - * - * This error indicates non-recoverable hardware malfunction. - */ - kDifOtpCtrlErrorMacroUnrecoverableRead, - /** - * Indicates that the blank write check failed during a write operation. - */ - kDifOtpCtrlErrorMacroBlankCheckFailed, - /** - * Indicates a locked memory region was accessed. - */ - kDifOtpCtrlErrorLockedAccess, - /** - * Indicates a parity, integrity or consistency check failed in the buffer - * registers. - * - * This error indicates non-recoverable hardware malfunction. - */ - kDifOtpCtrlErrorBackgroundCheckFailed, - /** - * Indicates that the FSM of the controller is in a bad state or that the - * controller's FSM has been moved into its terminal state due to escalation - * via the alert subsystem. - * - * This error indicates that the device has been glitched by an attacker. - */ - kDifOtpCtrlErrorFsmBadState, -} dif_otp_ctrl_error_t; - -/** - * The overall status of the OTP controller. - * - * See `dif_otp_ctrl_get_status()`. - */ -typedef struct dif_otp_ctrl_status { - /** - * Currently active statuses, given as a bit vector. To check whether a - * particular status code was returned, write - * - * bool has_code = (status.codes >> kMyStatusCode) & 1; - * - * Note that it is possible to quickly check that the controller is idle and - * error-free by writing - * - * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle); - */ - uint32_t codes; - /** - * A list of root causes for each error status code. - * - * If the error status code `error` is present in `codes`, and - * `error <= kDifOtpCtrlStatusCodeHasCauseLast`, then `causes[error]` - * will contain its root cause. - */ - dif_otp_ctrl_error_t causes[kDifOtpCtrlStatusCodeHasCauseLast + 1]; -} dif_otp_ctrl_status_t; - -/** - * Configures OTP with runtime information. - * - * This function should need to be called at most once for the lifetime of - * `otp`. - * - * @param otp An OTP handle. - * @param config Runtime configuration parameters. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_configure(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_config_t config); - -/** - * Runs an integrity check on the OTP hardware. - * - * This function can be used to trigger an integrity check independent of the - * pseudo-random hardware-generated checks. - * - * @param otp An OTP handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_check_integrity(const dif_otp_ctrl_t *otp); - -/** - * Runs a consistency check on the OTP hardware. - * - * This function can be used to trigger a consistency check independent of the - * pseudo-random hardware-generated checks. - * - * @param otp An OTP handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_check_consistency(const dif_otp_ctrl_t *otp); - -/** - * Locks out access to the direct access interface registers. - * - * This function is idempotent: calling it while functionality is locked will - * have no effect and return `kDifOk`. - * - * @param otp An OTP handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_lock(const dif_otp_ctrl_t *otp); - -/** - * Checks whether access to the direct access interface is locked. - * - * Note that besides locking the DAI out until the next reset using the - * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the - * HW itself when it is busy processing a DAI command. In such a case, the - * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well. - * - * @param otp An OTP handle. - * @param[out] is_locked Out-param for the locked state. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked); - -/** - * Locks out `dif_otp_ctrl_configure()` function. - * - * This function is idempotent: calling it while functionality is locked will - * have no effect and return `kDifOk`. - * - * @param otp An OTP handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp); - -/** - * Checks whether `dif_otp_ctrl_configure()` function is locked-out. - * - * @param otp An OTP handle. - * @param[out] is_locked Out-param for the locked state. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_config_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked); - -/** - * Locks out `dif_otp_ctrl_check_*()` functions. - * - * This function is idempotent: calling it while functionality is locked will - * have no effect and return `kDifOk`. - * - * @param otp An OTP handle. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_lock_check_trigger(const dif_otp_ctrl_t *otp); - -/** - * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out. - * - * @param otp An OTP handle. - * @param[out] is_locked Out-param for the locked state. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_check_trigger_is_locked(const dif_otp_ctrl_t *otp, - bool *is_locked); - -/** - * Locks out reads to a SW partition. - * - * This function should only be called on SW partitions; doing otherwise will - * return an error. - * - * Note that this is distinct from the write-locking performed by calling - * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will - * not persist past a system reset. - * - * This function is idempotent: calling it while functionality is locked will - * have no effect and return `kDifOk`. - * - * @param otp An OTP handle. - * @param partition The SW partition to lock. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_lock_reading(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition); - -/** - * Checks whether reads to a SW partition are locked out. - * - * This function should only be called on SW partitions; doing otherwise will - * return an error. - * - * @param otp An OTP handle. - * @param partition the SW partition to check for locking. - * @param[out] is_locked Out-param for the locked state. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_reading_is_locked(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - bool *is_locked); - -/** - * Gets the current status of the OTP controller. - * - * @param otp An OTP handle. - * @param[out] status Out-param for the controller's status. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_get_status(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_status_t *status); - -/** - * Calculates a `relative_address` with respect to a `partition` start - * address. - * - * @param partition The partition to use to calculate the reference start - * address. - * @param abs_address Input address relative to the OTP memory start address. - * @param[out] relative_address The result relative address with respect to the - * `partition` start address. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_relative_address(dif_otp_ctrl_partition_t partition, - uint32_t abs_address, - uint32_t *relative_address); - -/** - * Schedules a read on the Direct Access Interface. - * - * Reads are performed relative to a partition; `address` should be given - * relative to the start of `partition`. An error is returned for out-of-bounds - * access. - * - * Furthermore, `address` must be well-aligned: it must be four-byte aligned for - * normal partitions and eight-byte-aligned for secret partitions. An error is - * returned for unaligned access. - * - * @param otp An OTP handle. - * @param partition The partition to read from. - * @param address A partition-relative address to read from. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_read_start(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address); - -/** - * Gets the result of a completed 32-bit read operation on the Direct Access - * Interface. - * - * Whether this function or its 64-bit variant should be called is dependent on - * the most recent partition read from. - * - * @param otp An OTP handle. - * @param[out] value Out-param for the read value. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp, - uint32_t *value); - -/** - * Gets the result of a completed 64-bit read operation on the Direct Access - * Interface. - * - * Whether this function or its 32-bit variant should be called is dependent on - * the most recent partition read from. - * - * @param otp An OTP handle. - * @param[out] value Out-param for the read value. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp, - uint64_t *value); - -/** - * Schedules a 32-bit write on the Direct Access Interface. - * - * Writes are performed relative to a partition; `address` should be given - * relative to the start of `partition`. An error is returned for out-of-bounds - * access. - * - * Furthermore, `address` must be four-byte-aligned, and `partition` must not be - * a secret partition. An error is returned if neither condition is met. - * - * Note that this function cannot be used to program the digest at the end of a - * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead. - * - * @param otp An OTP handle. - * @param partition The partition to program. - * @param address A partition-relative address to program. - * @param value The value to program into the OTP. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_program32(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint32_t value); - -/** - * Schedules a 64-bit write on the Direct Access Interface. - * - * Writes are performed relative to a partition; `address` should be given - * relative to the start of `partition`. An error is returned for out-of-bounds - * access. - * - * Furthermore, `address` must be eight-byte-aligned, and `partition` must be - * a secret partition. An error is returned if neither condition is met. - * - * @param otp An OTP handle. - * @param partition The partition to program. - * @param address A partition-relative address to program. - * @param value The value to program into the OTP. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_program64(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint64_t value); - -/** - * Schedules a hardware digest operation on the Direct Access Interface. - * - * **This operation will also lock writes for the given partition.** - * - * If `partition` is a SW partition, `digest` must be non-zero; if it is a - * partition with a hardware-managed digest, `digest` *must* be zero (since the - * digest will be generated by the hardware). An error is returned if either - * precondition is not met. - * - * This function does not work with the lifecycle state partition, and will - * return an error in that case. - * - * @param otp An OTP handle. - * @param partition The partition to digest and lock. - * @param digest The digest to program (for SW partitions). - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_dai_digest(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint64_t digest); - -/** - * Checks if the digest value for the given partition has been computed. Once a - * digest has been computed for a partition, the partition is write-locked - * (additionally, read-locked if the partition is secret). - * - * The lifecycle partition does not have a digest, and checking if this region - * has a computed digest will return an error. - * - * @param otp An OTP handle. - * @param partition The partition to check the digest of. - * @param[out] is_computed Indicates if the digest has been computed. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_is_digest_computed(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - bool *is_computed); - -/** - * Gets the buffered digest value for the given partition. - * - * Note that this value is only updated when the device is reset; if the digest - * has not been computed yet, or has been computed but not since device reset, - * this function will return an error. - * - * The lifecycle partition does not have a digest and will result in an error - * being returned. - * - * @param otp An OTP handle. - * @param partition The partition to get a digest for. - * @param[out] digest Out-param for the digest. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_get_digest(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint64_t *digest); - -/** - * Performs a memory-mapped read of the given partition, if it supports them. - * - * In particular, this function will read `len` words, starting at `address`, - * relative to the start of `partition`. - * - * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in - * addition, `address + len` must also be in-range and must not overflow. - * - * This function will block until the read completes, unlike Direct Access - * Interface functions. - * - * @param otp An OTP handle. - * @param partition The partition to read from. - * @param address A partition-relative address to read from. - * @param[out] buf A buffer of words to write read values to. - * @param len The number of words to read. - * @return The result of the operation. - */ -OT_WARN_UNUSED_RESULT -dif_result_t dif_otp_ctrl_read_blocking(const dif_otp_ctrl_t *otp, - dif_otp_ctrl_partition_t partition, - uint32_t address, uint32_t *buf, - size_t len); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_ diff --git a/hw/ip/otp_ctrl/data/dif_otp_ctrl_unittest.cc.tpl b/hw/ip/otp_ctrl/data/dif_otp_ctrl_unittest.cc.tpl deleted file mode 100644 index bf26949744198..0000000000000 --- a/hw/ip/otp_ctrl/data/dif_otp_ctrl_unittest.cc.tpl +++ /dev/null @@ -1,790 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -parts = otp_mmap.config["partitions"] -digest_parts = [part for part in parts if - part["hw_digest"] or part["sw_digest"]] -hw_digest_parts = [part for part in parts if part["hw_digest"]] -sw_digest_parts = [part for part in parts if part["sw_digest"]] -read_locked_csr_parts = [part for part in parts if part["read_lock"] == "CSR"] -secret_parts = [part for part in parts if part["secret"]] -%>\ -#include "sw/device/lib/dif/dif_otp_ctrl.h" - -#include -#include -#include - -#include "gtest/gtest.h" -#include "sw/device/lib/base/mmio.h" -#include "sw/device/lib/base/mock_mmio.h" -#include "sw/device/lib/dif/dif_test_base.h" - -#include "otp_ctrl_regs.h" // Generated. - -namespace dif_otp_ctrl_unittest { -namespace { -using ::mock_mmio::LeInt; -using ::mock_mmio::MmioTest; -using ::mock_mmio::MockDevice; -using ::testing::Each; -using ::testing::ElementsAre; - -class OtpTest : public testing::Test, public MmioTest { - protected: - dif_otp_ctrl_t otp_ = {.base_addr = dev().region()}; -}; - -class DaiRegwenTest : public OtpTest {}; - -TEST_F(DaiRegwenTest, LockDai) { - EXPECT_WRITE32( - OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, false}}); - EXPECT_DIF_OK(dif_otp_ctrl_dai_lock(&otp_)); -} - -TEST_F(DaiRegwenTest, IsDaiLocked) { - bool flag; - - EXPECT_READ32( - OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, true}}); - EXPECT_DIF_OK(dif_otp_ctrl_dai_is_locked(&otp_, &flag)); - EXPECT_FALSE(flag); - - EXPECT_READ32( - OTP_CTRL_DIRECT_ACCESS_REGWEN_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_BIT, false}}); - EXPECT_DIF_OK(dif_otp_ctrl_dai_is_locked(&otp_, &flag)); - EXPECT_TRUE(flag); -} - -TEST_F(DaiRegwenTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_lock(nullptr)); - - bool flag; - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_is_locked(nullptr, &flag)); - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_is_locked(&otp_, nullptr)); -} - -class ConfigTest : public OtpTest {}; - -TEST_F(ConfigTest, Basic) { - dif_otp_ctrl_config_t config = { - .check_timeout = 100'000, - .integrity_period_mask = 0x3'ffff, - .consistency_period_mask = 0x3ff'ffff, - }; - - EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}}); - - EXPECT_WRITE32(OTP_CTRL_CHECK_TIMEOUT_REG_OFFSET, config.check_timeout); - EXPECT_WRITE32(OTP_CTRL_INTEGRITY_CHECK_PERIOD_REG_OFFSET, - config.integrity_period_mask); - EXPECT_WRITE32(OTP_CTRL_CONSISTENCY_CHECK_PERIOD_REG_OFFSET, - config.consistency_period_mask); - - EXPECT_DIF_OK(dif_otp_ctrl_configure(&otp_, config)); -} - -TEST_F(ConfigTest, Locked) { - EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}}); - - EXPECT_EQ(dif_otp_ctrl_configure(&otp_, {}), kDifLocked); -} - -TEST_F(ConfigTest, IsConfigLocked) { - bool flag; - - EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, true}}); - EXPECT_DIF_OK(dif_otp_ctrl_config_is_locked(&otp_, &flag)); - EXPECT_FALSE(flag); - - EXPECT_READ32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}}); - EXPECT_DIF_OK(dif_otp_ctrl_config_is_locked(&otp_, &flag)); - EXPECT_TRUE(flag); -} - -TEST_F(ConfigTest, LockConfig) { - EXPECT_WRITE32(OTP_CTRL_CHECK_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_REGWEN_CHECK_REGWEN_BIT, false}}); - EXPECT_DIF_OK(dif_otp_ctrl_lock_config(&otp_)); -} - -TEST_F(ConfigTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_configure(nullptr, {})); - - bool flag; - EXPECT_DIF_BADARG(dif_otp_ctrl_config_is_locked(nullptr, &flag)); - EXPECT_DIF_BADARG(dif_otp_ctrl_config_is_locked(&otp_, nullptr)); - - EXPECT_DIF_BADARG(dif_otp_ctrl_lock_config(nullptr)); -} - -class CheckTest : public OtpTest {}; - -TEST_F(CheckTest, Integrity) { - EXPECT_READ32( - OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}}); - EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_INTEGRITY_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_check_integrity(&otp_)); -} - -TEST_F(CheckTest, Consistency) { - EXPECT_READ32( - OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, true}}); - EXPECT_WRITE32(OTP_CTRL_CHECK_TRIGGER_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_CONSISTENCY_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_check_consistency(&otp_)); -} - -TEST_F(CheckTest, LockTrigger) { - EXPECT_WRITE32( - OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}}); - EXPECT_DIF_OK(dif_otp_ctrl_lock_check_trigger(&otp_)); -} - -TEST_F(CheckTest, Locked) { - EXPECT_READ32( - OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}}); - EXPECT_EQ(dif_otp_ctrl_check_integrity(&otp_), kDifLocked); - - EXPECT_READ32( - OTP_CTRL_CHECK_TRIGGER_REGWEN_REG_OFFSET, - {{OTP_CTRL_CHECK_TRIGGER_REGWEN_CHECK_TRIGGER_REGWEN_BIT, false}}); - EXPECT_EQ(dif_otp_ctrl_check_consistency(&otp_), kDifLocked); -} - -TEST_F(CheckTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_check_integrity(nullptr)); - EXPECT_DIF_BADARG(dif_otp_ctrl_check_consistency(nullptr)); -} - -class ReadLockTest : public OtpTest {}; - -// Too many formatting variants in template code, so disabling clang-format. -// clang-format off -TEST_F(ReadLockTest, IsLocked) { - bool flag; - -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() -%>\ - EXPECT_READ32( - OTP_CTRL_${part_name_define}_READ_LOCK_REG_OFFSET, - {{OTP_CTRL_${part_name_define}_READ_LOCK_${part_name_define}_READ_LOCK_BIT, - true}}); - EXPECT_DIF_OK(dif_otp_ctrl_reading_is_locked( - &otp_, kDifOtpCtrlPartition${part_name_camel}, &flag)); - EXPECT_FALSE(flag); - - EXPECT_READ32( - OTP_CTRL_${part_name_define}_READ_LOCK_REG_OFFSET, - {{OTP_CTRL_${part_name_define}_READ_LOCK_${part_name_define}_READ_LOCK_BIT, - false}}); - EXPECT_DIF_OK(dif_otp_ctrl_reading_is_locked( - &otp_, kDifOtpCtrlPartition${part_name_camel}, &flag)); - EXPECT_TRUE(flag); - % if not loop.last: - - %endif -% endfor -} - -TEST_F(ReadLockTest, Lock) { -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() -%>\ - EXPECT_WRITE32( - OTP_CTRL_${part_name_define}_READ_LOCK_REG_OFFSET, - {{OTP_CTRL_${part_name_define}_READ_LOCK_${part_name_define}_READ_LOCK_BIT, - false}}); - EXPECT_DIF_OK(dif_otp_ctrl_lock_reading( - &otp_, kDifOtpCtrlPartition${part_name_camel})); - % if not loop.last: - - %endif -% endfor -} - -TEST_F(ReadLockTest, NotLockablePartitions) { - bool flag; -% for part in [p for p in parts if p not in read_locked_csr_parts]: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - EXPECT_DIF_BADARG( - dif_otp_ctrl_lock_reading(&otp_, kDifOtpCtrlPartition${part_name_camel})); - EXPECT_DIF_BADARG(dif_otp_ctrl_reading_is_locked( - &otp_, kDifOtpCtrlPartition${part_name_camel}, &flag)); - % if not loop.last: - - %endif -% endfor -} -// clang-format on - -TEST_F(ReadLockTest, NullArgs) { - bool flag; -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - lock_reading_line = f"dif_otp_ctrl_lock_reading(nullptr, kDifOtpCtrlPartition{part_name_camel}));" -%>\ - EXPECT_DIF_BADARG(dif_otp_ctrl_reading_is_locked( - nullptr, kDifOtpCtrlPartition${part_name_camel}, &flag)); - EXPECT_DIF_BADARG(dif_otp_ctrl_reading_is_locked( - &otp_, kDifOtpCtrlPartition${part_name_camel}, nullptr)); - % if len(lock_reading_line) > 80 - 6: - EXPECT_DIF_BADARG(dif_otp_ctrl_lock_reading( - nullptr, kDifOtpCtrlPartition${part_name_camel})); - % else: - EXPECT_DIF_BADARG( - ${lock_reading_line} - % endif - % if not loop.last: - - %endif -% endfor -} - -class StatusTest : public OtpTest {}; - -TEST_F(StatusTest, Idle) { - dif_otp_ctrl_status_t status; - - EXPECT_READ32(OTP_CTRL_STATUS_REG_OFFSET, - {{OTP_CTRL_STATUS_DAI_IDLE_BIT, true}}); - EXPECT_DIF_OK(dif_otp_ctrl_get_status(&otp_, &status)); - - EXPECT_EQ(status.codes, 1 << kDifOtpCtrlStatusCodeDaiIdle); - EXPECT_THAT(status.causes, Each(kDifOtpCtrlErrorOk)); -} - -TEST_F(StatusTest, Errors) { - dif_otp_ctrl_status_t status; - - EXPECT_READ32(OTP_CTRL_STATUS_REG_OFFSET, - { - {OTP_CTRL_STATUS_DAI_IDLE_BIT, true}, - {OTP_CTRL_STATUS_HW_CFG0_ERROR_BIT, true}, - {OTP_CTRL_STATUS_LCI_ERROR_BIT, true}, - }); - -<% - hw_cfg0_error_index = [i for i, p in enumerate(parts) - if p["name"] == "HW_CFG0"][0] - lci_error_index = len(parts) + 1 -%>\ - EXPECT_READ32(OTP_CTRL_ERR_CODE_${hw_cfg0_error_index}_REG_OFFSET, - {{OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET, - OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ECC_CORR_ERROR}}); - EXPECT_READ32(OTP_CTRL_ERR_CODE_${lci_error_index}_REG_OFFSET, - {{OTP_CTRL_ERR_CODE_0_ERR_CODE_0_OFFSET, - OTP_CTRL_ERR_CODE_0_ERR_CODE_0_VALUE_MACRO_ERROR}}); - - EXPECT_DIF_OK(dif_otp_ctrl_get_status(&otp_, &status)); - EXPECT_EQ(status.codes, (1 << kDifOtpCtrlStatusCodeDaiIdle) | - (1 << kDifOtpCtrlStatusCodeHwCfg0Error) | - (1 << kDifOtpCtrlStatusCodeLciError)); - EXPECT_EQ(status.causes[kDifOtpCtrlStatusCodeHwCfg0Error], - kDifOtpCtrlErrorMacroRecoverableRead); - EXPECT_EQ(status.causes[kDifOtpCtrlStatusCodeLciError], - kDifOtpCtrlErrorMacroUnspecified); -} - -TEST_F(StatusTest, NullArgs) { - dif_otp_ctrl_status_t status; - - EXPECT_DIF_BADARG(dif_otp_ctrl_get_status(nullptr, &status)); - EXPECT_DIF_BADARG(dif_otp_ctrl_get_status(&otp_, nullptr)); -} - -struct RelativeAddressParams { - std::string name; - dif_otp_ctrl_partition_t partition; - uint32_t abs_address; - dif_result_t expected_result; - uint32_t expected_relative_address; -}; - -class RelativeAddress - : public OtpTest, - public testing::WithParamInterface {}; - -TEST_P(RelativeAddress, RelativeAddress) { - uint32_t got_relative_address; - dif_result_t got_result = dif_otp_ctrl_relative_address( - GetParam().partition, GetParam().abs_address, &got_relative_address); - EXPECT_EQ(got_result, GetParam().expected_result); - EXPECT_EQ(got_relative_address, GetParam().expected_relative_address); -} - -INSTANTIATE_TEST_SUITE_P( - AllPartitions, RelativeAddress, - testing::Values( -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() - step = 8 if part["secret"] else 4 -%>\ - RelativeAddressParams{ - "${part_name_camel}Okay", - kDifOtpCtrlPartition${part_name_camel}, - OTP_CTRL_PARAM_${part_name_define}_OFFSET + ${step}, - kDifOk, - ${step}, - }, - RelativeAddressParams{ - "${part_name_camel}Unaligned", - kDifOtpCtrlPartition${part_name_camel}, - OTP_CTRL_PARAM_${part_name_define}_OFFSET + 1, - kDifUnaligned, - 0, - }, -<% - ## Exclude first partition to avoid a negative offset. -%>\ - % if not loop.first: - RelativeAddressParams{ - "${part_name_camel}OutOfRangeBeforeStart", - kDifOtpCtrlPartition${part_name_camel}, - OTP_CTRL_PARAM_${part_name_define}_OFFSET - ${step}, - kDifOutOfRange, - 0, - }, - % endif - RelativeAddressParams{ - "${part_name_camel}OutOfRangePastEnd", - kDifOtpCtrlPartition${part_name_camel}, - % if len(f"OTP_CTRL_PARAM_{part_name_define}_OFFSET + OTP_CTRL_PARAM_{part_name_define}_SIZE,") <= 80 - 12: - OTP_CTRL_PARAM_${part_name_define}_OFFSET + OTP_CTRL_PARAM_${part_name_define}_SIZE, - % else: - OTP_CTRL_PARAM_${part_name_define}_OFFSET + - OTP_CTRL_PARAM_${part_name_define}_SIZE, - % endif - kDifOutOfRange, - 0, - }${")," if loop.last else ","} -% endfor - [](const testing::TestParamInfo &info) { - return info.param.name; - }); - -class DaiReadTest : public OtpTest {}; - -TEST_F(DaiReadTest, Read32) { - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_MANUF_STATE_OFFSET); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_read_start(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x20)); - - EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x12345678); - - uint32_t val; - EXPECT_DIF_OK(dif_otp_ctrl_dai_read32_end(&otp_, &val)); - EXPECT_EQ(val, 0x12345678); -} - -TEST_F(DaiReadTest, Read64) { - uint64_t val; -% for part in secret_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() -%>\ - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_${part_name_define}_OFFSET + 0x8); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_RD_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_read_start(&otp_, kDifOtpCtrlPartition${part_name_camel}, - /*address=*/0x8)); - - EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_1_REG_OFFSET, 0x12345678); - EXPECT_READ32(OTP_CTRL_DIRECT_ACCESS_RDATA_0_REG_OFFSET, 0x90abcdef); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_read64_end(&otp_, &val)); - EXPECT_EQ(val, 0x1234567890abcdef); - % if not loop.last: - - % endif -% endfor -} - -TEST_F(DaiReadTest, Unaligned) { - EXPECT_EQ(dif_otp_ctrl_dai_read_start(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0b01), - kDifUnaligned); - EXPECT_EQ(dif_otp_ctrl_dai_read_start(&otp_, kDifOtpCtrlPartitionSecret2, - /*address=*/0b100), - kDifUnaligned); -} - -TEST_F(DaiReadTest, OutOfRange) { - EXPECT_EQ(dif_otp_ctrl_dai_read_start(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x100), - kDifOutOfRange); -} - -TEST_F(DaiReadTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_read_start(nullptr, - kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x0)); - - uint32_t val32; - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_read32_end(nullptr, &val32)); - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_read32_end(&otp_, nullptr)); - - uint64_t val64; - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_read64_end(nullptr, &val64)); - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_read64_end(&otp_, nullptr)); -} - -class DaiProgramTest : public OtpTest {}; - -TEST_F(DaiProgramTest, Program32) { - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_MANUF_STATE_OFFSET); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x12345678); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_program32(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x20, - /*value=*/0x12345678)); -} - -TEST_F(DaiProgramTest, Program64) { - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_SECRET2_OFFSET + 0x8); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x90abcdef); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0x12345678); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_program64(&otp_, kDifOtpCtrlPartitionSecret2, - /*address=*/0x8, - /*value=*/0x1234567890abcdef)); -} - -TEST_F(DaiProgramTest, BadPartition) { - EXPECT_EQ(dif_otp_ctrl_dai_program32(&otp_, kDifOtpCtrlPartitionSecret1, - /*address=*/0x0, /*value=*/42), - kDifError); - EXPECT_EQ(dif_otp_ctrl_dai_program64(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x0, /*value=*/42), - kDifError); - - // LC is never writeable. - EXPECT_EQ(dif_otp_ctrl_dai_program32(&otp_, kDifOtpCtrlPartitionLifeCycle, - /*address=*/0x0, /*value=*/42), - kDifError); -} - -TEST_F(DaiProgramTest, Unaligned) { - EXPECT_EQ(dif_otp_ctrl_dai_program32(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*address=*/0b01, /*value=*/42), - kDifUnaligned); - EXPECT_EQ(dif_otp_ctrl_dai_program64(&otp_, kDifOtpCtrlPartitionSecret2, - /*address=*/0b100, /*value=*/42), - kDifUnaligned); -} - -TEST_F(DaiProgramTest, OutOfRange) { - // Check that we can't write a digest directly. - EXPECT_EQ(dif_otp_ctrl_dai_program32( - &otp_, kDifOtpCtrlPartitionCreatorSwCfg, - /*address=*/OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_OFFSET, - /*value=*/42), - kDifOutOfRange); - - // Same digest check for 64-bit. - EXPECT_EQ(dif_otp_ctrl_dai_program64( - &otp_, kDifOtpCtrlPartitionSecret2, - /*address=*/OTP_CTRL_PARAM_SECRET2_DIGEST_OFFSET, /*value=*/42), - kDifOutOfRange); -} - -TEST_F(DaiProgramTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_program32(nullptr, - kDifOtpCtrlPartitionHwCfg0, - /*address=*/0x0, /*value=*/42)); - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_program64(nullptr, - kDifOtpCtrlPartitionSecret0, - /*address=*/0x0, /*value=*/42)); -} - -class DaiDigestTest : public OtpTest {}; - -TEST_F(DaiDigestTest, DigestSw) { -% for part in sw_digest_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_define = part_name.as_c_define() - part_name_camel = part_name.as_camel_case() - dai_digest_line = ("EXPECT_DIF_OK(dif_otp_ctrl_dai_digest(&otp_, " - + f"kDifOtpCtrlPartition{part_name_camel},") -%>\ - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_${part_name.as_c_define()}_DIGEST_OFFSET); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_0_REG_OFFSET, 0x00abcdef); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_WDATA_1_REG_OFFSET, 0xabcdef00); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_WR_BIT, true}}); - - % if len(dai_digest_line) > 80 - 2: -<% dai_digest_line = (f"kDifOtpCtrlPartition{part_name_camel},") %>\ - % if len(dai_digest_line) > 80 - 40: - EXPECT_DIF_OK( - dif_otp_ctrl_dai_digest(&otp_, kDifOtpCtrlPartition${part_name_camel}, - /*digest=*/0xabcdef0000abcdef)); - % else: - EXPECT_DIF_OK(dif_otp_ctrl_dai_digest(&otp_, - kDifOtpCtrlPartition${part_name_camel}, - /*digest=*/0xabcdef0000abcdef)); - % endif - % else: - ${dai_digest_line} - /*digest=*/0xabcdef0000abcdef)); - % endif - % if not loop.last: - - % endif -% endfor -} - -TEST_F(DaiDigestTest, DigestHw) { -% for part in hw_digest_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_define = part_name.as_c_define() - part_name_camel = part_name.as_camel_case() - dai_digest_line = ("EXPECT_DIF_OK(dif_otp_ctrl_dai_digest(&otp_, " - + f"kDifOtpCtrlPartition{part_name_camel},") -%>\ - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_ADDRESS_REG_OFFSET, - OTP_CTRL_PARAM_${part_name_define}_OFFSET); - EXPECT_WRITE32(OTP_CTRL_DIRECT_ACCESS_CMD_REG_OFFSET, - {{OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_BIT, true}}); - - EXPECT_DIF_OK(dif_otp_ctrl_dai_digest(&otp_, kDifOtpCtrlPartition${part_name_camel}, - /*digest=*/0)); - % if not loop.last: - - % endif -% endfor -} - -TEST_F(DaiDigestTest, BadPartition) { - EXPECT_EQ(dif_otp_ctrl_dai_digest(&otp_, kDifOtpCtrlPartitionLifeCycle, - /*digest=*/0), - kDifError); -} - -TEST_F(DaiDigestTest, BadDigest) { - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_digest(&otp_, kDifOtpCtrlPartitionHwCfg0, - /*digest=*/0xabcdef0000abcdef)); - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_digest(&otp_, - kDifOtpCtrlPartitionCreatorSwCfg, - /*digest=*/0)); -} - -TEST_F(DaiDigestTest, NullArgs) { - EXPECT_DIF_BADARG(dif_otp_ctrl_dai_digest(nullptr, - kDifOtpCtrlPartitionCreatorSwCfg, - /*digest=*/0xabcdef0000abcdef)); -} - -class IsDigestComputed : public OtpTest {}; - -TEST_F(IsDigestComputed, NullArgs) { - bool is_computed; - EXPECT_DIF_BADARG(dif_otp_ctrl_is_digest_computed( - nullptr, kDifOtpCtrlPartitionSecret2, &is_computed)); - EXPECT_DIF_BADARG(dif_otp_ctrl_is_digest_computed( - &otp_, kDifOtpCtrlPartitionSecret2, nullptr)); - EXPECT_DIF_BADARG(dif_otp_ctrl_is_digest_computed( - nullptr, kDifOtpCtrlPartitionSecret2, nullptr)); -} - -TEST_F(IsDigestComputed, BadPartition) { - bool is_computed; - EXPECT_DIF_BADARG(dif_otp_ctrl_is_digest_computed( - &otp_, kDifOtpCtrlPartitionLifeCycle, &is_computed)); -} - -TEST_F(IsDigestComputed, Success) { - bool is_computed; - - EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET, 0x98abcdef); - EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET, 0xabcdef01); - EXPECT_DIF_OK(dif_otp_ctrl_is_digest_computed( - &otp_, kDifOtpCtrlPartitionSecret2, &is_computed)); - EXPECT_TRUE(is_computed); - - EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_1_REG_OFFSET, 0); - EXPECT_READ32(OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET, 0); - EXPECT_DIF_OK(dif_otp_ctrl_is_digest_computed( - &otp_, kDifOtpCtrlPartitionSecret2, &is_computed)); - EXPECT_FALSE(is_computed); -} - -struct DigestParams { - dif_otp_ctrl_partition_t partition; - bool has_digest; - ptrdiff_t reg0, reg1; -}; - -class GetDigest : public OtpTest, - public testing::WithParamInterface {}; - -TEST_P(GetDigest, GetDigest) { - if (!GetParam().has_digest) { - uint64_t digest; - EXPECT_DIF_BADARG( - dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest)); - return; - } - - EXPECT_READ32(GetParam().reg1, 0xabcdef99); - EXPECT_READ32(GetParam().reg0, 0x99abcdef); - - uint64_t digest; - EXPECT_DIF_OK(dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest)); - EXPECT_EQ(digest, 0xabcdef9999abcdef); -} - -TEST_P(GetDigest, BadDigest) { - if (!GetParam().has_digest) { - return; - } - - EXPECT_READ32(GetParam().reg1, 0x0); - EXPECT_READ32(GetParam().reg0, 0x0); - - uint64_t digest; - EXPECT_EQ(dif_otp_ctrl_get_digest(&otp_, GetParam().partition, &digest), - kDifError); -} - -TEST_P(GetDigest, NullArgs) { - uint64_t digest; - EXPECT_DIF_BADARG( - dif_otp_ctrl_get_digest(nullptr, GetParam().partition, &digest)); - EXPECT_DIF_BADARG( - dif_otp_ctrl_get_digest(&otp_, GetParam().partition, nullptr)); -} - -// This depends on the maximum length of partition names, which will -// be changing, so turn formatting off. -// clang-format off -INSTANTIATE_TEST_SUITE_P( - AllDigests, GetDigest, - testing::Values( -% for part in parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() - part_name_define = part_name.as_c_define() -%>\ - % if part in digest_parts: - DigestParams{ - kDifOtpCtrlPartition${part_name_camel}, - true, - OTP_CTRL_${part_name_define}_DIGEST_0_REG_OFFSET, - OTP_CTRL_${part_name_define}_DIGEST_1_REG_OFFSET, - }${"" if loop.last else ","} - % else: - DigestParams{ - kDifOtpCtrlPartition${part_name_camel}, - false, - 0, - 0, - }${"));" if loop.last else ","} - % endif -% endfor -// clang-format on - -class BlockingIoTest : public OtpTest { - protected: - static constexpr size_t kWords = 4; -}; - -TEST_F(BlockingIoTest, Read) { - for (size_t i = 0; i < kWords; ++i) { - auto offset = - OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET + 0x10 + i * sizeof(uint32_t); - EXPECT_READ32(OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET + offset, i + 1); - } - - std::vector buf(kWords); - EXPECT_DIF_OK(dif_otp_ctrl_read_blocking( - &otp_, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, buf.data(), buf.size())); - EXPECT_THAT(buf, ElementsAre(1, 2, 3, 4)); -} - -TEST_F(BlockingIoTest, BadPartition) { - std::vector buf(kWords); - EXPECT_EQ(dif_otp_ctrl_read_blocking(&otp_, kDifOtpCtrlPartitionHwCfg0, 0x10, - buf.data(), buf.size()), - kDifError); -} - -TEST_F(BlockingIoTest, Unaligned) { - std::vector buf(kWords); - EXPECT_EQ(dif_otp_ctrl_read_blocking(&otp_, kDifOtpCtrlPartitionOwnerSwCfg, - 0x11, buf.data(), buf.size()), - kDifUnaligned); -} - -TEST_F(BlockingIoTest, OutOfRange) { - std::vector buf(0x2f0); - EXPECT_EQ(dif_otp_ctrl_read_blocking(&otp_, kDifOtpCtrlPartitionOwnerSwCfg, - 0x300, buf.data(), buf.size()), - kDifOutOfRange); - EXPECT_EQ(dif_otp_ctrl_read_blocking(&otp_, kDifOtpCtrlPartitionOwnerSwCfg, - 0x10, buf.data(), 0x330), - kDifOutOfRange); -} - -TEST_F(BlockingIoTest, NullArgs) { - std::vector buf(kWords); - EXPECT_DIF_BADARG(dif_otp_ctrl_read_blocking( - nullptr, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, buf.data(), buf.size())); - EXPECT_DIF_BADARG(dif_otp_ctrl_read_blocking( - &otp_, kDifOtpCtrlPartitionOwnerSwCfg, 0x10, nullptr, buf.size())); -} - -} // namespace -} // namespace dif_otp_ctrl_unittest diff --git a/hw/ip/otp_ctrl/data/otp_ctrl.hjson b/hw/ip/otp_ctrl/data/otp_ctrl.hjson deleted file mode 100644 index 44844724b52a8..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl.hjson +++ /dev/null @@ -1,3318 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// HJSON with partition metadata. -// -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -{ - name: "otp_ctrl", - human_name: "One-Time Programmable Memory Controller", - one_line_desc: "Interfaces integrated one-time programmable memory, supports scrambling, integrity and secure wipe", - one_paragraph_desc: ''' - One-Time Programmable (OTP) Memory Controller provides an open source abstraction interface for software and other hardware components such as Life Cycle Controller and Key Manager to interact with an integrated, closed source, proprietary OTP memory. - On top of defensive features provided by the proprietary OTP memory to deter side-channel analysis (SCA), fault injection (FI) attacks, and visual and electrical probing, the open source OTP controller features high-level logical security protection such as integrity checks and scrambling, as well as software isolation for when OTP contents are readable and programmable. - It features multiple individually-lockable logical partitions, periodic / persistent checking of OTP values, and a separate partition and interface for Life Cycle Controller. - ''' - // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. - cip_id: "16", - design_spec: "../doc", - dv_doc: "../doc/dv", - hw_checklist: "../doc/checklist", - sw_checklist: "/sw/device/lib/dif/dif_otp_ctrl", - revisions: [ - { - version: "0.1.0", - life_stage: "L1", - design_stage: "D2", - verification_stage: "V2", - dif_stage: "S1", - commit_id: "127b109e2fab9336e830158abe449a3922544ded", - notes: "", - } - { - version: "1.0.0", - life_stage: "L1", - design_stage: "D3", - verification_stage: "V2S", - dif_stage: "S2", - notes: "", - } - { - version: "2.0.0", - life_stage: "L1", - design_stage: "D3", - verification_stage: "V2S", - dif_stage: "S2", - notes: "", - } - ] - clocking: [ - {clock: "clk_i", reset: "rst_ni", primary: true}, - {clock: "clk_edn_i", reset: "rst_edn_ni"} - ] - scan: "true", // Enable `scanmode_i` port - scan_reset: "true", // Enable `scan_rst_ni` port - scan_en: "true", // Enable `scan_en_i` port - bus_interfaces: [ - { protocol: "tlul", direction: "device", name: "core" } - { protocol: "tlul", direction: "device", name: "prim", hier_path: "u_otp.gen_generic.u_impl_generic.u_reg_top" } - ], - - available_output_list: [ - { name: "test", - width: 8, - desc: "Test-related GPIOs. Only active in DFT-enabled life cycle states." - } - ], - - /////////////////////////// - // Interrupts and Alerts // - /////////////////////////// - - interrupt_list: [ - { name: "otp_operation_done", - desc: "A direct access command or digest calculation operation has completed." - } - { name: "otp_error", - desc: "An error has occurred in the OTP controller. Check the !!ERR_CODE register to get more information." - } - ], - - alert_list: [ - { name: "fatal_macro_error", - desc: "This alert triggers if hardware detects an uncorrectable error during an OTP transaction, for example an uncorrectable ECC error in the OTP array.", - } - { name: "fatal_check_error", - desc: "This alert triggers if any of the background checks fails. This includes the digest checks and concurrent ECC checks in the buffer registers.", - } - { name: "fatal_bus_integ_error", - desc: "This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected." - } - { name: "fatal_prim_otp_alert", - desc: "Fatal alert triggered inside the OTP primitive, including fatal TL-UL bus integrity faults of the test interface." - } - { name: "recov_prim_otp_alert", - desc: "Recoverable alert triggered inside the OTP primitive." - } - ], - - //////////////// - // Parameters // - //////////////// - param_list: [ - // Init file - { name: "MemInitFile", - desc: "VMEM file to initialize the OTP macro.", - type: "", - default: '""', - expose: "true", - local: "false" - } - // Random netlist constants - { name: "RndCnstLfsrSeed", - desc: "Compile-time random bits for initial LFSR seed", - type: "otp_ctrl_pkg::lfsr_seed_t" - randcount: "40", - randtype: "data", // randomize randcount databits - } - { name: "RndCnstLfsrPerm", - desc: "Compile-time random permutation for LFSR output", - type: "otp_ctrl_pkg::lfsr_perm_t" - randcount: "40", - randtype: "perm", // random permutation for randcount elements - } - { name: "RndCnstScrmblKeyInit", - desc: "Compile-time random permutation for scrambling key/nonce register reset value", - type: "otp_ctrl_pkg::scrmbl_key_init_t" - randcount: "256", - randtype: "data", // random permutation for randcount elements - } - // Normal parameters - { name: "NumSramKeyReqSlots", - desc: "Number of key slots", - type: "int", - default: "4", - local: "true" - }, - { name: "OtpByteAddrWidth", - desc: "Width of the OTP byte address.", - type: "int", - default: "11", - local: "true" - }, - { name: "NumErrorEntries", - desc: "Number of error register entries.", - type: "int", - default: "13", // partitions + DAI/LCI - local: "true" - }, - { name: "NumDaiWords", - desc: "Number of 32bit words in the DAI.", - type: "int", - default: "2", - local: "true" - }, - { name: "NumDigestWords", - desc: "Size of the digest fields in 32bit words.", - type: "int", - default: "2", - local: "true" - }, - { name: "NumSwCfgWindowWords", - desc: "Size of the TL-UL window in 32bit words. Note that the effective partition size is smaller than that.", - type: "int", - default: "512", - local: "true" - } - - // Memory map Info - { name: "NumPart", - desc: "Number of partitions", - type: "int", - default: "11", - local: "true" - }, - { name: "NumPartUnbuf", - desc: "Number of unbuffered partitions", - type: "int", - default: "5", - local: "true" - }, - { name: "NumPartBuf", - desc: "Number of buffered partitions (including 1 lifecycle partition)", - type: "int", - default: "6", - local: "true" - }, - { name: "VendorTestOffset", - desc: "Offset of the VENDOR_TEST partition", - type: "int", - default: "0", - local: "true" - }, - { name: "VendorTestSize", - desc: "Size of the VENDOR_TEST partition", - type: "int", - default: "64", - local: "true" - }, - { name: "ScratchOffset", - desc: "Offset of SCRATCH", - type: "int", - default: "0", - local: "true" - }, - { name: "ScratchSize", - desc: "Size of SCRATCH", - type: "int", - default: "56", - local: "true" - }, - { name: "VendorTestDigestOffset", - desc: "Offset of VENDOR_TEST_DIGEST", - type: "int", - default: "56", - local: "true" - }, - { name: "VendorTestDigestSize", - desc: "Size of VENDOR_TEST_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "CreatorSwCfgOffset", - desc: "Offset of the CREATOR_SW_CFG partition", - type: "int", - default: "64", - local: "true" - }, - { name: "CreatorSwCfgSize", - desc: "Size of the CREATOR_SW_CFG partition", - type: "int", - default: "368", - local: "true" - }, - { name: "CreatorSwCfgAstCfgOffset", - desc: "Offset of CREATOR_SW_CFG_AST_CFG", - type: "int", - default: "64", - local: "true" - }, - { name: "CreatorSwCfgAstCfgSize", - desc: "Size of CREATOR_SW_CFG_AST_CFG", - type: "int", - default: "156", - local: "true" - }, - { name: "CreatorSwCfgAstInitEnOffset", - desc: "Offset of CREATOR_SW_CFG_AST_INIT_EN", - type: "int", - default: "220", - local: "true" - }, - { name: "CreatorSwCfgAstInitEnSize", - desc: "Size of CREATOR_SW_CFG_AST_INIT_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRomExtSkuOffset", - desc: "Offset of CREATOR_SW_CFG_ROM_EXT_SKU", - type: "int", - default: "224", - local: "true" - }, - { name: "CreatorSwCfgRomExtSkuSize", - desc: "Size of CREATOR_SW_CFG_ROM_EXT_SKU", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgSigverifySpxEnOffset", - desc: "Offset of CREATOR_SW_CFG_SIGVERIFY_SPX_EN", - type: "int", - default: "228", - local: "true" - }, - { name: "CreatorSwCfgSigverifySpxEnSize", - desc: "Size of CREATOR_SW_CFG_SIGVERIFY_SPX_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgFlashDataDefaultCfgOffset", - desc: "Offset of CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", - type: "int", - default: "232", - local: "true" - }, - { name: "CreatorSwCfgFlashDataDefaultCfgSize", - desc: "Size of CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgFlashInfoBootDataCfgOffset", - desc: "Offset of CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG", - type: "int", - default: "236", - local: "true" - }, - { name: "CreatorSwCfgFlashInfoBootDataCfgSize", - desc: "Size of CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgFlashHwInfoCfgOverrideOffset", - desc: "Offset of CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE", - type: "int", - default: "240", - local: "true" - }, - { name: "CreatorSwCfgFlashHwInfoCfgOverrideSize", - desc: "Size of CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngEnOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_EN", - type: "int", - default: "244", - local: "true" - }, - { name: "CreatorSwCfgRngEnSize", - desc: "Size of CREATOR_SW_CFG_RNG_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgJitterEnOffset", - desc: "Offset of CREATOR_SW_CFG_JITTER_EN", - type: "int", - default: "248", - local: "true" - }, - { name: "CreatorSwCfgJitterEnSize", - desc: "Size of CREATOR_SW_CFG_JITTER_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRetRamResetMaskOffset", - desc: "Offset of CREATOR_SW_CFG_RET_RAM_RESET_MASK", - type: "int", - default: "252", - local: "true" - }, - { name: "CreatorSwCfgRetRamResetMaskSize", - desc: "Size of CREATOR_SW_CFG_RET_RAM_RESET_MASK", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgManufStateOffset", - desc: "Offset of CREATOR_SW_CFG_MANUF_STATE", - type: "int", - default: "256", - local: "true" - }, - { name: "CreatorSwCfgManufStateSize", - desc: "Size of CREATOR_SW_CFG_MANUF_STATE", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRomExecEnOffset", - desc: "Offset of CREATOR_SW_CFG_ROM_EXEC_EN", - type: "int", - default: "260", - local: "true" - }, - { name: "CreatorSwCfgRomExecEnSize", - desc: "Size of CREATOR_SW_CFG_ROM_EXEC_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgCpuctrlOffset", - desc: "Offset of CREATOR_SW_CFG_CPUCTRL", - type: "int", - default: "264", - local: "true" - }, - { name: "CreatorSwCfgCpuctrlSize", - desc: "Size of CREATOR_SW_CFG_CPUCTRL", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgMinSecVerRomExtOffset", - desc: "Offset of CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT", - type: "int", - default: "268", - local: "true" - }, - { name: "CreatorSwCfgMinSecVerRomExtSize", - desc: "Size of CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgMinSecVerBl0Offset", - desc: "Offset of CREATOR_SW_CFG_MIN_SEC_VER_BL0", - type: "int", - default: "272", - local: "true" - }, - { name: "CreatorSwCfgMinSecVerBl0Size", - desc: "Size of CREATOR_SW_CFG_MIN_SEC_VER_BL0", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgDefaultBootDataInProdEnOffset", - desc: "Offset of CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN", - type: "int", - default: "276", - local: "true" - }, - { name: "CreatorSwCfgDefaultBootDataInProdEnSize", - desc: "Size of CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRmaSpinEnOffset", - desc: "Offset of CREATOR_SW_CFG_RMA_SPIN_EN", - type: "int", - default: "280", - local: "true" - }, - { name: "CreatorSwCfgRmaSpinEnSize", - desc: "Size of CREATOR_SW_CFG_RMA_SPIN_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRmaSpinCyclesOffset", - desc: "Offset of CREATOR_SW_CFG_RMA_SPIN_CYCLES", - type: "int", - default: "284", - local: "true" - }, - { name: "CreatorSwCfgRmaSpinCyclesSize", - desc: "Size of CREATOR_SW_CFG_RMA_SPIN_CYCLES", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngRepcntThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS", - type: "int", - default: "288", - local: "true" - }, - { name: "CreatorSwCfgRngRepcntThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngRepcntsThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS", - type: "int", - default: "292", - local: "true" - }, - { name: "CreatorSwCfgRngRepcntsThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngAdaptpHiThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS", - type: "int", - default: "296", - local: "true" - }, - { name: "CreatorSwCfgRngAdaptpHiThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngAdaptpLoThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS", - type: "int", - default: "300", - local: "true" - }, - { name: "CreatorSwCfgRngAdaptpLoThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngBucketThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS", - type: "int", - default: "304", - local: "true" - }, - { name: "CreatorSwCfgRngBucketThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngMarkovHiThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS", - type: "int", - default: "308", - local: "true" - }, - { name: "CreatorSwCfgRngMarkovHiThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngMarkovLoThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS", - type: "int", - default: "312", - local: "true" - }, - { name: "CreatorSwCfgRngMarkovLoThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngExthtHiThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS", - type: "int", - default: "316", - local: "true" - }, - { name: "CreatorSwCfgRngExthtHiThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngExthtLoThresholdsOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS", - type: "int", - default: "320", - local: "true" - }, - { name: "CreatorSwCfgRngExthtLoThresholdsSize", - desc: "Size of CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngAlertThresholdOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_ALERT_THRESHOLD", - type: "int", - default: "324", - local: "true" - }, - { name: "CreatorSwCfgRngAlertThresholdSize", - desc: "Size of CREATOR_SW_CFG_RNG_ALERT_THRESHOLD", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgRngHealthConfigDigestOffset", - desc: "Offset of CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST", - type: "int", - default: "328", - local: "true" - }, - { name: "CreatorSwCfgRngHealthConfigDigestSize", - desc: "Size of CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgSramKeyRenewEnOffset", - desc: "Offset of CREATOR_SW_CFG_SRAM_KEY_RENEW_EN", - type: "int", - default: "332", - local: "true" - }, - { name: "CreatorSwCfgSramKeyRenewEnSize", - desc: "Size of CREATOR_SW_CFG_SRAM_KEY_RENEW_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtEnOffset", - desc: "Offset of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN", - type: "int", - default: "336", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtEnSize", - desc: "Size of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtStartOffsetOffset", - desc: "Offset of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET", - type: "int", - default: "340", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtStartOffsetSize", - desc: "Size of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtLengthOffset", - desc: "Offset of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH", - type: "int", - default: "344", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtLengthSize", - desc: "Size of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH", - type: "int", - default: "4", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtSha256HashOffset", - desc: "Offset of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH", - type: "int", - default: "348", - local: "true" - }, - { name: "CreatorSwCfgImmutableRomExtSha256HashSize", - desc: "Size of CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH", - type: "int", - default: "32", - local: "true" - }, - { name: "CreatorSwCfgReservedOffset", - desc: "Offset of CREATOR_SW_CFG_RESERVED", - type: "int", - default: "380", - local: "true" - }, - { name: "CreatorSwCfgReservedSize", - desc: "Size of CREATOR_SW_CFG_RESERVED", - type: "int", - default: "32", - local: "true" - }, - { name: "CreatorSwCfgDigestOffset", - desc: "Offset of CREATOR_SW_CFG_DIGEST", - type: "int", - default: "424", - local: "true" - }, - { name: "CreatorSwCfgDigestSize", - desc: "Size of CREATOR_SW_CFG_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "OwnerSwCfgOffset", - desc: "Offset of the OWNER_SW_CFG partition", - type: "int", - default: "432", - local: "true" - }, - { name: "OwnerSwCfgSize", - desc: "Size of the OWNER_SW_CFG partition", - type: "int", - default: "712", - local: "true" - }, - { name: "OwnerSwCfgRomErrorReportingOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ERROR_REPORTING", - type: "int", - default: "432", - local: "true" - }, - { name: "OwnerSwCfgRomErrorReportingSize", - desc: "Size of OWNER_SW_CFG_ROM_ERROR_REPORTING", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomBootstrapDisOffset", - desc: "Offset of OWNER_SW_CFG_ROM_BOOTSTRAP_DIS", - type: "int", - default: "436", - local: "true" - }, - { name: "OwnerSwCfgRomBootstrapDisSize", - desc: "Size of OWNER_SW_CFG_ROM_BOOTSTRAP_DIS", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertClassEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_CLASS_EN", - type: "int", - default: "440", - local: "true" - }, - { name: "OwnerSwCfgRomAlertClassEnSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_CLASS_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertEscalationOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_ESCALATION", - type: "int", - default: "444", - local: "true" - }, - { name: "OwnerSwCfgRomAlertEscalationSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_ESCALATION", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertClassificationOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION", - type: "int", - default: "448", - local: "true" - }, - { name: "OwnerSwCfgRomAlertClassificationSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION", - type: "int", - default: "320", - local: "true" - }, - { name: "OwnerSwCfgRomLocalAlertClassificationOffset", - desc: "Offset of OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION", - type: "int", - default: "768", - local: "true" - }, - { name: "OwnerSwCfgRomLocalAlertClassificationSize", - desc: "Size of OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION", - type: "int", - default: "64", - local: "true" - }, - { name: "OwnerSwCfgRomAlertAccumThreshOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH", - type: "int", - default: "832", - local: "true" - }, - { name: "OwnerSwCfgRomAlertAccumThreshSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH", - type: "int", - default: "16", - local: "true" - }, - { name: "OwnerSwCfgRomAlertTimeoutCyclesOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES", - type: "int", - default: "848", - local: "true" - }, - { name: "OwnerSwCfgRomAlertTimeoutCyclesSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES", - type: "int", - default: "16", - local: "true" - }, - { name: "OwnerSwCfgRomAlertPhaseCyclesOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES", - type: "int", - default: "864", - local: "true" - }, - { name: "OwnerSwCfgRomAlertPhaseCyclesSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES", - type: "int", - default: "64", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestProdOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD", - type: "int", - default: "928", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestProdSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestProdEndOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END", - type: "int", - default: "932", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestProdEndSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestDevOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV", - type: "int", - default: "936", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestDevSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestRmaOffset", - desc: "Offset of OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA", - type: "int", - default: "940", - local: "true" - }, - { name: "OwnerSwCfgRomAlertDigestRmaSize", - desc: "Size of OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomWatchdogBiteThresholdCyclesOffset", - desc: "Offset of OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES", - type: "int", - default: "944", - local: "true" - }, - { name: "OwnerSwCfgRomWatchdogBiteThresholdCyclesSize", - desc: "Size of OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomKeymgrOtpMeasEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN", - type: "int", - default: "948", - local: "true" - }, - { name: "OwnerSwCfgRomKeymgrOtpMeasEnSize", - desc: "Size of OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgManufStateOffset", - desc: "Offset of OWNER_SW_CFG_MANUF_STATE", - type: "int", - default: "952", - local: "true" - }, - { name: "OwnerSwCfgManufStateSize", - desc: "Size of OWNER_SW_CFG_MANUF_STATE", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomRstmgrInfoEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_RSTMGR_INFO_EN", - type: "int", - default: "956", - local: "true" - }, - { name: "OwnerSwCfgRomRstmgrInfoEnSize", - desc: "Size of OWNER_SW_CFG_ROM_RSTMGR_INFO_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomExtBootstrapEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN", - type: "int", - default: "960", - local: "true" - }, - { name: "OwnerSwCfgRomExtBootstrapEnSize", - desc: "Size of OWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomSensorCtrlAlertCfgOffset", - desc: "Offset of OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG", - type: "int", - default: "964", - local: "true" - }, - { name: "OwnerSwCfgRomSensorCtrlAlertCfgSize", - desc: "Size of OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG", - type: "int", - default: "12", - local: "true" - }, - { name: "OwnerSwCfgRomSramReadbackEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_SRAM_READBACK_EN", - type: "int", - default: "976", - local: "true" - }, - { name: "OwnerSwCfgRomSramReadbackEnSize", - desc: "Size of OWNER_SW_CFG_ROM_SRAM_READBACK_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomPreserveResetReasonEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN", - type: "int", - default: "980", - local: "true" - }, - { name: "OwnerSwCfgRomPreserveResetReasonEnSize", - desc: "Size of OWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomResetReasonCheckValueOffset", - desc: "Offset of OWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE", - type: "int", - default: "984", - local: "true" - }, - { name: "OwnerSwCfgRomResetReasonCheckValueSize", - desc: "Size of OWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomBannerEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_BANNER_EN", - type: "int", - default: "988", - local: "true" - }, - { name: "OwnerSwCfgRomBannerEnSize", - desc: "Size of OWNER_SW_CFG_ROM_BANNER_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgRomFlashEccExcHandlerEnOffset", - desc: "Offset of OWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN", - type: "int", - default: "992", - local: "true" - }, - { name: "OwnerSwCfgRomFlashEccExcHandlerEnSize", - desc: "Size of OWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN", - type: "int", - default: "4", - local: "true" - }, - { name: "OwnerSwCfgReservedOffset", - desc: "Offset of OWNER_SW_CFG_RESERVED", - type: "int", - default: "996", - local: "true" - }, - { name: "OwnerSwCfgReservedSize", - desc: "Size of OWNER_SW_CFG_RESERVED", - type: "int", - default: "128", - local: "true" - }, - { name: "OwnerSwCfgDigestOffset", - desc: "Offset of OWNER_SW_CFG_DIGEST", - type: "int", - default: "1136", - local: "true" - }, - { name: "OwnerSwCfgDigestSize", - desc: "Size of OWNER_SW_CFG_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "RotCreatorAuthCodesignOffset", - desc: "Offset of the ROT_CREATOR_AUTH_CODESIGN partition", - type: "int", - default: "1144", - local: "true" - }, - { name: "RotCreatorAuthCodesignSize", - desc: "Size of the ROT_CREATOR_AUTH_CODESIGN partition", - type: "int", - default: "472", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType0Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE0", - type: "int", - default: "1144", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType0Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE0", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey0Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY0", - type: "int", - default: "1148", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey0Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY0", - type: "int", - default: "64", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType1Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE1", - type: "int", - default: "1212", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType1Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE1", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey1Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY1", - type: "int", - default: "1216", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey1Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY1", - type: "int", - default: "64", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType2Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE2", - type: "int", - default: "1280", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType2Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE2", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey2Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY2", - type: "int", - default: "1284", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey2Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY2", - type: "int", - default: "64", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType3Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE3", - type: "int", - default: "1348", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKeyType3Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE3", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey3Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY3", - type: "int", - default: "1352", - local: "true" - }, - { name: "RotCreatorAuthCodesignEcdsaKey3Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY3", - type: "int", - default: "64", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType0Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE0", - type: "int", - default: "1416", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType0Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE0", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey0Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY0", - type: "int", - default: "1420", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey0Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY0", - type: "int", - default: "32", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig0Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG0", - type: "int", - default: "1452", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig0Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG0", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType1Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE1", - type: "int", - default: "1456", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType1Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE1", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey1Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY1", - type: "int", - default: "1460", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey1Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY1", - type: "int", - default: "32", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig1Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG1", - type: "int", - default: "1492", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig1Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG1", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType2Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE2", - type: "int", - default: "1496", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType2Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE2", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey2Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY2", - type: "int", - default: "1500", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey2Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY2", - type: "int", - default: "32", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig2Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG2", - type: "int", - default: "1532", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig2Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG2", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType3Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE3", - type: "int", - default: "1536", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyType3Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE3", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey3Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY3", - type: "int", - default: "1540", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKey3Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY3", - type: "int", - default: "32", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig3Offset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG3", - type: "int", - default: "1572", - local: "true" - }, - { name: "RotCreatorAuthCodesignSpxKeyConfig3Size", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG3", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthCodesignBlockSha2_256HashOffset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH", - type: "int", - default: "1576", - local: "true" - }, - { name: "RotCreatorAuthCodesignBlockSha2_256HashSize", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH", - type: "int", - default: "32", - local: "true" - }, - { name: "RotCreatorAuthCodesignDigestOffset", - desc: "Offset of ROT_CREATOR_AUTH_CODESIGN_DIGEST", - type: "int", - default: "1608", - local: "true" - }, - { name: "RotCreatorAuthCodesignDigestSize", - desc: "Size of ROT_CREATOR_AUTH_CODESIGN_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "RotCreatorAuthStateOffset", - desc: "Offset of the ROT_CREATOR_AUTH_STATE partition", - type: "int", - default: "1616", - local: "true" - }, - { name: "RotCreatorAuthStateSize", - desc: "Size of the ROT_CREATOR_AUTH_STATE partition", - type: "int", - default: "40", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey0Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_ECDSA_KEY0", - type: "int", - default: "1616", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey0Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_ECDSA_KEY0", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey1Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_ECDSA_KEY1", - type: "int", - default: "1620", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey1Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_ECDSA_KEY1", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey2Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_ECDSA_KEY2", - type: "int", - default: "1624", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey2Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_ECDSA_KEY2", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey3Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_ECDSA_KEY3", - type: "int", - default: "1628", - local: "true" - }, - { name: "RotCreatorAuthStateEcdsaKey3Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_ECDSA_KEY3", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey0Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_SPX_KEY0", - type: "int", - default: "1632", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey0Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_SPX_KEY0", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey1Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_SPX_KEY1", - type: "int", - default: "1636", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey1Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_SPX_KEY1", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey2Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_SPX_KEY2", - type: "int", - default: "1640", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey2Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_SPX_KEY2", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey3Offset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_SPX_KEY3", - type: "int", - default: "1644", - local: "true" - }, - { name: "RotCreatorAuthStateSpxKey3Size", - desc: "Size of ROT_CREATOR_AUTH_STATE_SPX_KEY3", - type: "int", - default: "4", - local: "true" - }, - { name: "RotCreatorAuthStateDigestOffset", - desc: "Offset of ROT_CREATOR_AUTH_STATE_DIGEST", - type: "int", - default: "1648", - local: "true" - }, - { name: "RotCreatorAuthStateDigestSize", - desc: "Size of ROT_CREATOR_AUTH_STATE_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "HwCfg0Offset", - desc: "Offset of the HW_CFG0 partition", - type: "int", - default: "1656", - local: "true" - }, - { name: "HwCfg0Size", - desc: "Size of the HW_CFG0 partition", - type: "int", - default: "72", - local: "true" - }, - { name: "DeviceIdOffset", - desc: "Offset of DEVICE_ID", - type: "int", - default: "1656", - local: "true" - }, - { name: "DeviceIdSize", - desc: "Size of DEVICE_ID", - type: "int", - default: "32", - local: "true" - }, - { name: "ManufStateOffset", - desc: "Offset of MANUF_STATE", - type: "int", - default: "1688", - local: "true" - }, - { name: "ManufStateSize", - desc: "Size of MANUF_STATE", - type: "int", - default: "32", - local: "true" - }, - { name: "HwCfg0DigestOffset", - desc: "Offset of HW_CFG0_DIGEST", - type: "int", - default: "1720", - local: "true" - }, - { name: "HwCfg0DigestSize", - desc: "Size of HW_CFG0_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "HwCfg1Offset", - desc: "Offset of the HW_CFG1 partition", - type: "int", - default: "1728", - local: "true" - }, - { name: "HwCfg1Size", - desc: "Size of the HW_CFG1 partition", - type: "int", - default: "16", - local: "true" - }, - { name: "EnSramIfetchOffset", - desc: "Offset of EN_SRAM_IFETCH", - type: "int", - default: "1728", - local: "true" - }, - { name: "EnSramIfetchSize", - desc: "Size of EN_SRAM_IFETCH", - type: "int", - default: "1", - local: "true" - }, - { name: "EnCsrngSwAppReadOffset", - desc: "Offset of EN_CSRNG_SW_APP_READ", - type: "int", - default: "1729", - local: "true" - }, - { name: "EnCsrngSwAppReadSize", - desc: "Size of EN_CSRNG_SW_APP_READ", - type: "int", - default: "1", - local: "true" - }, - { name: "DisRvDmLateDebugOffset", - desc: "Offset of DIS_RV_DM_LATE_DEBUG", - type: "int", - default: "1730", - local: "true" - }, - { name: "DisRvDmLateDebugSize", - desc: "Size of DIS_RV_DM_LATE_DEBUG", - type: "int", - default: "1", - local: "true" - }, - { name: "HwCfg1DigestOffset", - desc: "Offset of HW_CFG1_DIGEST", - type: "int", - default: "1736", - local: "true" - }, - { name: "HwCfg1DigestSize", - desc: "Size of HW_CFG1_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "Secret0Offset", - desc: "Offset of the SECRET0 partition", - type: "int", - default: "1744", - local: "true" - }, - { name: "Secret0Size", - desc: "Size of the SECRET0 partition", - type: "int", - default: "40", - local: "true" - }, - { name: "TestUnlockTokenOffset", - desc: "Offset of TEST_UNLOCK_TOKEN", - type: "int", - default: "1744", - local: "true" - }, - { name: "TestUnlockTokenSize", - desc: "Size of TEST_UNLOCK_TOKEN", - type: "int", - default: "16", - local: "true" - }, - { name: "TestExitTokenOffset", - desc: "Offset of TEST_EXIT_TOKEN", - type: "int", - default: "1760", - local: "true" - }, - { name: "TestExitTokenSize", - desc: "Size of TEST_EXIT_TOKEN", - type: "int", - default: "16", - local: "true" - }, - { name: "Secret0DigestOffset", - desc: "Offset of SECRET0_DIGEST", - type: "int", - default: "1776", - local: "true" - }, - { name: "Secret0DigestSize", - desc: "Size of SECRET0_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "Secret1Offset", - desc: "Offset of the SECRET1 partition", - type: "int", - default: "1784", - local: "true" - }, - { name: "Secret1Size", - desc: "Size of the SECRET1 partition", - type: "int", - default: "88", - local: "true" - }, - { name: "FlashAddrKeySeedOffset", - desc: "Offset of FLASH_ADDR_KEY_SEED", - type: "int", - default: "1784", - local: "true" - }, - { name: "FlashAddrKeySeedSize", - desc: "Size of FLASH_ADDR_KEY_SEED", - type: "int", - default: "32", - local: "true" - }, - { name: "FlashDataKeySeedOffset", - desc: "Offset of FLASH_DATA_KEY_SEED", - type: "int", - default: "1816", - local: "true" - }, - { name: "FlashDataKeySeedSize", - desc: "Size of FLASH_DATA_KEY_SEED", - type: "int", - default: "32", - local: "true" - }, - { name: "SramDataKeySeedOffset", - desc: "Offset of SRAM_DATA_KEY_SEED", - type: "int", - default: "1848", - local: "true" - }, - { name: "SramDataKeySeedSize", - desc: "Size of SRAM_DATA_KEY_SEED", - type: "int", - default: "16", - local: "true" - }, - { name: "Secret1DigestOffset", - desc: "Offset of SECRET1_DIGEST", - type: "int", - default: "1864", - local: "true" - }, - { name: "Secret1DigestSize", - desc: "Size of SECRET1_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "Secret2Offset", - desc: "Offset of the SECRET2 partition", - type: "int", - default: "1872", - local: "true" - }, - { name: "Secret2Size", - desc: "Size of the SECRET2 partition", - type: "int", - default: "88", - local: "true" - }, - { name: "RmaTokenOffset", - desc: "Offset of RMA_TOKEN", - type: "int", - default: "1872", - local: "true" - }, - { name: "RmaTokenSize", - desc: "Size of RMA_TOKEN", - type: "int", - default: "16", - local: "true" - }, - { name: "CreatorRootKeyShare0Offset", - desc: "Offset of CREATOR_ROOT_KEY_SHARE0", - type: "int", - default: "1888", - local: "true" - }, - { name: "CreatorRootKeyShare0Size", - desc: "Size of CREATOR_ROOT_KEY_SHARE0", - type: "int", - default: "32", - local: "true" - }, - { name: "CreatorRootKeyShare1Offset", - desc: "Offset of CREATOR_ROOT_KEY_SHARE1", - type: "int", - default: "1920", - local: "true" - }, - { name: "CreatorRootKeyShare1Size", - desc: "Size of CREATOR_ROOT_KEY_SHARE1", - type: "int", - default: "32", - local: "true" - }, - { name: "Secret2DigestOffset", - desc: "Offset of SECRET2_DIGEST", - type: "int", - default: "1952", - local: "true" - }, - { name: "Secret2DigestSize", - desc: "Size of SECRET2_DIGEST", - type: "int", - default: "8", - local: "true" - }, - { name: "LifeCycleOffset", - desc: "Offset of the LIFE_CYCLE partition", - type: "int", - default: "1960", - local: "true" - }, - { name: "LifeCycleSize", - desc: "Size of the LIFE_CYCLE partition", - type: "int", - default: "88", - local: "true" - }, - { name: "LcTransitionCntOffset", - desc: "Offset of LC_TRANSITION_CNT", - type: "int", - default: "1960", - local: "true" - }, - { name: "LcTransitionCntSize", - desc: "Size of LC_TRANSITION_CNT", - type: "int", - default: "48", - local: "true" - }, - { name: "LcStateOffset", - desc: "Offset of LC_STATE", - type: "int", - default: "2008", - local: "true" - }, - { name: "LcStateSize", - desc: "Size of LC_STATE", - type: "int", - default: "40", - local: "true" - }, - ] - - ///////////////////////////// - // Intermodule Connections // - ///////////////////////////// - - inter_signal_list: [ - // OTP dedicated power connection from AST - { struct: "" - type: "io" - name: "otp_ext_voltage_h" - act: "none" - default: "'0" - package: "", - } - // Power sequencing signals to AST - { struct: "otp_ast_req" - type: "uni" - name: "otp_ast_pwr_seq" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Power sequencing signals to AST (VDD domain)." - } - // Power sequencing signals from AST - { struct: "otp_ast_rsp" - type: "uni" - name: "otp_ast_pwr_seq_h" - act: "rcv" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Power sequencing signals coming from AST (VCC domain)." - } - // EDN interface - { struct: "edn" - type: "req_rsp" - name: "edn" - act: "req" - package: "edn_pkg" - desc: "Entropy request to the entropy distribution network for LFSR reseeding and ephemeral key derivation." - } - // Power manager init command - { struct: "pwr_otp" - type: "req_rsp" - name: "pwr_otp" - act: "rsp" - default: "'0" - package: "pwrmgr_pkg" - desc: "Initialization request/acknowledge from/to power manager." - } - // Macro-specific test signals to/from LC TAP - { struct: "lc_otp_vendor_test" - type: "req_rsp" - name: "lc_otp_vendor_test" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Vendor test control signals from/to the life cycle TAP." - } - // LC transition command - { struct: "lc_otp_program" - type: "req_rsp" - name: "lc_otp_program" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Life cycle state transition interface." - } - // Broadcast to LC - { struct: "otp_lc_data" - type: "uni" - name: "otp_lc_data" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: ''' - Life cycle state output holding the current life cycle state, - the value of the transition counter and the tokens needed for life cycle transitions. - ''' - } - // Broadcast from LC - { struct: "lc_tx" - type: "uni" - name: "lc_escalate_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Life cycle escalation enable coming from life cycle controller. - This signal moves all FSMs within OTP into the error state. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_creator_seed_sw_rw_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Provision enable qualifier coming from life cycle controller. - This signal enables SW read / write access to the RMA_TOKEN and CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_owner_seed_sw_rw_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Provision enable qualifier coming from life cycle controller. - This signal enables SW read / write access to the OWNER_SEED. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_seed_hw_rd_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Seed read enable coming from life cycle controller. - This signal enables HW read access to the CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_dft_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Test enable qualifier coming from life cycle controller. - This signals enables the TL-UL access port to the proprietary OTP IP. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_check_byp_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Life cycle partition check bypass signal. - This signal causes the life cycle partition to bypass consistency checks during life cycle state transitions in order to prevent spurious consistency check failures. - ''' - } - // Broadcast to Key Manager - { struct: "otp_keymgr_key" - type: "uni" - name: "otp_keymgr_key" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key output to the key manager holding CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1." - } - // Broadcast to Flash Controller - { struct: "flash_otp_key" - type: "req_rsp" - name: "flash_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key derivation interface for FLASH scrambling." - } - // Key request from SRAM scramblers - { struct: "sram_otp_key" - // TODO: would be nice if this could accept parameters. - // Split this out into an issue. - width: "4" - type: "req_rsp" - name: "sram_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Array with key derivation interfaces for SRAM scrambling devices." - } - // Key request from OTBN RAM Scrambler - { struct: "otbn_otp_key" - type: "req_rsp" - name: "otbn_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key derivation interface for OTBN scrambling devices." - } - // Hardware config partition - { struct: "otp_broadcast" - type: "uni" - name: "otp_broadcast" - act: "req" - default: "'0" - package: "otp_ctrl_part_pkg" - desc: "Output of the HW partitions with breakout data types." - } - // AST observability control - { struct: "ast_obs_ctrl", - type: "uni", - name: "obs_ctrl", - act: "rcv", - package: "ast_pkg" - desc: "AST observability control signals." - } - // prim otp observe bus - { struct: "logic", - type: "uni", - name: "otp_obs", - act: "req", - width: "8", - package: "" - desc: "AST observability bus." - } - ] // inter_signal_list - - ///////////////////// - // Countermeasures // - ///////////////////// - - countermeasures: [ - { name: "BUS.INTEGRITY", - desc: "End-to-end bus integrity scheme." - } - { name: "SECRET.MEM.SCRAMBLE", - desc: "Secret partitions are scrambled with a full-round PRESENT cipher." - } - { name: "PART.MEM.DIGEST", - desc: "Integrity of buffered partitions is ensured via a 64bit digest." - } - { name: "DAI.FSM.SPARSE", - desc: "The direct access interface FSM is sparsely encoded." - } - { name: "KDI.FSM.SPARSE", - desc: "The key derivation interface FSM is sparsely encoded." - } - { name: "LCI.FSM.SPARSE", - desc: "The life cycle interface FSM is sparsely encoded." - } - { name: "PART.FSM.SPARSE", - desc: "The partition FSMs are sparsely encoded." - } - { name: "SCRMBL.FSM.SPARSE", - desc: "The scramble datapath FSM is sparsely encoded." - } - { name: "TIMER.FSM.SPARSE", - desc: "The background check timer FSM is sparsely encoded." - } - { name: "DAI.CTR.REDUN", - desc: "The direct access interface address counter employs a cross-counter implementation." - } - { name: "KDI_SEED.CTR.REDUN", - desc: "The key derivation interface counter employs a cross-counter implementation." - } - { name: "KDI_ENTROPY.CTR.REDUN", - desc: "The key derivation entropy counter employs a cross-counter implementation." - } - { name: "LCI.CTR.REDUN", - desc: "The life cycle interface address counter employs a cross-counter implementation." - } - { name: "PART.CTR.REDUN", - desc: "The address counter of buffered partitions employs a cross-counter implementation." - } - { name: "SCRMBL.CTR.REDUN", - desc: "The srambling datapath counter employs a cross-counter implementation." - } - { name: "TIMER_INTEG.CTR.REDUN", - desc: "The background integrity check timer employs a duplicated counter implementation." - } - { name: "TIMER_CNSTY.CTR.REDUN", - desc: "The background consistency check timer employs a duplicated counter implementation." - } - { name: "TIMER.LFSR.REDUN", - desc: "The background check LFSR is duplicated." - } - { name: "DAI.FSM.LOCAL_ESC", - desc: "The direct access interface FSM is moved into an invalid state upon local escalation." - } - { name: "LCI.FSM.LOCAL_ESC", - desc: "The life cycle interface FSM is moved into an invalid state upon local escalation." - } - { name: "KDI.FSM.LOCAL_ESC", - desc: "The key derivation interface FSM is moved into an invalid state upon local escalation." - } - { name: "PART.FSM.LOCAL_ESC", - desc: "The partition FSMs are moved into an invalid state upon local escalation." - } - { name: "SCRMBL.FSM.LOCAL_ESC", - desc: "The scramble datapath FSM is moved into an invalid state upon local escalation." - } - { name: "TIMER.FSM.LOCAL_ESC", - desc: "The background check timer FSM is moved into an invalid state upon local escalation." - } - { name: "DAI.FSM.GLOBAL_ESC", - desc: "The direct access interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "LCI.FSM.GLOBAL_ESC", - desc: "The life cycle interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "KDI.FSM.GLOBAL_ESC", - desc: "The key derivation interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "PART.FSM.GLOBAL_ESC", - desc: "The partition FSMs are moved into an invalid state upon global escalation via life cycle." - } - { name: "SCRMBL.FSM.GLOBAL_ESC", - desc: "The scramble datapath FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "TIMER.FSM.GLOBAL_ESC", - desc: "The background check timer FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "PART.DATA_REG.INTEGRITY", - desc: "All partition buffer registers are protected with ECC on 64bit blocks." - } - { name: "PART.DATA_REG.BKGN_CHK", - desc: "The digest of buffered partitions is recomputed and checked at pseudorandom intervals in the background." - } - { name: "PART.MEM.REGREN" - desc: "Unbuffered ('software') partitions can be read-locked via a CSR until the next system reset." - } - { name: "PART.MEM.SW_UNREADABLE" - desc: "Secret buffered partitions become unreadable to software once they are locked via the digest." - } - { name: "PART.MEM.SW_UNWRITABLE" - desc: "All partitions become unwritable by software once they are locked via the digest." - } - { name: "LC_PART.MEM.SW_NOACCESS" - desc: "The life cycle partition is not directly readable nor writable via software." - } - { name: "ACCESS.CTRL.MUBI", - desc: "The access control signals going from the partitions to the DAI are MUBI encoded." - } - { name: "TOKEN_VALID.CTRL.MUBI", - desc: "The token valid signals going to the life cycle controller are MUBI encoded." - } - { name: "LC_CTRL.INTERSIG.MUBI", - desc: "The life cycle control signals are multibit encoded." - } - { name: "TEST.BUS.LC_GATED", - desc: "Prevent access to test signals and the OTP backdoor interface in non-test lifecycle states." - } - { name: "TEST_TL_LC_GATE.FSM.SPARSE", - desc: "The control FSM inside the TL-UL gating primitive is sparsely encoded." - } - { name: "DIRECT_ACCESS.CONFIG.REGWEN", - desc: "The direct access CSRs are REGWEN protected." - } - { name: "CHECK_TRIGGER.CONFIG.REGWEN", - desc: "The check trigger CSR is REGWEN protected." - } - { name: "CHECK.CONFIG.REGWEN", - desc: "The check CSR is REGWEN protected." - } - { name: "MACRO.MEM.INTEGRITY", - desc: ''' - The OTP macro employs a vendor-specific integrity scheme at the granularity of the native 16bit OTP words. - The scheme is able to at least detect single bit errors. - ''' - } - { name: "MACRO.MEM.CM", - desc: "The OTP macro may contain additional vendor-specific countermeasures." - } - ] - - features: [ - { - name: "OTP_CTRL.PARTITION.VENDOR_TEST" - desc: '''Vendor test partition is used for OTP programming smoke check during manufacturing flow. - In this partition, ECC uncorrectable errors will not lead to fatal errors and alerts. - Instead the error will be reported as correctable ECC error. - ''' - } - { - name: "OTP_CTRL.PARTITION.CREATOR_SW_CFG" - desc: '''During calibration stage, various parameters (clock, voltage, and timing sources) are calibrated and recorded to CREATOR_SW_CFG partition. - ''' - } - { - name: "OTP_CTRL.PARTITION.OWNER_SW_CFG" - desc: "Define attriutes for rom code execution" - } - { - name: "OTP_CTRL.INIT" - desc: '''When power is up, OTP controller reads devices status. - After all reads complete, the controller performs integrity check on the HW_CFG* and SECRET partitions. - Once all integrity checks are complete, the controller marks outputs as valid. - ''' - } - { - name: "OTP_CTRL.ENTROPY_READ" - desc: '''Firmware can read entropy from ENTROPY_SRC block by configuring following field of HW_CFG* partition. - - EN_CSRNG_SW_APP_READ - ''' - } - { - name: "OTP_CTRL.KEY_DERIVATION" - desc: "OTP controller participate key derivation process by providing scramble key seed to SRAM_CTRL and FLASH_CTRL." - } - { - name: "OTP_CTRL.PROGRAM" - desc: '''All other partitions except life cycle partition are programmed through DAI interface. - And once non-zero digest is programmed to these partition, no further write access is allowed. - Life cycle partition is programmed by LC_CTRL. - ''' - } - { - name: "OTP_CTRL.PARTITION.SECRET0" - desc: "Test unlock tokens, Test exit token" - } - { - name: "OTP_CTRL.PARTITION.SECRET1" - desc: "SRAM and FLASH scrambling key" - } - { - name: "OTP_CTRL.PARTITION.SECRET2" - desc: "RMA unlock token and creator root key" - } - { - name: "OTP_CTRL.PARTITION.LIFE_CYCLE" - desc: '''LC state, LC transition count. - This feature is owned by the LC_CTRL and cannot be tested well through the OTP_CTRL CSR interface. - ''' - } - { - name: "OTP_CTRL.PARTITIONS_FEATURE.READ_LOCK" - desc: '''Following partitions can be read lockable by CSR. - - VENDOR_TEST - - CREATOR_SW_CFG - - OWNER_SW_CFG - Following partitions can be read lockable by writing digest. - - SECRET0 - - SECRET1 - - RECRET2 - All read attempt to these partitions after read is locked will trigger AccessError (recoverable). - ''' - } - { - name: "OTP_CTRL.PARTITIONS_FEATURE.WRITE_LOCK" - desc: "All partitions except LIFE_CYCLE can be write lockable by writing digest." - } - { - name: "OTP_CTRL.ERROR_HANDLING.RECOVERABLE" - desc: "Recoverable error is created when unauthorized access atempt are detected via dai interface." - } - { - name: "OTP_CTRL.ERROR_HANDLING.FATAL" - desc: "Unrecoverable errors are created for uncorrectable ecc error, otp macro malfunction and unauthorized access via lc_ctrl." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.CHECK_TIMEOUT" - desc: "Timeout value for the integrity and consistency checks." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.INTEGRITY_CHECK_PERIOD" - desc: "The interval which the digest of the partition is recomputed to check integrity of locked partition." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.CONSISTENCY_CHECK_PERIOD" - desc: "Re-read period of the buffer registers to ensure data is matched with the associated OTP partition." - } - ] - - /////////////// - // Registers // - /////////////// - - regwidth: "32", - registers: { - core: [ - //////////////////////// - // Ctrl / Status CSRs // - //////////////////////// - - { name: "STATUS", - desc: "OTP status register.", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - resval: 0, - tags: [ // OTP internal HW can modify status register - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "0" - name: "VENDOR_TEST_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "1" - name: "CREATOR_SW_CFG_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "2" - name: "OWNER_SW_CFG_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "3" - name: "ROT_CREATOR_AUTH_CODESIGN_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "4" - name: "ROT_CREATOR_AUTH_STATE_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "5" - name: "HW_CFG0_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "6" - name: "HW_CFG1_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "7" - name: "SECRET0_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "8" - name: "SECRET1_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "9" - name: "SECRET2_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "10" - name: "LIFE_CYCLE_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "11" - name: "DAI_ERROR" - desc: ''' - Set to 1 if an error occurred in the DAI. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "12" - name: "LCI_ERROR" - desc: ''' - Set to 1 if an error occurred in the LCI. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "13" - name: "TIMEOUT_ERROR" - desc: ''' - Set to 1 if an integrity or consistency check times out. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "14" - name: "LFSR_FSM_ERROR" - desc: ''' - Set to 1 if the LFSR timer FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "15" - name: "SCRAMBLING_FSM_ERROR" - desc: ''' - Set to 1 if the scrambling datapath FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "16" - name: "KEY_DERIV_FSM_ERROR" - desc: ''' - Set to 1 if the key derivation FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "17" - name: "BUS_INTEG_ERROR" - desc: ''' - This bit is set to 1 if a fatal bus integrity fault is detected. - This error triggers a fatal_bus_integ_error alert. - ''' - } - { bits: "18" - name: "DAI_IDLE" - desc: "Set to 1 if the DAI is idle and ready to accept commands." - } - { bits: "19" - name: "CHECK_PENDING" - desc: "Set to 1 if an integrity or consistency check triggered by the LFSR timer or via !!CHECK_TRIGGER is pending." - } - ] - } - { multireg: { - name: "ERR_CODE", - desc: ''' - This register holds information about error conditions that occurred in the agents - interacting with the OTP macro via the internal bus. The error codes should be checked - if the partitions, DAI or LCI flag an error in the !!STATUS register, or when an - !!INTR_STATE.otp_error has been triggered. Note that all errors trigger an otp_error - interrupt, and in addition some errors may trigger either an fatal_macro_error or an - fatal_check_error alert. - ''', - count: "NumErrorEntries", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "AGENT", - compact: "false", - resval: 0, - tags: [ // OTP internal HW can modify the error code registers - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { - bits: "2:0" - enum: [ - { value: "0", - name: "NO_ERROR", - desc: ''' - No error condition has occurred. - ''' - }, - { value: "1", - name: "MACRO_ERROR", - desc: ''' - Returned if the OTP macro command was invalid or did not complete successfully - due to a macro malfunction. - This error should never occur during normal operation and is not recoverable. - This error triggers an fatal_macro_error alert. - ''' - }, - { value: "2", - name: "MACRO_ECC_CORR_ERROR", - desc: ''' - A correctable ECC error has occured during an OTP read operation. - The corresponding controller automatically recovers from this error when - issuing a new command. - ''' - }, - { value: "3", - name: "MACRO_ECC_UNCORR_ERROR", - desc: ''' - An uncorrectable ECC error has occurred during an OTP read operation. - This error should never occur during normal operation and is not recoverable. - If this error is present this may be a sign that the device is malfunctioning. - This error triggers an fatal_macro_error alert. - ''' - }, - { value: "4", - name: "MACRO_WRITE_BLANK_ERROR", - desc: ''' - This error is returned if a programming operation attempted to clear a bit that has previously been programmed to 1. - The corresponding controller automatically recovers from this error when issuing a new command. - - Note however that the affected OTP word may be left in an inconsistent state if this error occurs. - This can cause several issues when the word is accessed again (either as part of a regular read operation, as part of the readout at boot, or as part of a background check). - - It is important that SW ensures that each word is only written once, since this can render the device useless. - ''' - }, - { value: "5", - name: "ACCESS_ERROR", - desc: ''' - This error indicates that a locked memory region has been accessed. - The corresponding controller automatically recovers from this error when issuing a new command. - ''' - }, - { value: "6", - name: "CHECK_FAIL_ERROR", - desc: ''' - An ECC, integrity or consistency mismatch has been detected in the buffer registers. - This error should never occur during normal operation and is not recoverable. - This error triggers an fatal_check_error alert. - ''' - }, - { value: "7", - name: "FSM_STATE_ERROR", - desc: ''' - The FSM of the corresponding controller has reached an invalid state, or the FSM has - been moved into a terminal error state due to an escalation action via lc_escalate_en_i. - This error should never occur during normal operation and is not recoverable. - If this error is present, this is a sign that the device has fallen victim to - an invasive attack. This error triggers an fatal_check_error alert. - ''' - }, - ] - } - ] - } - } - { name: "DIRECT_ACCESS_REGWEN", - desc: ''' - Register write enable for all direct access interface registers. - ''', - swaccess: "rw0c", - hwaccess: "hrw", - hwext: "true", - hwqe: "true", - tags: [ // OTP internal HW will set this enable register to 0 when OTP is not under IDLE - // state, so could not auto-predict its value - "excl:CsrNonInitTests:CsrExclCheck"], - fields: [ - { - bits: "0", - desc: ''' - This bit controls whether the DAI registers can be written. - Write 0 to it in order to clear the bit. - - Note that the hardware also modulates this bit and sets it to 0 temporarily - during an OTP operation such that the corresponding address and data registers - cannot be modified while an operation is pending. The !!DAI_IDLE status bit - will also be set to 0 in such a case. - ''' - resval: 1, - }, - ] - }, - { name: "DIRECT_ACCESS_CMD", - desc: "Command register for direct accesses.", - swaccess: "r0w1c", - hwaccess: "hro", - hwqe: "true", - hwext: "true", - resval: 0, - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // Write to DIRECT_ACCESS_CMD randomly might cause OTP_ERRORs and illegal sequences - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - name: "RD", - desc: ''' - Initiates a readout sequence that reads the location specified - by !!DIRECT_ACCESS_ADDRESS. The command places the data read into - !!DIRECT_ACCESS_RDATA_0 and !!DIRECT_ACCESS_RDATA_1 (for 64bit partitions). - ''' - } - { bits: "1", - name: "WR", - desc: ''' - Initiates a programming sequence that writes the data in !!DIRECT_ACCESS_WDATA_0 - and !!DIRECT_ACCESS_WDATA_1 (for 64bit partitions) to the location specified by - !!DIRECT_ACCESS_ADDRESS. - ''' - } - { bits: "2", - name: "DIGEST", - desc: ''' - Initiates the digest calculation and locking sequence for the partition specified by - !!DIRECT_ACCESS_ADDRESS. - ''' - } - ] - } - { name: "DIRECT_ACCESS_ADDRESS", - desc: "Address register for direct accesses.", - swaccess: "rw", - hwaccess: "hro", - hwqe: "false", - resval: 0, - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The enable register "DIRECT_ACCESS_REGWEN" is HW controlled, - // so not able to predict this register value automatically - "excl:CsrNonInitTests:CsrExclCheck"], - fields: [ - { bits: "OtpByteAddrWidth-1:0", - desc: ''' - This is the address for the OTP word to be read or written through - the direct access interface. Note that the address is aligned to the access size - internally, hence bits 1:0 are ignored for 32bit accesses, and bits 2:0 are ignored - for 64bit accesses. - - For the digest calculation command, set this register to the partition base offset. - ''' - } - ] - } - { multireg: { - name: "DIRECT_ACCESS_WDATA", - desc: '''Write data for direct accesses. - Hardware automatically determines the access granule (32bit or 64bit) based on which - partition is being written to. - ''', - count: "NumDaiWords", // 2 x 32bit = 64bit - swaccess: "rw", - hwaccess: "hro", - hwqe: "false", - regwen: "DIRECT_ACCESS_REGWEN", - cname: "WORD", - resval: 0, - tags: [ // The value of this register is written from "DIRECT_ACCESS_RDATA", - // so could not predict this register value automatically - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "DIRECT_ACCESS_RDATA", - desc: '''Read data for direct accesses. - Hardware automatically determines the access granule (32bit or 64bit) based on which - partition is read from. - ''', - count: "NumDaiWords", // 2 x 32bit = 64bit - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - fields: [ - { bits: "31:0" - } - ] - } - }, - - ////////////////////////////////////// - // Integrity and Consistency Checks // - ////////////////////////////////////// - { name: "CHECK_TRIGGER_REGWEN", - desc: ''' - Register write enable for !!CHECK_TRIGGER. - ''', - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, the !!CHECK_TRIGGER register cannot be written anymore. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "CHECK_TRIGGER", - desc: "Command register for direct accesses.", - swaccess: "r0w1c", - hwaccess: "hro", - hwqe: "true", - hwext: "true", - resval: 0, - regwen: "CHECK_TRIGGER_REGWEN", - fields: [ - { bits: "0", - name: "INTEGRITY", - desc: ''' - Writing 1 to this bit triggers an integrity check. SW should monitor !!STATUS.CHECK_PENDING - and wait until the check has been completed. If there are any errors, those will be flagged - in the !!STATUS and !!ERR_CODE registers, and via the interrupts and alerts. - ''' - } - { bits: "1", - name: "CONSISTENCY", - desc: ''' - Writing 1 to this bit triggers a consistency check. SW should monitor !!STATUS.CHECK_PENDING - and wait until the check has been completed. If there are any errors, those will be flagged - in the !!STATUS and !!ERR_CODE registers, and via interrupts and alerts. - ''' - } - ] - }, - { name: "CHECK_REGWEN", - desc: ''' - Register write enable for !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD. - ''', - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD registers cannot be written anymore. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "CHECK_TIMEOUT", - desc: ''' - Timeout value for the integrity and consistency checks. - ''', - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - tags: [ // Do not write to this automatically, as it may trigger fatal alert, and cause - // escalation. - "excl:CsrAllTests:CsrExclWrite"], - fields: [ - { bits: "31:0", - desc: ''' - Timeout value in cycles for the for the integrity and consistency checks. If an integrity or consistency - check does not complete within the timeout window, an error will be flagged in the !!STATUS register, - an otp_error interrupt will be raised, and an fatal_check_error alert will be sent out. The timeout should - be set to a large value to stay on the safe side. The maximum check time can be upper bounded by the - number of cycles it takes to readout, scramble and digest the entire OTP array. Since this amounts to - roughly 25k cycles, it is recommended to set this value to at least 100'000 cycles in order to stay on the - safe side. A value of zero disables the timeout mechanism (default). - ''' - resval: 0, - }, - ] - }, - { name: "INTEGRITY_CHECK_PERIOD", - desc: ''' - This value specifies the maximum period that can be generated pseudo-randomly. - Only applies to the HW_CFG* and SECRET* partitions once they are locked. - ''' - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - fields: [ - { bits: "31:0", - desc: ''' - The pseudo-random period is generated using a 40bit LFSR internally, and this register defines - the bit mask to be applied to the LFSR output in order to limit its range. The value of this - register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. - A recommended value is 0x3_FFFF, corresponding to a maximum period of ~2.8s at 24MHz. - A value of zero disables the timer (default). Note that a one-off check can always be triggered via - !!CHECK_TRIGGER.INTEGRITY. - ''' - resval: "0" - } - ] - } - { name: "CONSISTENCY_CHECK_PERIOD", - desc: ''' - This value specifies the maximum period that can be generated pseudo-randomly. - This applies to the LIFE_CYCLE partition and the HW_CFG* and SECRET* partitions once they are locked. - ''' - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - fields: [ - { bits: "31:0", - desc: ''' - The pseudo-random period is generated using a 40bit LFSR internally, and this register defines - the bit mask to be applied to the LFSR output in order to limit its range. The value of this - register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. - A recommended value is 0x3FF_FFFF, corresponding to a maximum period of ~716s at 24MHz. - A value of zero disables the timer (default). Note that a one-off check can always be triggered via - !!CHECK_TRIGGER.CONSISTENCY. - ''' - resval: "0" - } - ] - } - - //////////////////////////////////// - // Dynamic Locks of SW Parititons // - //////////////////////////////////// - { name: "VENDOR_TEST_READ_LOCK", - desc: ''' - Runtime read lock for the VENDOR_TEST partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the VENDOR_TEST partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "CREATOR_SW_CFG_READ_LOCK", - desc: ''' - Runtime read lock for the CREATOR_SW_CFG partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the CREATOR_SW_CFG partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "OWNER_SW_CFG_READ_LOCK", - desc: ''' - Runtime read lock for the OWNER_SW_CFG partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the OWNER_SW_CFG partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "ROT_CREATOR_AUTH_CODESIGN_READ_LOCK", - desc: ''' - Runtime read lock for the ROT_CREATOR_AUTH_CODESIGN partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the ROT_CREATOR_AUTH_CODESIGN partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "ROT_CREATOR_AUTH_STATE_READ_LOCK", - desc: ''' - Runtime read lock for the ROT_CREATOR_AUTH_STATE partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the ROT_CREATOR_AUTH_STATE partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - - /////////////////////// - // Integrity Digests // - /////////////////////// - { multireg: { - name: "VENDOR_TEST_DIGEST", - desc: ''' - Integrity digest for the VENDOR_TEST partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the VENDOR_TEST partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "CREATOR_SW_CFG_DIGEST", - desc: ''' - Integrity digest for the CREATOR_SW_CFG partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the CREATOR_SW_CFG partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "OWNER_SW_CFG_DIGEST", - desc: ''' - Integrity digest for the OWNER_SW_CFG partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the OWNER_SW_CFG partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "ROT_CREATOR_AUTH_CODESIGN_DIGEST", - desc: ''' - Integrity digest for the ROT_CREATOR_AUTH_CODESIGN partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the ROT_CREATOR_AUTH_CODESIGN partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "ROT_CREATOR_AUTH_STATE_DIGEST", - desc: ''' - Integrity digest for the ROT_CREATOR_AUTH_STATE partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the ROT_CREATOR_AUTH_STATE partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "HW_CFG0_DIGEST", - desc: ''' - Integrity digest for the HW_CFG0 partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "HW_CFG1_DIGEST", - desc: ''' - Integrity digest for the HW_CFG1 partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "SECRET0_DIGEST", - desc: ''' - Integrity digest for the SECRET0 partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "SECRET1_DIGEST", - desc: ''' - Integrity digest for the SECRET1 partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "SECRET2_DIGEST", - desc: ''' - Integrity digest for the SECRET2 partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - - //////////////////////////////// - // Software Config Partitions // - //////////////////////////////// - { skipto: "0x800" } - - { window: { - name: "SW_CFG_WINDOW" - items: "NumSwCfgWindowWords" - swaccess: "ro", - desc: ''' - Any read to this window directly maps to the corresponding offset in the creator and owner software - config partitions, and triggers an OTP readout of the bytes requested. Note that the transaction - will block until OTP readout has completed. - ''' - } - } - ], - - // OTP wrapper-specific registers - prim: [ - { name: "CSR0", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "0", - name: "field0", - desc: "", - resval: "0x0", - } - { bits: "1", - name: "field1", - desc: "", - resval: "0x0", - } - { bits: "2", - name: "field2", - desc: "", - resval: "0x0", - } - { bits: "13:4", - name: "field3", - desc: "" - resval: "0x0", - } - { bits: "26:16", - name: "field4", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR1", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "6:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "7:7", - name: "field1", - desc: "", - resval: "0x0", - } - { bits: "14:8", - name: "field2", - desc: "" - resval: "0x0", - } - { bits: "15:15", - name: "field3", - desc: "", - resval: "0x0", - } - { bits: "31:16", - name: "field4", - desc: "", - resval: "0x0", - } - ] - }, - { name: "CSR2", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "0", - name: "field0", - desc: "", - resval: "0x0", - } - ] - }, - { name: "CSR3", - desc: "" - swaccess: "rw", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "2:0", - name: "field0", - desc: "" - swaccess: "rw1c", - resval: "0x0", - } - { bits: "13:4", - name: "field1", - desc: "", - swaccess: "rw1c", - resval: "0x0", - } - { bits: "16", - name: "field2", - desc: "", - swaccess: "rw1c", - resval: "0x0", - } - { bits: "17", - name: "field3", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "18", - name: "field4", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "19", - name: "field5", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "20", - name: "field6", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "21", - name: "field7", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "22", - name: "field8", - desc: "", - swaccess: "ro", - resval: "0x0", - } - ] - }, - { name: "CSR4", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "9:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "12", - name: "field1", - desc: "" - resval: "0x0", - } - { bits: "13", - name: "field2", - desc: "" - resval: "0x0", - } - { bits: "14", - name: "field3", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR5", - desc: "" - swaccess: "rw", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "5:0", - name: "field0", - desc: "" - swaccess: "rw", - resval: "0x0", - } - { bits: "7:6", - name: "field1", - desc: "" - swaccess: "rw", - resval: "0x0", - } - { bits: "8", - name: "field2", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "11:9", - name: "field3", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "12", - name: "field4", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "13", - name: "field5", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "31:16", - name: "field6", - desc: "" - swaccess: "rw", - resval: "0x0", - } - ] - }, - { name: "CSR6", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "9:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "11", - name: "field1", - desc: "", - swaccess: "rw", - resval: "0x0", - } - { bits: "12", - name: "field2", - desc: "", - swaccess: "rw", - resval: "0x0", - } - { bits: "31:16", - name: "field3", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR7", - desc: "", - swaccess: "ro", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "5:0", - name: "field0", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "10:8", - name: "field1", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "14", - name: "field2", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "15", - name: "field3", - desc: "", - swaccess: "ro", - resval: "0x0", - } - ] - }, - ] - } -} diff --git a/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl b/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl deleted file mode 100644 index f9e96a5c05193..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl +++ /dev/null @@ -1,1533 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// HJSON with partition metadata. -// -${gen_comment} -<% -from topgen.lib import Name - -num_part = len(otp_mmap.config["partitions"]) -num_part_unbuf = 0 -for part in otp_mmap.config["partitions"]: - if part["variant"] == "Unbuffered": - num_part_unbuf += 1 -num_part_buf = num_part - num_part_unbuf -otp_size_as_bytes = 2 ** otp_mmap.config["otp"]["byte_addr_width"] -otp_size_as_uint32 = otp_size_as_bytes // 4 -%>\ -{ - name: "otp_ctrl", - human_name: "One-Time Programmable Memory Controller", - one_line_desc: "Interfaces integrated one-time programmable memory, supports scrambling, integrity and secure wipe", - one_paragraph_desc: ''' - One-Time Programmable (OTP) Memory Controller provides an open source abstraction interface for software and other hardware components such as Life Cycle Controller and Key Manager to interact with an integrated, closed source, proprietary OTP memory. - On top of defensive features provided by the proprietary OTP memory to deter side-channel analysis (SCA), fault injection (FI) attacks, and visual and electrical probing, the open source OTP controller features high-level logical security protection such as integrity checks and scrambling, as well as software isolation for when OTP contents are readable and programmable. - It features multiple individually-lockable logical partitions, periodic / persistent checking of OTP values, and a separate partition and interface for Life Cycle Controller. - ''' - // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. - cip_id: "16", - design_spec: "../doc", - dv_doc: "../doc/dv", - hw_checklist: "../doc/checklist", - sw_checklist: "/sw/device/lib/dif/dif_otp_ctrl", - revisions: [ - { - version: "0.1.0", - life_stage: "L1", - design_stage: "D2", - verification_stage: "V2", - dif_stage: "S1", - commit_id: "127b109e2fab9336e830158abe449a3922544ded", - notes: "", - } - { - version: "1.0.0", - life_stage: "L1", - design_stage: "D3", - verification_stage: "V2S", - dif_stage: "S2", - notes: "", - } - { - version: "2.0.0", - life_stage: "L1", - design_stage: "D3", - verification_stage: "V2S", - dif_stage: "S2", - notes: "", - } - ] - clocking: [ - {clock: "clk_i", reset: "rst_ni", primary: true}, - {clock: "clk_edn_i", reset: "rst_edn_ni"} - ] - scan: "true", // Enable `scanmode_i` port - scan_reset: "true", // Enable `scan_rst_ni` port - scan_en: "true", // Enable `scan_en_i` port - bus_interfaces: [ - { protocol: "tlul", direction: "device", name: "core" } - { protocol: "tlul", direction: "device", name: "prim", hier_path: "u_otp.gen_generic.u_impl_generic.u_reg_top" } - ], - - available_output_list: [ - { name: "test", - width: 8, - desc: "Test-related GPIOs. Only active in DFT-enabled life cycle states." - } - ], - - /////////////////////////// - // Interrupts and Alerts // - /////////////////////////// - - interrupt_list: [ - { name: "otp_operation_done", - desc: "A direct access command or digest calculation operation has completed." - } - { name: "otp_error", - desc: "An error has occurred in the OTP controller. Check the !!ERR_CODE register to get more information." - } - ], - - alert_list: [ - { name: "fatal_macro_error", - desc: "This alert triggers if hardware detects an uncorrectable error during an OTP transaction, for example an uncorrectable ECC error in the OTP array.", - } - { name: "fatal_check_error", - desc: "This alert triggers if any of the background checks fails. This includes the digest checks and concurrent ECC checks in the buffer registers.", - } - { name: "fatal_bus_integ_error", - desc: "This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected." - } - { name: "fatal_prim_otp_alert", - desc: "Fatal alert triggered inside the OTP primitive, including fatal TL-UL bus integrity faults of the test interface." - } - { name: "recov_prim_otp_alert", - desc: "Recoverable alert triggered inside the OTP primitive." - } - ], - - //////////////// - // Parameters // - //////////////// - param_list: [ - // Init file - { name: "MemInitFile", - desc: "VMEM file to initialize the OTP macro.", - type: "", - default: '""', - expose: "true", - local: "false" - } - // Random netlist constants - { name: "RndCnstLfsrSeed", - desc: "Compile-time random bits for initial LFSR seed", - type: "otp_ctrl_pkg::lfsr_seed_t" - randcount: "40", - randtype: "data", // randomize randcount databits - } - { name: "RndCnstLfsrPerm", - desc: "Compile-time random permutation for LFSR output", - type: "otp_ctrl_pkg::lfsr_perm_t" - randcount: "40", - randtype: "perm", // random permutation for randcount elements - } - { name: "RndCnstScrmblKeyInit", - desc: "Compile-time random permutation for scrambling key/nonce register reset value", - type: "otp_ctrl_pkg::scrmbl_key_init_t" - randcount: "256", - randtype: "data", // random permutation for randcount elements - } - // Normal parameters - { name: "NumSramKeyReqSlots", - desc: "Number of key slots", - type: "int", - default: "4", - local: "true" - }, - { name: "OtpByteAddrWidth", - desc: "Width of the OTP byte address.", - type: "int", - default: "${otp_mmap.config["otp"]["byte_addr_width"]}", - local: "true" - }, - { name: "NumErrorEntries", - desc: "Number of error register entries.", - type: "int", - default: "${num_part + 2}", // partitions + DAI/LCI - local: "true" - }, - { name: "NumDaiWords", - desc: "Number of 32bit words in the DAI.", - type: "int", - default: "2", - local: "true" - }, - { name: "NumDigestWords", - desc: "Size of the digest fields in 32bit words.", - type: "int", - default: "2", - local: "true" - }, - { name: "NumSwCfgWindowWords", - desc: "Size of the TL-UL window in 32bit words. Note that the effective partition size is smaller than that.", - type: "int", - default: "${otp_size_as_uint32}", - local: "true" - } - - // Memory map Info - { name: "NumPart", - desc: "Number of partitions", - type: "int", - default: "${num_part}", - local: "true" - }, - { name: "NumPartUnbuf", - desc: "Number of unbuffered partitions", - type: "int", - default: "${num_part_unbuf}", - local: "true" - }, - { name: "NumPartBuf", - desc: "Number of buffered partitions (including 1 lifecycle partition)", - type: "int", - default: "${num_part_buf}", - local: "true" - }, -% for part in otp_mmap.config["partitions"]: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - { name: "${part_name_camel}Offset", - desc: "Offset of the ${part["name"]} partition", - type: "int", - default: "${part["offset"]}", - local: "true" - }, - { name: "${part_name_camel}Size", - desc: "Size of the ${part["name"]} partition", - type: "int", - default: "${part["size"]}", - local: "true" - }, - % for item in part["items"]: -<% - item_name = Name.from_snake_case(item["name"]) - item_name_camel = item_name.as_camel_case() -%>\ - { name: "${item_name_camel}Offset", - desc: "Offset of ${item["name"]}", - type: "int", - default: "${item["offset"]}", - local: "true" - }, - { name: "${item_name_camel}Size", - desc: "Size of ${item["name"]}", - type: "int", - default: "${item["size"]}", - local: "true" - }, - % endfor -% endfor - ] - - ///////////////////////////// - // Intermodule Connections // - ///////////////////////////// - - inter_signal_list: [ - // OTP dedicated power connection from AST - { struct: "" - type: "io" - name: "otp_ext_voltage_h" - act: "none" - default: "'0" - package: "", - } - // Power sequencing signals to AST - { struct: "otp_ast_req" - type: "uni" - name: "otp_ast_pwr_seq" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Power sequencing signals to AST (VDD domain)." - } - // Power sequencing signals from AST - { struct: "otp_ast_rsp" - type: "uni" - name: "otp_ast_pwr_seq_h" - act: "rcv" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Power sequencing signals coming from AST (VCC domain)." - } - // EDN interface - { struct: "edn" - type: "req_rsp" - name: "edn" - act: "req" - package: "edn_pkg" - desc: "Entropy request to the entropy distribution network for LFSR reseeding and ephemeral key derivation." - } - // Power manager init command - { struct: "pwr_otp" - type: "req_rsp" - name: "pwr_otp" - act: "rsp" - default: "'0" - package: "pwrmgr_pkg" - desc: "Initialization request/acknowledge from/to power manager." - } - // Macro-specific test signals to/from LC TAP - { struct: "lc_otp_vendor_test" - type: "req_rsp" - name: "lc_otp_vendor_test" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Vendor test control signals from/to the life cycle TAP." - } - // LC transition command - { struct: "lc_otp_program" - type: "req_rsp" - name: "lc_otp_program" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Life cycle state transition interface." - } - // Broadcast to LC - { struct: "otp_lc_data" - type: "uni" - name: "otp_lc_data" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: ''' - Life cycle state output holding the current life cycle state, - the value of the transition counter and the tokens needed for life cycle transitions. - ''' - } - // Broadcast from LC - { struct: "lc_tx" - type: "uni" - name: "lc_escalate_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Life cycle escalation enable coming from life cycle controller. - This signal moves all FSMs within OTP into the error state. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_creator_seed_sw_rw_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Provision enable qualifier coming from life cycle controller. - This signal enables SW read / write access to the RMA_TOKEN and CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_owner_seed_sw_rw_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Provision enable qualifier coming from life cycle controller. - This signal enables SW read / write access to the OWNER_SEED. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_seed_hw_rd_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Seed read enable coming from life cycle controller. - This signal enables HW read access to the CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_dft_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Test enable qualifier coming from life cycle controller. - This signals enables the TL-UL access port to the proprietary OTP IP. - ''' - } - { struct: "lc_tx" - type: "uni" - name: "lc_check_byp_en" - act: "rcv" - default: "lc_ctrl_pkg::Off" - package: "lc_ctrl_pkg" - desc: ''' - Life cycle partition check bypass signal. - This signal causes the life cycle partition to bypass consistency checks during life cycle state transitions in order to prevent spurious consistency check failures. - ''' - } - // Broadcast to Key Manager - { struct: "otp_keymgr_key" - type: "uni" - name: "otp_keymgr_key" - act: "req" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key output to the key manager holding CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1." - } - // Broadcast to Flash Controller - { struct: "flash_otp_key" - type: "req_rsp" - name: "flash_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key derivation interface for FLASH scrambling." - } - // Key request from SRAM scramblers - { struct: "sram_otp_key" - // TODO: would be nice if this could accept parameters. - // Split this out into an issue. - width: "4" - type: "req_rsp" - name: "sram_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Array with key derivation interfaces for SRAM scrambling devices." - } - // Key request from OTBN RAM Scrambler - { struct: "otbn_otp_key" - type: "req_rsp" - name: "otbn_otp_key" - act: "rsp" - default: "'0" - package: "otp_ctrl_pkg" - desc: "Key derivation interface for OTBN scrambling devices." - } - // Hardware config partition - { struct: "otp_broadcast" - type: "uni" - name: "otp_broadcast" - act: "req" - default: "'0" - package: "otp_ctrl_part_pkg" - desc: "Output of the HW partitions with breakout data types." - } - // AST observability control - { struct: "ast_obs_ctrl", - type: "uni", - name: "obs_ctrl", - act: "rcv", - package: "ast_pkg" - desc: "AST observability control signals." - } - // prim otp observe bus - { struct: "logic", - type: "uni", - name: "otp_obs", - act: "req", - width: "8", - package: "" - desc: "AST observability bus." - } - ] // inter_signal_list - - ///////////////////// - // Countermeasures // - ///////////////////// - - countermeasures: [ - { name: "BUS.INTEGRITY", - desc: "End-to-end bus integrity scheme." - } - { name: "SECRET.MEM.SCRAMBLE", - desc: "Secret partitions are scrambled with a full-round PRESENT cipher." - } - { name: "PART.MEM.DIGEST", - desc: "Integrity of buffered partitions is ensured via a 64bit digest." - } - { name: "DAI.FSM.SPARSE", - desc: "The direct access interface FSM is sparsely encoded." - } - { name: "KDI.FSM.SPARSE", - desc: "The key derivation interface FSM is sparsely encoded." - } - { name: "LCI.FSM.SPARSE", - desc: "The life cycle interface FSM is sparsely encoded." - } - { name: "PART.FSM.SPARSE", - desc: "The partition FSMs are sparsely encoded." - } - { name: "SCRMBL.FSM.SPARSE", - desc: "The scramble datapath FSM is sparsely encoded." - } - { name: "TIMER.FSM.SPARSE", - desc: "The background check timer FSM is sparsely encoded." - } - { name: "DAI.CTR.REDUN", - desc: "The direct access interface address counter employs a cross-counter implementation." - } - { name: "KDI_SEED.CTR.REDUN", - desc: "The key derivation interface counter employs a cross-counter implementation." - } - { name: "KDI_ENTROPY.CTR.REDUN", - desc: "The key derivation entropy counter employs a cross-counter implementation." - } - { name: "LCI.CTR.REDUN", - desc: "The life cycle interface address counter employs a cross-counter implementation." - } - { name: "PART.CTR.REDUN", - desc: "The address counter of buffered partitions employs a cross-counter implementation." - } - { name: "SCRMBL.CTR.REDUN", - desc: "The srambling datapath counter employs a cross-counter implementation." - } - { name: "TIMER_INTEG.CTR.REDUN", - desc: "The background integrity check timer employs a duplicated counter implementation." - } - { name: "TIMER_CNSTY.CTR.REDUN", - desc: "The background consistency check timer employs a duplicated counter implementation." - } - { name: "TIMER.LFSR.REDUN", - desc: "The background check LFSR is duplicated." - } - { name: "DAI.FSM.LOCAL_ESC", - desc: "The direct access interface FSM is moved into an invalid state upon local escalation." - } - { name: "LCI.FSM.LOCAL_ESC", - desc: "The life cycle interface FSM is moved into an invalid state upon local escalation." - } - { name: "KDI.FSM.LOCAL_ESC", - desc: "The key derivation interface FSM is moved into an invalid state upon local escalation." - } - { name: "PART.FSM.LOCAL_ESC", - desc: "The partition FSMs are moved into an invalid state upon local escalation." - } - { name: "SCRMBL.FSM.LOCAL_ESC", - desc: "The scramble datapath FSM is moved into an invalid state upon local escalation." - } - { name: "TIMER.FSM.LOCAL_ESC", - desc: "The background check timer FSM is moved into an invalid state upon local escalation." - } - { name: "DAI.FSM.GLOBAL_ESC", - desc: "The direct access interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "LCI.FSM.GLOBAL_ESC", - desc: "The life cycle interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "KDI.FSM.GLOBAL_ESC", - desc: "The key derivation interface FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "PART.FSM.GLOBAL_ESC", - desc: "The partition FSMs are moved into an invalid state upon global escalation via life cycle." - } - { name: "SCRMBL.FSM.GLOBAL_ESC", - desc: "The scramble datapath FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "TIMER.FSM.GLOBAL_ESC", - desc: "The background check timer FSM is moved into an invalid state upon global escalation via life cycle." - } - { name: "PART.DATA_REG.INTEGRITY", - desc: "All partition buffer registers are protected with ECC on 64bit blocks." - } - { name: "PART.DATA_REG.BKGN_CHK", - desc: "The digest of buffered partitions is recomputed and checked at pseudorandom intervals in the background." - } - { name: "PART.MEM.REGREN" - desc: "Unbuffered ('software') partitions can be read-locked via a CSR until the next system reset." - } - { name: "PART.MEM.SW_UNREADABLE" - desc: "Secret buffered partitions become unreadable to software once they are locked via the digest." - } - { name: "PART.MEM.SW_UNWRITABLE" - desc: "All partitions become unwritable by software once they are locked via the digest." - } - { name: "LC_PART.MEM.SW_NOACCESS" - desc: "The life cycle partition is not directly readable nor writable via software." - } - { name: "ACCESS.CTRL.MUBI", - desc: "The access control signals going from the partitions to the DAI are MUBI encoded." - } - { name: "TOKEN_VALID.CTRL.MUBI", - desc: "The token valid signals going to the life cycle controller are MUBI encoded." - } - { name: "LC_CTRL.INTERSIG.MUBI", - desc: "The life cycle control signals are multibit encoded." - } - { name: "TEST.BUS.LC_GATED", - desc: "Prevent access to test signals and the OTP backdoor interface in non-test lifecycle states." - } - { name: "TEST_TL_LC_GATE.FSM.SPARSE", - desc: "The control FSM inside the TL-UL gating primitive is sparsely encoded." - } - { name: "DIRECT_ACCESS.CONFIG.REGWEN", - desc: "The direct access CSRs are REGWEN protected." - } - { name: "CHECK_TRIGGER.CONFIG.REGWEN", - desc: "The check trigger CSR is REGWEN protected." - } - { name: "CHECK.CONFIG.REGWEN", - desc: "The check CSR is REGWEN protected." - } - { name: "MACRO.MEM.INTEGRITY", - desc: ''' - The OTP macro employs a vendor-specific integrity scheme at the granularity of the native 16bit OTP words. - The scheme is able to at least detect single bit errors. - ''' - } - { name: "MACRO.MEM.CM", - desc: "The OTP macro may contain additional vendor-specific countermeasures." - } - ] - - features: [ - { - name: "OTP_CTRL.PARTITION.VENDOR_TEST" - desc: '''Vendor test partition is used for OTP programming smoke check during manufacturing flow. - In this partition, ECC uncorrectable errors will not lead to fatal errors and alerts. - Instead the error will be reported as correctable ECC error. - ''' - } - { - name: "OTP_CTRL.PARTITION.CREATOR_SW_CFG" - desc: '''During calibration stage, various parameters (clock, voltage, and timing sources) are calibrated and recorded to CREATOR_SW_CFG partition. - ''' - } - { - name: "OTP_CTRL.PARTITION.OWNER_SW_CFG" - desc: "Define attriutes for rom code execution" - } - { - name: "OTP_CTRL.INIT" - desc: '''When power is up, OTP controller reads devices status. - After all reads complete, the controller performs integrity check on the HW_CFG* and SECRET partitions. - Once all integrity checks are complete, the controller marks outputs as valid. - ''' - } - { - name: "OTP_CTRL.ENTROPY_READ" - desc: '''Firmware can read entropy from ENTROPY_SRC block by configuring following field of HW_CFG* partition. - - EN_CSRNG_SW_APP_READ - ''' - } - { - name: "OTP_CTRL.KEY_DERIVATION" - desc: "OTP controller participate key derivation process by providing scramble key seed to SRAM_CTRL and FLASH_CTRL." - } - { - name: "OTP_CTRL.PROGRAM" - desc: '''All other partitions except life cycle partition are programmed through DAI interface. - And once non-zero digest is programmed to these partition, no further write access is allowed. - Life cycle partition is programmed by LC_CTRL. - ''' - } - { - name: "OTP_CTRL.PARTITION.SECRET0" - desc: "Test unlock tokens, Test exit token" - } - { - name: "OTP_CTRL.PARTITION.SECRET1" - desc: "SRAM and FLASH scrambling key" - } - { - name: "OTP_CTRL.PARTITION.SECRET2" - desc: "RMA unlock token and creator root key" - } - { - name: "OTP_CTRL.PARTITION.LIFE_CYCLE" - desc: '''LC state, LC transition count. - This feature is owned by the LC_CTRL and cannot be tested well through the OTP_CTRL CSR interface. - ''' - } - { - name: "OTP_CTRL.PARTITIONS_FEATURE.READ_LOCK" - desc: '''Following partitions can be read lockable by CSR. - - VENDOR_TEST - - CREATOR_SW_CFG - - OWNER_SW_CFG - Following partitions can be read lockable by writing digest. - - SECRET0 - - SECRET1 - - RECRET2 - All read attempt to these partitions after read is locked will trigger AccessError (recoverable). - ''' - } - { - name: "OTP_CTRL.PARTITIONS_FEATURE.WRITE_LOCK" - desc: "All partitions except LIFE_CYCLE can be write lockable by writing digest." - } - { - name: "OTP_CTRL.ERROR_HANDLING.RECOVERABLE" - desc: "Recoverable error is created when unauthorized access atempt are detected via dai interface." - } - { - name: "OTP_CTRL.ERROR_HANDLING.FATAL" - desc: "Unrecoverable errors are created for uncorrectable ecc error, otp macro malfunction and unauthorized access via lc_ctrl." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.CHECK_TIMEOUT" - desc: "Timeout value for the integrity and consistency checks." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.INTEGRITY_CHECK_PERIOD" - desc: "The interval which the digest of the partition is recomputed to check integrity of locked partition." - } - { - name: "OTP_CTRL.BACKGROUND_CHECK.CONSISTENCY_CHECK_PERIOD" - desc: "Re-read period of the buffer registers to ensure data is matched with the associated OTP partition." - } - ] - - /////////////// - // Registers // - /////////////// - - regwidth: "32", - registers: { - core: [ - //////////////////////// - // Ctrl / Status CSRs // - //////////////////////// - - { name: "STATUS", - desc: "OTP status register.", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - resval: 0, - tags: [ // OTP internal HW can modify status register - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - % for k, part in enumerate(otp_mmap.config["partitions"]): - { bits: "${k}" - name: "${part["name"]}_ERROR" - desc: ''' - Set to 1 if an error occurred in this partition. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - % endfor - { bits: "${num_part}" - name: "DAI_ERROR" - desc: ''' - Set to 1 if an error occurred in the DAI. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "${num_part+1}" - name: "LCI_ERROR" - desc: ''' - Set to 1 if an error occurred in the LCI. - If set to 1, SW should check the !!ERR_CODE register at the corresponding index. - ''' - } - { bits: "${num_part+2}" - name: "TIMEOUT_ERROR" - desc: ''' - Set to 1 if an integrity or consistency check times out. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "${num_part+3}" - name: "LFSR_FSM_ERROR" - desc: ''' - Set to 1 if the LFSR timer FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "${num_part+4}" - name: "SCRAMBLING_FSM_ERROR" - desc: ''' - Set to 1 if the scrambling datapath FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "${num_part+5}" - name: "KEY_DERIV_FSM_ERROR" - desc: ''' - Set to 1 if the key derivation FSM has reached an invalid state. - This raises an fatal_check_error alert and is an unrecoverable error condition. - ''' - } - { bits: "${num_part+6}" - name: "BUS_INTEG_ERROR" - desc: ''' - This bit is set to 1 if a fatal bus integrity fault is detected. - This error triggers a fatal_bus_integ_error alert. - ''' - } - { bits: "${num_part+7}" - name: "DAI_IDLE" - desc: "Set to 1 if the DAI is idle and ready to accept commands." - } - { bits: "${num_part+8}" - name: "CHECK_PENDING" - desc: "Set to 1 if an integrity or consistency check triggered by the LFSR timer or via !!CHECK_TRIGGER is pending." - } - ] - } - { multireg: { - name: "ERR_CODE", - desc: ''' - This register holds information about error conditions that occurred in the agents - interacting with the OTP macro via the internal bus. The error codes should be checked - if the partitions, DAI or LCI flag an error in the !!STATUS register, or when an - !!INTR_STATE.otp_error has been triggered. Note that all errors trigger an otp_error - interrupt, and in addition some errors may trigger either an fatal_macro_error or an - fatal_check_error alert. - ''', - count: "NumErrorEntries", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "AGENT", - compact: "false", - resval: 0, - tags: [ // OTP internal HW can modify the error code registers - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { - bits: "2:0" - enum: [ - { value: "0", - name: "NO_ERROR", - desc: ''' - No error condition has occurred. - ''' - }, - { value: "1", - name: "MACRO_ERROR", - desc: ''' - Returned if the OTP macro command was invalid or did not complete successfully - due to a macro malfunction. - This error should never occur during normal operation and is not recoverable. - This error triggers an fatal_macro_error alert. - ''' - }, - { value: "2", - name: "MACRO_ECC_CORR_ERROR", - desc: ''' - A correctable ECC error has occured during an OTP read operation. - The corresponding controller automatically recovers from this error when - issuing a new command. - ''' - }, - { value: "3", - name: "MACRO_ECC_UNCORR_ERROR", - desc: ''' - An uncorrectable ECC error has occurred during an OTP read operation. - This error should never occur during normal operation and is not recoverable. - If this error is present this may be a sign that the device is malfunctioning. - This error triggers an fatal_macro_error alert. - ''' - }, - { value: "4", - name: "MACRO_WRITE_BLANK_ERROR", - desc: ''' - This error is returned if a programming operation attempted to clear a bit that has previously been programmed to 1. - The corresponding controller automatically recovers from this error when issuing a new command. - - Note however that the affected OTP word may be left in an inconsistent state if this error occurs. - This can cause several issues when the word is accessed again (either as part of a regular read operation, as part of the readout at boot, or as part of a background check). - - It is important that SW ensures that each word is only written once, since this can render the device useless. - ''' - }, - { value: "5", - name: "ACCESS_ERROR", - desc: ''' - This error indicates that a locked memory region has been accessed. - The corresponding controller automatically recovers from this error when issuing a new command. - ''' - }, - { value: "6", - name: "CHECK_FAIL_ERROR", - desc: ''' - An ECC, integrity or consistency mismatch has been detected in the buffer registers. - This error should never occur during normal operation and is not recoverable. - This error triggers an fatal_check_error alert. - ''' - }, - { value: "7", - name: "FSM_STATE_ERROR", - desc: ''' - The FSM of the corresponding controller has reached an invalid state, or the FSM has - been moved into a terminal error state due to an escalation action via lc_escalate_en_i. - This error should never occur during normal operation and is not recoverable. - If this error is present, this is a sign that the device has fallen victim to - an invasive attack. This error triggers an fatal_check_error alert. - ''' - }, - ] - } - ] - } - } - { name: "DIRECT_ACCESS_REGWEN", - desc: ''' - Register write enable for all direct access interface registers. - ''', - swaccess: "rw0c", - hwaccess: "hrw", - hwext: "true", - hwqe: "true", - tags: [ // OTP internal HW will set this enable register to 0 when OTP is not under IDLE - // state, so could not auto-predict its value - "excl:CsrNonInitTests:CsrExclCheck"], - fields: [ - { - bits: "0", - desc: ''' - This bit controls whether the DAI registers can be written. - Write 0 to it in order to clear the bit. - - Note that the hardware also modulates this bit and sets it to 0 temporarily - during an OTP operation such that the corresponding address and data registers - cannot be modified while an operation is pending. The !!DAI_IDLE status bit - will also be set to 0 in such a case. - ''' - resval: 1, - }, - ] - }, - { name: "DIRECT_ACCESS_CMD", - desc: "Command register for direct accesses.", - swaccess: "r0w1c", - hwaccess: "hro", - hwqe: "true", - hwext: "true", - resval: 0, - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // Write to DIRECT_ACCESS_CMD randomly might cause OTP_ERRORs and illegal sequences - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - name: "RD", - desc: ''' - Initiates a readout sequence that reads the location specified - by !!DIRECT_ACCESS_ADDRESS. The command places the data read into - !!DIRECT_ACCESS_RDATA_0 and !!DIRECT_ACCESS_RDATA_1 (for 64bit partitions). - ''' - } - { bits: "1", - name: "WR", - desc: ''' - Initiates a programming sequence that writes the data in !!DIRECT_ACCESS_WDATA_0 - and !!DIRECT_ACCESS_WDATA_1 (for 64bit partitions) to the location specified by - !!DIRECT_ACCESS_ADDRESS. - ''' - } - { bits: "2", - name: "DIGEST", - desc: ''' - Initiates the digest calculation and locking sequence for the partition specified by - !!DIRECT_ACCESS_ADDRESS. - ''' - } - ] - } - { name: "DIRECT_ACCESS_ADDRESS", - desc: "Address register for direct accesses.", - swaccess: "rw", - hwaccess: "hro", - hwqe: "false", - resval: 0, - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The enable register "DIRECT_ACCESS_REGWEN" is HW controlled, - // so not able to predict this register value automatically - "excl:CsrNonInitTests:CsrExclCheck"], - fields: [ - { bits: "OtpByteAddrWidth-1:0", - desc: ''' - This is the address for the OTP word to be read or written through - the direct access interface. Note that the address is aligned to the access size - internally, hence bits 1:0 are ignored for 32bit accesses, and bits 2:0 are ignored - for 64bit accesses. - - For the digest calculation command, set this register to the partition base offset. - ''' - } - ] - } - { multireg: { - name: "DIRECT_ACCESS_WDATA", - desc: '''Write data for direct accesses. - Hardware automatically determines the access granule (32bit or 64bit) based on which - partition is being written to. - ''', - count: "NumDaiWords", // 2 x 32bit = 64bit - swaccess: "rw", - hwaccess: "hro", - hwqe: "false", - regwen: "DIRECT_ACCESS_REGWEN", - cname: "WORD", - resval: 0, - tags: [ // The value of this register is written from "DIRECT_ACCESS_RDATA", - // so could not predict this register value automatically - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - { multireg: { - name: "DIRECT_ACCESS_RDATA", - desc: '''Read data for direct accesses. - Hardware automatically determines the access granule (32bit or 64bit) based on which - partition is read from. - ''', - count: "NumDaiWords", // 2 x 32bit = 64bit - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - fields: [ - { bits: "31:0" - } - ] - } - }, - - ////////////////////////////////////// - // Integrity and Consistency Checks // - ////////////////////////////////////// - { name: "CHECK_TRIGGER_REGWEN", - desc: ''' - Register write enable for !!CHECK_TRIGGER. - ''', - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, the !!CHECK_TRIGGER register cannot be written anymore. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "CHECK_TRIGGER", - desc: "Command register for direct accesses.", - swaccess: "r0w1c", - hwaccess: "hro", - hwqe: "true", - hwext: "true", - resval: 0, - regwen: "CHECK_TRIGGER_REGWEN", - fields: [ - { bits: "0", - name: "INTEGRITY", - desc: ''' - Writing 1 to this bit triggers an integrity check. SW should monitor !!STATUS.CHECK_PENDING - and wait until the check has been completed. If there are any errors, those will be flagged - in the !!STATUS and !!ERR_CODE registers, and via the interrupts and alerts. - ''' - } - { bits: "1", - name: "CONSISTENCY", - desc: ''' - Writing 1 to this bit triggers a consistency check. SW should monitor !!STATUS.CHECK_PENDING - and wait until the check has been completed. If there are any errors, those will be flagged - in the !!STATUS and !!ERR_CODE registers, and via interrupts and alerts. - ''' - } - ] - }, - { name: "CHECK_REGWEN", - desc: ''' - Register write enable for !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD. - ''', - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD registers cannot be written anymore. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - { name: "CHECK_TIMEOUT", - desc: ''' - Timeout value for the integrity and consistency checks. - ''', - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - tags: [ // Do not write to this automatically, as it may trigger fatal alert, and cause - // escalation. - "excl:CsrAllTests:CsrExclWrite"], - fields: [ - { bits: "31:0", - desc: ''' - Timeout value in cycles for the for the integrity and consistency checks. If an integrity or consistency - check does not complete within the timeout window, an error will be flagged in the !!STATUS register, - an otp_error interrupt will be raised, and an fatal_check_error alert will be sent out. The timeout should - be set to a large value to stay on the safe side. The maximum check time can be upper bounded by the - number of cycles it takes to readout, scramble and digest the entire OTP array. Since this amounts to - roughly 25k cycles, it is recommended to set this value to at least 100'000 cycles in order to stay on the - safe side. A value of zero disables the timeout mechanism (default). - ''' - resval: 0, - }, - ] - }, - { name: "INTEGRITY_CHECK_PERIOD", - desc: ''' - This value specifies the maximum period that can be generated pseudo-randomly. - Only applies to the HW_CFG* and SECRET* partitions once they are locked. - ''' - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - fields: [ - { bits: "31:0", - desc: ''' - The pseudo-random period is generated using a 40bit LFSR internally, and this register defines - the bit mask to be applied to the LFSR output in order to limit its range. The value of this - register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. - A recommended value is 0x3_FFFF, corresponding to a maximum period of ~2.8s at 24MHz. - A value of zero disables the timer (default). Note that a one-off check can always be triggered via - !!CHECK_TRIGGER.INTEGRITY. - ''' - resval: "0" - } - ] - } - { name: "CONSISTENCY_CHECK_PERIOD", - desc: ''' - This value specifies the maximum period that can be generated pseudo-randomly. - This applies to the LIFE_CYCLE partition and the HW_CFG* and SECRET* partitions once they are locked. - ''' - swaccess: "rw", - hwaccess: "hro", - regwen: "CHECK_REGWEN", - fields: [ - { bits: "31:0", - desc: ''' - The pseudo-random period is generated using a 40bit LFSR internally, and this register defines - the bit mask to be applied to the LFSR output in order to limit its range. The value of this - register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. - A recommended value is 0x3FF_FFFF, corresponding to a maximum period of ~716s at 24MHz. - A value of zero disables the timer (default). Note that a one-off check can always be triggered via - !!CHECK_TRIGGER.CONSISTENCY. - ''' - resval: "0" - } - ] - } - - //////////////////////////////////// - // Dynamic Locks of SW Parititons // - //////////////////////////////////// - % for part in otp_mmap.config["partitions"]: - % if part["read_lock"].lower() == "csr": - { name: "${part["name"]}_READ_LOCK", - desc: ''' - Runtime read lock for the ${part["name"]} partition. - ''', - swaccess: "rw0c", - hwaccess: "hro", - regwen: "DIRECT_ACCESS_REGWEN", - tags: [ // The value of this register can affect the read access of the this - // partition's memory window. Excluding this register from writing can ensure - // memories have read and write access. - "excl:CsrNonInitTests:CsrExclWrite"], - fields: [ - { bits: "0", - desc: ''' - When cleared to 0, read access to the ${part["name"]} partition is locked. - Write 0 to clear this bit. - ''' - resval: 1, - }, - ] - }, - % endif - % endfor - - /////////////////////// - // Integrity Digests // - /////////////////////// - % for part in otp_mmap.config["partitions"]: - % if part["sw_digest"]: - { multireg: { - name: "${part["name"]}_DIGEST", - desc: ''' - Integrity digest for the ${part["name"]} partition. - The integrity digest is 0 by default. Software must write this - digest value via the direct access interface in order to lock the partition. - After a reset, write access to the ${part["name"]} partition is locked and - the digest becomes visible in this CSR. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - % elif part["hw_digest"]: - { multireg: { - name: "${part["name"]}_DIGEST", - desc: ''' - Integrity digest for the ${part["name"]} partition. - The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. - After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. - ''', - count: "NumDigestWords", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - cname: "WORD", - resval: 0, - tags: [ // OTP internal HW will update status so can not auto-predict its value. - "excl:CsrAllTests:CsrExclCheck"], - fields: [ - { bits: "31:0" - } - ] - } - }, - % endif - % endfor - - //////////////////////////////// - // Software Config Partitions // - //////////////////////////////// - { skipto: "${hex(otp_size_as_bytes)}" } - - { window: { - name: "SW_CFG_WINDOW" - items: "NumSwCfgWindowWords" - swaccess: "ro", - desc: ''' - Any read to this window directly maps to the corresponding offset in the creator and owner software - config partitions, and triggers an OTP readout of the bytes requested. Note that the transaction - will block until OTP readout has completed. - ''' - } - } - ], - - // OTP wrapper-specific registers - prim: [ - { name: "CSR0", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "0", - name: "field0", - desc: "", - resval: "0x0", - } - { bits: "1", - name: "field1", - desc: "", - resval: "0x0", - } - { bits: "2", - name: "field2", - desc: "", - resval: "0x0", - } - { bits: "13:4", - name: "field3", - desc: "" - resval: "0x0", - } - { bits: "26:16", - name: "field4", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR1", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "6:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "7:7", - name: "field1", - desc: "", - resval: "0x0", - } - { bits: "14:8", - name: "field2", - desc: "" - resval: "0x0", - } - { bits: "15:15", - name: "field3", - desc: "", - resval: "0x0", - } - { bits: "31:16", - name: "field4", - desc: "", - resval: "0x0", - } - ] - }, - { name: "CSR2", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "0", - name: "field0", - desc: "", - resval: "0x0", - } - ] - }, - { name: "CSR3", - desc: "" - swaccess: "rw", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "2:0", - name: "field0", - desc: "" - swaccess: "rw1c", - resval: "0x0", - } - { bits: "13:4", - name: "field1", - desc: "", - swaccess: "rw1c", - resval: "0x0", - } - { bits: "16", - name: "field2", - desc: "", - swaccess: "rw1c", - resval: "0x0", - } - { bits: "17", - name: "field3", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "18", - name: "field4", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "19", - name: "field5", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "20", - name: "field6", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "21", - name: "field7", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "22", - name: "field8", - desc: "", - swaccess: "ro", - resval: "0x0", - } - ] - }, - { name: "CSR4", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "9:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "12", - name: "field1", - desc: "" - resval: "0x0", - } - { bits: "13", - name: "field2", - desc: "" - resval: "0x0", - } - { bits: "14", - name: "field3", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR5", - desc: "" - swaccess: "rw", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "5:0", - name: "field0", - desc: "" - swaccess: "rw", - resval: "0x0", - } - { bits: "7:6", - name: "field1", - desc: "" - swaccess: "rw", - resval: "0x0", - } - { bits: "8", - name: "field2", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "11:9", - name: "field3", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "12", - name: "field4", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "13", - name: "field5", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "31:16", - name: "field6", - desc: "" - swaccess: "rw", - resval: "0x0", - } - ] - }, - { name: "CSR6", - desc: "" - swaccess: "rw", - hwaccess: "hro", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "9:0", - name: "field0", - desc: "" - resval: "0x0", - } - { bits: "11", - name: "field1", - desc: "", - swaccess: "rw", - resval: "0x0", - } - { bits: "12", - name: "field2", - desc: "", - swaccess: "rw", - resval: "0x0", - } - { bits: "31:16", - name: "field3", - desc: "" - resval: "0x0", - } - ] - }, - { name: "CSR7", - desc: "", - swaccess: "ro", - hwaccess: "hrw", - hwext: "false", - hwqe: "false", - fields: [ - { bits: "5:0", - name: "field0", - desc: "" - swaccess: "ro", - resval: "0x0", - } - { bits: "10:8", - name: "field1", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "14", - name: "field2", - desc: "", - swaccess: "ro", - resval: "0x0", - } - { bits: "15", - name: "field3", - desc: "", - swaccess: "ro", - resval: "0x0", - } - ] - }, - ] - } -} diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_base_vseq.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_base_vseq.sv.tpl deleted file mode 100644 index 1728c95812e58..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_base_vseq.sv.tpl +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -unbuf_parts_with_digest = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Unbuffered" and - (part["sw_digest"] or part["hw_digest"])] -parts_with_digest = [part for part in otp_mmap.config["partitions"] if - (part["sw_digest"] or part["hw_digest"])] -read_locked_csr_parts = [part for part in otp_mmap.config["partitions"] if - part["read_lock"] == "CSR"] -write_locked_digest_parts = [part for part in otp_mmap.config["partitions"] if - part["write_lock"] == "Digest"] -secret_parts = [part for part in otp_mmap.config["partitions"] if - part["secret"]] -%>\ -class otp_ctrl_base_vseq extends cip_base_vseq #( - .RAL_T (otp_ctrl_core_reg_block), - .CFG_T (otp_ctrl_env_cfg), - .COV_T (otp_ctrl_env_cov), - .VIRTUAL_SEQUENCER_T (otp_ctrl_virtual_sequencer) - ); - `uvm_object_utils(otp_ctrl_base_vseq) - `uvm_object_new - - // various knobs to enable certain routines - bit do_otp_ctrl_init = 1'b1; - bit do_otp_pwr_init = 1'b1; - - // To only write unused OTP address, sequence will collect all the written addresses to an - // associative array to avoid `write_blank_addr_error`. - bit write_unused_addr = 1; - static bit used_dai_addrs[bit [OTP_ADDR_WIDTH - 1 : 0]]; - - rand bit [NumOtpCtrlIntr-1:0] en_intr; - - rand int apply_reset_during_pwr_init_cycles; - - bit is_valid_dai_op = 1; - - // According to spec, the period between digest calculation and reset should not issue any write. - bit [NumPart-2:0] digest_calculated; - - // For stress_all_with_rand reset sequence to issue reset during OTP operations. - bit do_digest_cal, do_otp_rd, do_otp_wr; - - // LC program request will use a separate variable to automatically set to non-blocking setting - // when LC error bit is set. - bit default_req_blocking = 1; - bit lc_prog_blocking = 1; - bit dai_wr_inprogress = 0; - uint32_t op_done_spinwait_timeout_ns = 20_000_000; - - // Collect current lc_state and lc_cnt. This is used to create next lc_state and lc_cnt without - // error. - lc_ctrl_state_pkg::lc_state_e lc_state; - lc_ctrl_state_pkg::lc_cnt_e lc_cnt; - - otp_ctrl_callback_vseq callback_vseq; - - constraint apply_reset_during_pwr_init_cycles_c { - apply_reset_during_pwr_init_cycles == 0; - } - - virtual task pre_start(); - `uvm_create_on(callback_vseq, p_sequencer); - super.pre_start(); - endtask - - virtual task dut_init(string reset_kind = "HARD"); - // OTP has dut and edn reset. If assign OTP values after `super.dut_init()`, and if dut reset - // deasserts earlier than edn reset, some OTP outputs might remain X or Z when dut clock is - // running. - otp_ctrl_vif_init(); - super.dut_init(reset_kind); - callback_vseq.dut_init_callback(); - - cfg.backdoor_clear_mem = 0; - // reset power init pin and lc pins - if (do_otp_ctrl_init && do_apply_reset) otp_ctrl_init(); - cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); - if (do_otp_pwr_init && do_apply_reset) otp_pwr_init(); - callback_vseq.post_otp_pwr_init(); - endtask - - // Cfg errors are cleared after reset - virtual task apply_reset(string kind = "HARD"); - super.apply_reset(kind); - cfg.otp_ctrl_vif.release_part_access_mubi(); - clear_seq_flags(); - endtask - - virtual function void clear_seq_flags(); - do_digest_cal = 0; - do_otp_rd = 0; - do_otp_wr = 0; - endfunction - - virtual task otp_ctrl_vif_init(); - cfg.otp_ctrl_vif.drive_lc_creator_seed_sw_rw_en(lc_ctrl_pkg::On); - cfg.otp_ctrl_vif.drive_lc_owner_seed_sw_rw_en(lc_ctrl_pkg::On); - cfg.otp_ctrl_vif.drive_lc_seed_hw_rd_en(get_rand_lc_tx_val()); - cfg.otp_ctrl_vif.drive_lc_dft_en(get_rand_lc_tx_val(.t_weight(0))); - cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off); - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - cfg.otp_ctrl_vif.drive_ext_voltage_h_io(1'bz); - - // Unused signals in open sourced OTP memory - `DV_CHECK_RANDOMIZE_FATAL(cfg.dut_cfg) - cfg.otp_ctrl_vif.otp_ast_pwr_seq_h_i = cfg.dut_cfg.otp_ast_pwr_seq_h; - cfg.otp_ctrl_vif.scan_en_i = cfg.dut_cfg.scan_en; - cfg.otp_ctrl_vif.scan_rst_ni = cfg.dut_cfg.scan_rst_n; - cfg.otp_ctrl_vif.scanmode_i = cfg.dut_cfg.scanmode; - cfg.otp_ctrl_vif.otp_vendor_test_ctrl_i = cfg.dut_cfg.otp_vendor_test_ctrl; - endtask - - // drive otp_pwr req pin to initialize OTP, and wait until init is done - virtual task otp_pwr_init(); - cfg.otp_ctrl_vif.drive_pwr_otp_init(1); - if (apply_reset_during_pwr_init_cycles > 0) begin - `DV_SPINWAIT_EXIT( - cfg.clk_rst_vif.wait_clks(apply_reset_during_pwr_init_cycles);, - wait (cfg.otp_ctrl_vif.pwr_otp_done_o == 1);) - if (cfg.otp_ctrl_vif.pwr_otp_done_o == 0) begin - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - apply_reset(); - cfg.otp_ctrl_vif.drive_pwr_otp_init(1); - end - end - wait (cfg.otp_ctrl_vif.pwr_otp_done_o == 1); - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - digest_calculated = 0; - endtask - - // setup basic otp_ctrl features - virtual task otp_ctrl_init(); - // reset memory to avoid readout X - clear_otp_memory(); - lc_state = lc_state_e'(0); - lc_cnt = lc_cnt_e'(0); - endtask - - virtual function void clear_otp_memory(); - cfg.mem_bkdr_util_h.clear_mem(); - cfg.backdoor_clear_mem = 1; - used_dai_addrs.delete(); - endfunction - - // Overide this task for otp_ctrl_common_vseq and otp_ctrl_stress_all_with_rand_reset_vseq - // because some registers won't set to default value until otp_init is done. - virtual task read_and_check_all_csrs_after_reset(); - cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off); - otp_pwr_init(); - super.read_and_check_all_csrs_after_reset(); - endtask - - // this task triggers an OTP write sequence via the DAI interface - virtual task dai_wr(bit [TL_DW-1:0] addr, - bit [TL_DW-1:0] wdata0, - bit [TL_DW-1:0] wdata1 = 0); - bit [TL_DW-1:0] val; - dai_wr_inprogress = 1; - if (write_unused_addr) begin - if (used_dai_addrs.exists(addr[OTP_ADDR_WIDTH - 1 : 0])) begin - `uvm_info(`gfn, $sformatf("addr %0h is already written!", addr), UVM_MEDIUM) - dai_wr_inprogress = 0; - return; - end else begin - used_dai_addrs[addr] = 1; - end - end - addr = randomize_dai_addr(addr); - `uvm_info(`gfn, $sformatf("dai write addr %0h, data %0h", addr, wdata0), UVM_HIGH) - csr_wr(ral.direct_access_address, addr); - csr_wr(ral.direct_access_wdata[0], wdata0); - if (is_secret(addr) || is_sw_digest(addr)) csr_wr(ral.direct_access_wdata[1], wdata1); - - do_otp_wr = 1; - csr_wr(ral.direct_access_cmd, int'(otp_ctrl_pkg::DaiWrite)); - `uvm_info(`gfn, $sformatf("DAI write, address %0h, data0 %0h data1 %0h, is_secret = %0b", - addr, wdata0, wdata1, is_secret(addr)), UVM_DEBUG) - - // Direct_access_regwen and dai_idle are checked only when following conditions are met: - // - the dai operation is valid, otherwise it is hard to predict which cycle the error is - // detected - // - zero delays in TLUL interface, otherwise dai operation might be finished before reading - // these two CSRs - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - wait_dai_op_done(); - rd_and_clear_intrs(); - dai_wr_inprogress = 0; - endtask : dai_wr - - // This task triggers an OTP readout sequence via the DAI interface - virtual task dai_rd(input bit [TL_DW-1:0] addr, - output bit [TL_DW-1:0] rdata0, - output bit [TL_DW-1:0] rdata1); - bit [TL_DW-1:0] val; - addr = randomize_dai_addr(addr); - - csr_wr(ral.direct_access_address, addr); - do_otp_rd = 1; - csr_wr(ral.direct_access_cmd, int'(otp_ctrl_pkg::DaiRead)); - - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - - wait_dai_op_done(); - csr_rd(ral.direct_access_rdata[0], rdata0); - if (is_secret(addr) || is_digest(addr)) csr_rd(ral.direct_access_rdata[1], rdata1); - rd_and_clear_intrs(); - endtask : dai_rd - - virtual task dai_rd_check(bit [TL_DW-1:0] addr, - bit [TL_DW-1:0] exp_data0, - bit [TL_DW-1:0] exp_data1 = 0); - bit [TL_DW-1:0] rdata0, rdata1; - dai_rd(addr, rdata0, rdata1); - if (!cfg.under_reset) begin - `DV_CHECK_EQ(rdata0, exp_data0, $sformatf("dai addr %0h rdata0 readout mismatch", addr)) - if (is_secret(addr) || is_digest(addr)) begin - `DV_CHECK_EQ(rdata1, exp_data1, $sformatf("dai addr %0h rdata1 readout mismatch", addr)) - end - end - endtask: dai_rd_check - - // this task exercises an OTP digest calculation via the DAI interface - virtual task cal_digest(int part_idx); - bit [TL_DW-1:0] val; - csr_wr(ral.direct_access_address, PART_BASE_ADDRS[part_idx]); - csr_wr(ral.direct_access_cmd, otp_ctrl_pkg::DaiDigest); - - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - do_digest_cal = 1; - wait_dai_op_done(); - digest_calculated[part_idx] = 1; - rd_and_clear_intrs(); - endtask - - // this task provisions all HW partitions - // SW partitions could not be provisioned via DAI interface - // LC partitions cannot be locked - virtual task cal_hw_digests(bit [NumPart-1:0] trigger_digest = $urandom()); - foreach (PartInfo[i]) begin - if (PartInfo[i].hw_digest && trigger_digest[i]) begin - cal_digest(i); - end - end - endtask - - // SW digest data are calculated in sw and won't be checked in OTP. - // Here to simplify testbench, write random data to sw digest. - virtual task write_sw_digests(bit [NumPartUnbuf-1:0] wr_digest = $urandom()); - bit [TL_DW*2-1:0] wdata; - % for part in unbuf_parts_with_digest: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (wr_digest[${part_name_camel}Idx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(${part_name_camel}DigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end -% endfor - endtask - - virtual task write_sw_rd_locks(bit [NumPartUnbuf-1:0] do_rd_lock= $urandom()); -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (do_rd_lock[${part_name_camel}Idx]) csr_wr(ral.${part["name"].lower()}_read_lock, 0); -% endfor - endtask - - // The digest CSR values are verified in otp_ctrl_scoreboard - virtual task rd_digests(); - bit [TL_DW-1:0] val; -% for part in parts_with_digest: - csr_rd(.ptr(ral.${part["name"].lower()}_digest[0]), .value(val)); - csr_rd(.ptr(ral.${part["name"].lower()}_digest[1]), .value(val)); -% endfor - endtask - - // If the partition is read/write locked, there is 20% chance we will force the internal mubi - // access signal to the values other than mubi::true or mubi::false. - virtual task force_mubi_part_access(); - // Stress_all_with_rand_reset seq will issue reset and wait until reset is done then kill the - // parallel sequence. This gating logic avoid injecting error during reset active. - if (cfg.otp_ctrl_vif.alert_reqs == 0 && !cfg.under_reset) begin - otp_part_access_lock_t forced_mubi_part_access[NumPart-1]; - - // Digest write locks -% for part in write_locked_digest_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if ((`gmv(ral.${part["name"].lower()}_digest[0]) || - `gmv(ral.${part["name"].lower()}_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[${part_name_camel}Idx].write_lock = 1; - end -% endfor - - // CSR read locks -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if ((`gmv(ral.${part["name"].lower()}_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[${part_name_camel}Idx].read_lock = 1; - end -% endfor - - - // Digest read locks -% for part in secret_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if ((`gmv(ral.${part["name"].lower()}_digest[0]) || - `gmv(ral.${part["name"].lower()}_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[${part_name_camel}Idx].read_lock = 1; - end -% endfor - - foreach (forced_mubi_part_access[i]) begin - `uvm_info(`gfn, $sformatf("partition %0d inject mubi value: read=%0b, write=%0b", i, - forced_mubi_part_access[i].read_lock, forced_mubi_part_access[i].write_lock), UVM_HIGH) - end - - cfg.otp_ctrl_vif.force_part_access_mubi(forced_mubi_part_access); - end - endtask - - // This function backdoor inject error according to ecc_err: - // - for OtpEccUncorrErr it injects a 2 bit eror - // - for OtpEccCorrErr it injects a 1 bit eror - // This function will output original backdoor read data for the given address - // so the error can be cleared. - virtual function bit [TL_DW-1:0] backdoor_inject_ecc_err(bit [TL_DW-1:0] addr, - otp_ecc_err_e ecc_err); - bit [TL_DW-1:0] val; - addr = {addr[TL_DW-1:2], 2'b00}; - val = cfg.mem_bkdr_util_h.read32(addr); - if (ecc_err == OtpNoEccErr || addr >= (LifeCycleOffset + LifeCycleSize)) return val; - - // Backdoor read and write back with error bits - cfg.mem_bkdr_util_h.inject_errors(addr, (ecc_err == OtpEccUncorrErr) ? 2 : 1); - `uvm_info(`gfn, $sformatf("original val %0h, addr %0h, err_type %0s", - val, addr, ecc_err.name), UVM_HIGH) - return val; - endfunction - - virtual task trigger_checks(bit [1:0] val, - bit wait_done = 1, - otp_ecc_err_e ecc_err = OtpNoEccErr); - bit [TL_DW-1:0] backdoor_rd_val, addr; - - // If ECC and check error happens in the same consistency check, the scb cannot predict which - // error will happen first, so it cannot correctly predict the error status and alert - // triggered. - // So the sequence only allows one error at a time. - if (get_field_val(ral.check_trigger.consistency, val) && - `gmv(ral.check_timeout) > 0 && `gmv(ral.check_timeout) <= CHK_TIMEOUT_CYC) begin - ecc_err = OtpNoEccErr; - end - - // Backdoor write ECC errors - if (ecc_err != OtpNoEccErr) begin - int part_idx = $urandom_range(HwCfg0Idx, LifeCycleIdx); - - // Only HW cfgs check digest correctness - if (part_idx != LifeCycleIdx) begin - addr = $urandom_range(0, 1) ? PART_OTP_DIGEST_ADDRS[part_idx] << 2 : - (PART_OTP_DIGEST_ADDRS[part_idx] + 1) << 2; - end else begin - addr = $urandom_range(LifeCycleOffset, LifeCycleOffset + LifeCycleSize - 1); - addr = {addr[TL_DW-1:2], 2'b00}; - end - backdoor_rd_val = backdoor_inject_ecc_err(addr, ecc_err); - cfg.ecc_chk_err[part_idx] = ecc_err; - end - - csr_wr(ral.check_trigger, val); - if (wait_done && val) csr_spinwait(ral.status.check_pending, 0); - - if (ecc_err != OtpNoEccErr) begin - cfg.mem_bkdr_util_h.write32(addr, backdoor_rd_val); - cfg.ecc_chk_err = '{default: OtpNoEccErr}; - end - endtask - - // For a DAI interface operation to finish, either way until status dai_idle is set, or check - // err_code and see if fatal error happened. In any case, break out of this wait if there - // is a need to stop transaction generators, since a spinwait will otherwise just stop - // when it times-out. - virtual task wait_dai_op_done(); - if (cfg.stop_transaction_generators()) return; - fork begin - fork - begin - csr_spinwait(.ptr(ral.status.dai_idle), - .exp_data(1), - .timeout_ns(op_done_spinwait_timeout_ns), - .spinwait_delay_ns($urandom_range(0, 5))); - end - begin - forever begin - bit [TL_DW-1:0] err_val; - cfg.clk_rst_vif.wait_clks(1); - csr_rd(.ptr(ral.err_code[DaiIdx].err_code), .value(err_val), .backdoor(1)); - // Break if error will cause fatal alerts - if (err_val inside {OTP_TERMINAL_ERRS}) break; - end - end - begin - forever begin - cfg.clk_rst_vif.wait_clks(1); - if (cfg.stop_transaction_generators()) break; - end - end - join_any - wait_no_outstanding_access(); - disable fork; - end join - endtask - - virtual task rd_and_clear_intrs(); - bit [TL_DW-1:0] val; - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check == 0) begin - csr_rd(ral.intr_state, val); - // In case lc_program request is issued after intr_state read - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check == 0) csr_wr(ral.intr_state, val); - end - endtask - - // first two or three LSB bits of DAI address can be randomized based on if it is secret - virtual function bit [TL_AW-1:0] randomize_dai_addr(bit [TL_AW-1:0] dai_addr); - if (is_secret(dai_addr)) begin - bit [2:0] rand_addr = $urandom(); - randomize_dai_addr = {dai_addr[TL_DW-1:3], rand_addr}; - end else begin - bit [1:0] rand_addr = $urandom(); - randomize_dai_addr = {dai_addr[TL_DW-1:2], rand_addr}; - end - endfunction - - // The following interface requests are separated to blocking and non-blocking accesses. - // The non-blocking access is mainly used when lc_escalate_en is On, which acts like a reset and - // move all design state machines to ErrorSt. Thus pending request will never get a response - // until reset. - virtual task req_sram_key(int index, bit blocking = default_req_blocking); - // Return if the request is already high, this is mainly due to lc_escalate_en On. - if (cfg.m_sram_pull_agent_cfg[index].vif.req === 1'b1) return; - - if (blocking) begin - req_sram_key_sub(index); - end else begin - fork - begin - req_sram_key_sub(index); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_sram_key_sub(int index); - push_pull_host_seq#(.DeviceDataWidth(SRAM_DATA_SIZE)) sram_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(sram_pull_seq, p_sequencer.sram_pull_sequencer_h[index]); - `DV_CHECK_RANDOMIZE_FATAL(sram_pull_seq) - `uvm_send(sram_pull_seq) - endtask - - virtual task req_all_sram_keys(bit blocking = default_req_blocking); - for (int i = 0; i < NumSramKeyReqSlots; i++) req_sram_key(i, blocking); - endtask - - virtual task req_otbn_key(bit blocking = default_req_blocking); - if (cfg.m_otbn_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_otbn_key_sub(); - end else begin - fork - begin - req_otbn_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_otbn_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(OTBN_DATA_SIZE)) otbn_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(otbn_pull_seq, p_sequencer.otbn_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(otbn_pull_seq) - `uvm_send(otbn_pull_seq) - endtask - - virtual task req_flash_addr_key(bit blocking = default_req_blocking); - if (cfg.m_flash_addr_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_flash_addr_key_sub(); - end else begin - fork - begin - req_flash_addr_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_flash_addr_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_addr_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(flash_addr_pull_seq, p_sequencer.flash_addr_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(flash_addr_pull_seq) - `uvm_send(flash_addr_pull_seq) - endtask - - virtual task req_flash_data_key(bit blocking = default_req_blocking); - if (cfg.m_flash_data_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_flash_data_key_sub(); - end else begin - fork - begin - req_flash_data_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_flash_data_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_data_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(flash_data_pull_seq, p_sequencer.flash_data_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(flash_data_pull_seq) - `uvm_send(flash_data_pull_seq) - endtask - - virtual task req_lc_transition(bit check_intr = 0, - bit blocking = default_req_blocking, - bit wr_blank_err = !write_unused_addr); - if (cfg.m_lc_prog_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_lc_transition_sub(check_intr, wr_blank_err); - end else begin - fork - begin - req_lc_transition_sub(check_intr, wr_blank_err); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_lc_transition_sub(bit check_intr = 0, bit wr_blank_err = !write_unused_addr); - lc_ctrl_state_pkg::lc_cnt_e next_lc_cnt; - lc_ctrl_state_pkg::dec_lc_state_e next_lc_state, lc_state_dec; - bit [TL_DW-1:0] intr_val; - push_pull_host_seq#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1)) - lc_prog_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(lc_prog_pull_seq, p_sequencer.lc_prog_pull_sequencer_h); - - if (!wr_blank_err) begin - // Find valid next state and next cnt using lc_ctrl_dv_utils_pkg. - // If terminal state or max LcCnt reaches, will not program any new data. - if ((lc_state != LcStScrap) && (lc_cnt != LcCnt24)) begin - lc_state_dec = lc_ctrl_dv_utils_pkg::dec_lc_state(lc_state); - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(next_lc_state, - next_lc_state inside {VALID_NEXT_STATES[lc_state_dec]};) - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(next_lc_cnt, next_lc_cnt > lc_cnt;) - lc_state = lc_ctrl_dv_utils_pkg::encode_lc_state(next_lc_state); - lc_cnt = next_lc_cnt; - end - cfg.m_lc_prog_pull_agent_cfg.add_h_user_data({lc_cnt, lc_state}); - end - - `DV_CHECK_RANDOMIZE_FATAL(lc_prog_pull_seq) - `uvm_send(lc_prog_pull_seq) - - if (check_intr) rd_and_clear_intrs(); - endtask - - // This test access OTP_CTRL's test_access memory. The open-sourced code only test if the access - // is valid. Please override this task in proprietary OTP. - virtual task otp_test_access(); - if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin - repeat (10) begin - bit [TL_DW-1:0] data; - bit test_access_en; - bit [TL_AW-1:0] rand_addr = $urandom_range(0, NUM_PRIM_REG - 1) * 4; - bit [TL_AW-1:0] tlul_addr = - cfg.ral_models["otp_ctrl_prim_reg_block"].get_addr_from_offset(rand_addr); - if (cfg.stop_transaction_generators()) break; - rand_drive_dft_en(); - `DV_CHECK_STD_RANDOMIZE_FATAL(data) - test_access_en = cfg.otp_ctrl_vif.lc_dft_en_i == lc_ctrl_pkg::On; - tl_access(.addr(tlul_addr), .write(1), .data(data), .exp_err_rsp(~test_access_en), - .tl_sequencer_h(p_sequencer.tl_sequencer_hs["otp_ctrl_prim_reg_block"])); - tl_access(.addr(tlul_addr), .write(0), .data(data), .exp_err_rsp(~test_access_en), - .tl_sequencer_h(p_sequencer.tl_sequencer_hs["otp_ctrl_prim_reg_block"])); - end - end - endtask - - // Empty task, only drive it under `otp_ctrl_test_access_vseq` - virtual task rand_drive_dft_en(); - endtask -endclass : otp_ctrl_base_vseq diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_cov_bind.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_cov_bind.sv.tpl deleted file mode 100644 index fa61630f92678..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_cov_bind.sv.tpl +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Binds OTP_CTRL functional coverage interaface to the top level OTP_CTRL module. -// -${gen_comment} -<% -from topgen.lib import Name - -# The unsavory ${"\\"} tokens are used to escape the macros newline handling. -%>\ -`define PART_MUBI_COV(__part_name, __index) ${"\\"} - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) ``__part_name``_read_lock_mubi_cov_if ( ${"\\"} - .rst_ni (rst_ni), ${"\\"} - .mubi (part_access[``__index``].read_lock) ${"\\"} - ); ${"\\"} - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) ``__part_name``_write_lock_mubi_cov_if ( ${"\\"} - .rst_ni (rst_ni), ${"\\"} - .mubi (part_access[``__index``].write_lock) ${"\\"} - ); - -`define DAI_MUBI_COV(__part_name, __index) ${"\\"} - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) dai_``__part_name``_read_lock_mubi_cov_if ( ${"\\"} - .rst_ni (rst_ni), ${"\\"} - .mubi (part_access_dai[``__index``].read_lock) ${"\\"} - ); ${"\\"} - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) dai_``__part_name``_write_lock_mubi_cov_if ( ${"\\"} - .rst_ni (rst_ni), ${"\\"} - .mubi (part_access_dai[``__index``].write_lock) ${"\\"} - ); - -module otp_ctrl_cov_bind; - import otp_ctrl_part_pkg::*; - - bind otp_ctrl otp_ctrl_cov_if u_otp_ctrl_cov_if ( - .pwr_otp_o (pwr_otp_o), - .lc_otp_program_i (lc_otp_program_i), - .lc_escalate_en_i (lc_escalate_en_i), - .flash_otp_key_i (flash_otp_key_i), - .sram_otp_key_i (sram_otp_key_i), - .otbn_otp_key_i (otbn_otp_key_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_creator_seed_sw_rw_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_creator_seed_sw_rw_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_seed_hw_rd_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_seed_hw_rd_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_dft_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_dft_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_escalate_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_escalate_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_check_byp_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_check_byp_en_i) - ); - - // Mubi internal coverage for buffered and unbuffered partitions. -% for part in otp_mmap.config["partitions"][:-1]: -<% part_name = Name.from_snake_case(part["name"]) %>\ - `PART_MUBI_COV(${part_name.as_snake_case()}, otp_ctrl_part_pkg::${part_name.as_camel_case()}Idx) -% endfor - - // Mubi internal coverage for DAI interface access -% for part in otp_mmap.config["partitions"][:-1]: -<% part_name = Name.from_snake_case(part["name"]) %>\ - `DAI_MUBI_COV(${part_name.as_snake_case()}, otp_ctrl_part_pkg::${part_name.as_camel_case()}Idx) -% endfor - -`undef PART_MUBI_COV -`undef DAI_MUBI_COV -endmodule diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_dai_lock_vseq.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_dai_lock_vseq.sv.tpl deleted file mode 100644 index 05e81f1ab20f9..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_dai_lock_vseq.sv.tpl +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] in ["Buffered", "Unbuffered"]] - -parts_with_digest = [part for part in otp_mmap.config["partitions"] if - (part["sw_digest"] or part["hw_digest"])] -%>\ -// otp_ctrl_dai_lock_vseq is developed to read/write lock DAI interface by partitions, and request -// read/write access to check if correct status and error code is triggered - -// Partition's legal range covers offset to digest addresses, dai_rd/dai_wr function will -// randomize the address based on the granularity. -`define PART_ADDR_RANGE(i) ${"\\"} - {[PartInfo[``i``].offset : (PartInfo[``i``].offset + PartInfo[``i``].size - 8)]} - -class otp_ctrl_dai_lock_vseq extends otp_ctrl_smoke_vseq; - `uvm_object_utils(otp_ctrl_dai_lock_vseq) - - `uvm_object_new - - // enable access_err for each cycle - constraint no_access_err_c {access_locked_parts == 1;} - - constraint num_trans_c { - num_trans inside {[1:10]}; - num_dai_op inside {[1:50]}; - } - - // the LC partition is always the last one - constraint partition_index_c {part_idx inside {[0:LifeCycleIdx]};} - - constraint dai_wr_legal_addr_c { -% for part in parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (part_idx == ${part_name_camel}Idx) { - dai_addr inside `PART_ADDR_RANGE(${part_name_camel}Idx); - } -% endfor - if (part_idx == LifeCycleIdx) { - if (write_unused_addr) { - dai_addr inside {[PartInfo[LifeCycleIdx].offset : {OTP_ADDR_WIDTH{1'b1}}]}; - } else { - dai_addr inside `PART_ADDR_RANGE(LifeCycleIdx); - } - } - solve part_idx before dai_addr; - } - - constraint dai_wr_digests_c { - {dai_addr[TL_AW-1:2], 2'b0} dist { - { -% for part in parts_with_digest: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - ${part_name_camel}DigestOffset${"" if loop.last else ","} -% endfor - } :/ 1, - [VendorTestOffset : '1] :/ 9 - }; - } - - virtual task pre_start(); - super.pre_start(); - is_valid_dai_op = 0; - endtask - - virtual task dut_init(string reset_kind = "HARD"); - super.dut_init(reset_kind); - if ($urandom_range(0, 1)) begin - cfg.otp_ctrl_vif.drive_lc_creator_seed_sw_rw_en(get_rand_lc_tx_val(.t_weight(0))); - end - if ($urandom_range(0, 1)) begin - cfg.otp_ctrl_vif.drive_lc_owner_seed_sw_rw_en(get_rand_lc_tx_val(.t_weight(0))); - end - endtask - -endclass - -`undef PART_ADDR_RANGE diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_env_cov.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_env_cov.sv.tpl deleted file mode 100644 index f20736c346159..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_env_cov.sv.tpl +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -/** - * Covergoups that are dependent on run-time parameters that may be available - * only in build_phase can be defined here - * Covergroups may also be wrapped inside helper classes if needed. - */ -<% -from topgen.lib import Name - -parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] in ["Buffered", "Unbuffered"]] - -unbuffered_parts = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Unbuffered"] - -unbuffered_parts_with_digest = [part for part in unbuffered_parts if - (part["sw_digest"] or part["hw_digest"])] - -buffered_parts = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Buffered"] - -buffered_nonsecret_parts_with_digest = [part for part in buffered_parts if - (part["sw_digest"] or part["hw_digest"]) and - not part["secret"]] - -buffered_secret_parts_with_digest = [part for part in buffered_parts if - (part["sw_digest"] or part["hw_digest"]) and - part["secret"]] -## Partitions + LCI + DAI -num_err_code = len(otp_mmap.config["partitions"]) + 2 -%>\ -class otp_ctrl_unbuf_err_code_cg_wrap; - // Unbuffered partition can use TLUL interface to read out but cannot write, thus error_code does - // not have write_blank_err. - covergroup unbuf_err_code_cg(string name) with function sample(bit [TL_DW-1:0] val); - option.per_instance = 1; - option.name = name; - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins access_err = {OtpAccessError}; - bins check_fail = {OtpCheckFailError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - function new(string name); - unbuf_err_code_cg = new(name); - endfunction -endclass - -class otp_ctrl_buf_err_code_cg_wrap; - // Buffered partition must use DAI interface to access partition, so it does not have access_err - // and write_blank err. - covergroup buf_err_code_cg(string name) with function sample(bit [TL_DW-1:0] val); - option.per_instance = 1; - option.name = name; - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins check_fail = {OtpCheckFailError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - function new(string name); - buf_err_code_cg = new(name); - endfunction -endclass - -class otp_ctrl_csr_rd_after_alert_cg_wrap; - // This covergroup samples CSRs being checked (via CSR read) after fatal alert is issued. - covergroup csr_rd_after_alert_cg(otp_ctrl_core_reg_block ral) with function sample(bit[TL_DW-1:0] - csr_offset); - read_csr_after_alert_issued: coverpoint csr_offset { - bins unbuffered_digests = { -% for part in unbuffered_parts_with_digest: - ral.${part["name"].lower()}_digest[0].get_offset(), - ral.${part["name"].lower()}_digest[1].get_offset()${"" if loop.last else ","} -% endfor - }; - bins hw_digests = { -% for part in buffered_nonsecret_parts_with_digest: - ral.${part["name"].lower()}_digest[0].get_offset(), - ral.${part["name"].lower()}_digest[1].get_offset()${"" if loop.last else ","} -% endfor - }; - bins secret_digests = { -% for part in buffered_secret_parts_with_digest: - ral.${part["name"].lower()}_digest[0].get_offset(), - ral.${part["name"].lower()}_digest[1].get_offset()${"" if loop.last else ","} -% endfor - }; - bins direct_access_rdata = { - ral.direct_access_rdata[0].get_offset(), - ral.direct_access_rdata[1].get_offset() - }; - bins status = { - ral.status.get_offset() - }; - bins error_code = { -% for k in range(num_err_code): - ral.err_code[${k}].get_offset()${"" if loop.last else ","} -% endfor - }; - } - endgroup - - function new(otp_ctrl_core_reg_block ral); - csr_rd_after_alert_cg = new(ral); - endfunction - - function void sample(bit[TL_DW-1:0] csr_offset); - csr_rd_after_alert_cg.sample(csr_offset); - endfunction -endclass - -class otp_ctrl_unbuf_access_lock_cg_wrap; - covergroup unbuf_access_lock_cg(string name) with function sample(bit read_lock, bit write_lock, - bit is_write); - option.per_instance = 1; - option.name = name; - read_access_locked: coverpoint read_lock; - write_access_locked: coverpoint write_lock; - operation_type: coverpoint is_write { - bins write_op = {1}; - bins read_op = {0}; - } - unbuf_part_access_cross: cross read_access_locked, write_access_locked, operation_type; - endgroup - - function new(string name); - unbuf_access_lock_cg = new(name); - endfunction - - function void sample(bit read_lock, bit write_lock, bit is_write); - unbuf_access_lock_cg.sample(read_lock, write_lock, is_write); - endfunction -endclass - -class otp_ctrl_env_cov extends cip_base_env_cov #(.CFG_T(otp_ctrl_env_cfg)); - `uvm_component_utils(otp_ctrl_env_cov) - - // the base class provides the following handles for use: - // otp_ctrl_env_cfg: cfg - - otp_ctrl_unbuf_err_code_cg_wrap unbuf_err_code_cg_wrap[NumPartUnbuf]; - otp_ctrl_buf_err_code_cg_wrap buf_err_code_cg_wrap[NumPartBuf]; - otp_ctrl_csr_rd_after_alert_cg_wrap csr_rd_after_alert_cg_wrap; - otp_ctrl_unbuf_access_lock_cg_wrap unbuf_access_lock_cg_wrap[NumPartUnbuf]; - - bit_toggle_cg_wrap lc_prog_cg; - bit_toggle_cg_wrap otbn_req_cg; - bit_toggle_cg_wrap status_csr_cg[OtpStatusFieldSize]; - - // covergroups - // This covergroup collects different conditions when outputs (hwcfg_o, keymgr_key_o) are checked - // in scb: - // - If lc_esc_en is On - // - If each partition is locked (expect LC) - covergroup power_on_cg with function sample (bit lc_esc_en, bit[NumPart-2:0] parts_locked); - lc_esc: coverpoint lc_esc_en; -% for k, part in enumerate(parts_without_lc): - ${part["name"].lower()}_lock: coverpoint parts_locked[${k}]; -% endfor - endgroup - - // This covergroup is sampled only if flash request passed scb check. - covergroup flash_req_cg with function sample (int index, bit locked); - flash_index: coverpoint index { - bins flash_data_key = {FlashDataKey}; - bins flash_addr_key = {FlashAddrKey}; - illegal_bins il = default; - } - secret1_lock: coverpoint locked; - flash_req_lock_cross: cross flash_index, secret1_lock; - endgroup - - // This covergroup is sampled only if sram request passed scb check. - covergroup sram_req_cg with function sample (int index, bit locked); - sram_index: coverpoint index { - bins sram_key[NumSramKeyReqSlots] = {[0:(NumSramKeyReqSlots-1)]}; - illegal_bins il = default; - } - secret1_lock: coverpoint locked; - sram_req_lock_cross: cross sram_index, secret1_lock; - endgroup - - // This covergroup is sampled only if keymgr output passed scb check. - covergroup keymgr_o_cg with function sample (bit lc_seed_hw_rd_en, bit locked); - keymgr_rd_en: coverpoint lc_seed_hw_rd_en; - // TODO: probably should add all partitions with keymgr material here. - secret2_lock: coverpoint locked; - keymgr_output_conditions: cross keymgr_rd_en, secret2_lock; - endgroup - - // This covergroup samples dai request being issued after fatal alert is issued. - covergroup req_dai_access_after_alert_cg with function sample(bit [TL_DW-1:0] val); - req_dai_access_after_alert_issued: coverpoint val { - bins dai_write = {DaiWrite}; - bins dai_read = {DaiRead}; - bins dai_digest = {DaiDigest}; - } - endgroup - - // This covergroup samples background check being issued after fatal alert is issued. - covergroup issue_checks_after_alert_cg with function sample(bit [TL_DW-1:0] val); - issue_checks_after_alert_issued: coverpoint val { - bins integrity_check = {1}; - bins consistency_check = {2}; - } - endgroup - - // This covergroup collects DAI err_code value. - // DAI access does not have checks, thus no check_fail error. - covergroup dai_err_code_cg with function sample(bit [TL_DW-1:0] val, int part_idx); - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins write_blank_err = {OtpMacroWriteBlankError}; - bins access_err = {OtpAccessError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - partition: coverpoint part_idx { -% for part in otp_mmap.config["partitions"]: -<% part_name = Name.from_snake_case(part["name"]) %>\ - bins ${part["name"].lower()} = {${part_name.as_camel_case()}Idx}; -% endfor - bins illegal_idx = default; - } - // LC partition has a separate LCI err_code to collect macro related errors. - dai_err_code_for_all_partitions: cross err_code_vals, partition { - // Illegal bin - vendor_test partition does not have EccUncorrectable error. - illegal_bins vendor_test_ecc_uncorrectable_err = - binsof (partition.vendor_test) && binsof (err_code_vals.ecc_uncorr_err); - ignore_bins life_cycle_ignore = binsof (partition.life_cycle) && - binsof(err_code_vals) intersect {[OtpMacroError:OtpMacroWriteBlankError]}; - } - endgroup - - // This covergroup collects LCI err_code value. - // LCI access does not have digest, thus no access_err. Check_fail, ecc_errors are covered in lc - // buffered partition instead of LCI here. - covergroup lci_err_code_cg with function sample(bit [TL_DW-1:0] val); - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins write_blank_err = {OtpMacroWriteBlankError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - covergroup dai_access_secret2_cg with function sample(bit lc_rw_en, dai_cmd_e dai_cmd); - lc_creator_seed_sw_rw_en: coverpoint lc_rw_en; - dai_access_cmd: coverpoint dai_cmd { - bins dai_rd = {DaiRead}; - bins dai_wr = {DaiWrite}; - bins dai_digest = {DaiDigest}; - } - dai_access_secret2: cross lc_creator_seed_sw_rw_en, dai_access_cmd; - endgroup - - function new(string name, uvm_component parent); - super.new(name, parent); - // Create coverage from local covergroups. - power_on_cg = new(); - flash_req_cg = new(); - sram_req_cg = new(); - keymgr_o_cg = new(); - req_dai_access_after_alert_cg = new(); - issue_checks_after_alert_cg = new(); - dai_err_code_cg = new(); - lci_err_code_cg = new(); - dai_access_secret2_cg = new(); - endfunction : new - - virtual function void build_phase(uvm_phase phase); - super.build_phase(phase); - // Create instances from bit_toggle_cg_wrapper. - lc_prog_cg = new("lc_prog_cg", "", 0); - otbn_req_cg = new("otbn_req_cg", "", 0); - foreach (status_csr_cg[i]) begin - otp_status_e index = otp_status_e'(i); - status_csr_cg[i]= new(index.name, "status_csr_cg", 0); - end - - // Create instances from external wrapper classes. - csr_rd_after_alert_cg_wrap = new(cfg.ral); - foreach (unbuf_err_code_cg_wrap[i]) begin - otp_status_e index = otp_status_e'(i); - unbuf_err_code_cg_wrap[i] = new($sformatf("unbuf_err_code_cg_wrap[%0s]", index.name)); - end - foreach (buf_err_code_cg_wrap[i]) begin - otp_status_e index = otp_status_e'(i + 2); - buf_err_code_cg_wrap[i] = new($sformatf("buf_err_code_cg_wrap[%0s]", index.name)); - end - foreach (unbuf_access_lock_cg_wrap[i]) begin - part_idx_e index = part_idx_e'(i); - unbuf_access_lock_cg_wrap[i] = new($sformatf("buf_err_code_cg_wrap[%0s]", index.name)); - end - endfunction - - function void collect_status_cov(bit [TL_DW-1:0] val); - foreach (status_csr_cg[i]) begin - status_csr_cg[i].sample(val[i]); - end - endfunction - - // Collect coverage for err_code when it is a compact multi-reg. For DAI error it uses the given - // access_part_idx as the target of the DAI access. - function void collect_compact_err_code_cov(bit [TL_DW-1:0] val, int access_part_idx = DaiIdx); - dv_base_reg_field err_code_flds[$]; - cfg.ral.err_code[0].get_dv_base_reg_fields(err_code_flds); - foreach (err_code_flds[part]) begin - collect_err_code_cov(part, get_field_val(err_code_flds[part], val), access_part_idx); - end - endfunction - - // Collect coverage for a given partition error_code. For DAI error it uses the given - // access_part_idx as the target of the DAI access. - function void collect_err_code_cov(int part_idx, bit [TL_DW-1:0] val, - int access_part_idx = DaiIdx); - case (part_idx) -% for part in otp_mmap.config["partitions"]: -<% part_name = Name.from_snake_case(part["name"]) %>\ - Otp${part_name.as_camel_case()}ErrIdx: begin - % if part in unbuffered_parts: - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - % elif part in buffered_parts: - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - % endif - end -% endfor - OtpDaiErrIdx: begin - dai_err_code_cg.sample(val, access_part_idx); - end - OtpLciErrIdx: begin - lci_err_code_cg.sample(val); - end - default: begin - `uvm_fatal(`gfn, $sformatf("invalid err_code index %0d", part_idx)) - end - endcase - endfunction -endclass diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_env_pkg.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_env_pkg.sv.tpl deleted file mode 100644 index 08c86cb201937..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_env_pkg.sv.tpl +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] in ["Buffered", "Unbuffered"]] -otp_size_as_hex_text = f'{(2 ** otp_mmap.config["otp"]["byte_addr_width"]):x}' -%>\ -package otp_ctrl_env_pkg; - // dep packages - import uvm_pkg::*; - import top_pkg::*; - import dv_utils_pkg::*; - import dv_lib_pkg::*; - import dv_base_reg_pkg::*; - import tl_agent_pkg::*; - import cip_base_pkg::*; - import csr_utils_pkg::*; - import push_pull_agent_pkg::*; - import otp_ctrl_core_ral_pkg::*; - import otp_ctrl_prim_ral_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_pkg::*; - import otp_ctrl_part_pkg::*; - import lc_ctrl_pkg::*; - import lc_ctrl_state_pkg::*; - import lc_ctrl_dv_utils_pkg::*; - import mem_bkdr_util_pkg::*; - import otp_scrambler_pkg::*; - import sec_cm_pkg::*; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // parameters - parameter string LIST_OF_ALERTS[] = {"fatal_macro_error", - "fatal_check_error", - "fatal_bus_integ_error", - "fatal_prim_otp_alert", - "recov_prim_otp_alert"}; - parameter uint NUM_ALERTS = 5; - parameter uint NUM_EDN = 1; - - parameter uint DIGEST_SIZE = 8; - parameter uint SW_WINDOW_BASE_ADDR = 'h${otp_size_as_hex_text}; - parameter uint SW_WINDOW_SIZE = NumSwCfgWindowWords * 4; - - parameter uint TL_SIZE = (TL_DW / 8); - // LC has its own storage in scb - // we can use the LC offset here because it will always be the last partition. - parameter uint OTP_ARRAY_SIZE = LcTransitionCntOffset / TL_SIZE; - - parameter int OTP_ADDR_WIDTH = OtpByteAddrWidth-2; - - parameter uint NUM_PRIM_REG = 8; - - // sram rsp data has 1 bit for seed_valid, the rest are for key and nonce - parameter uint SRAM_DATA_SIZE = 1 + SramKeyWidth + SramNonceWidth; - // otbn rsp data has 1 bit for seed_valid, the rest are for key and nonce - parameter uint OTBN_DATA_SIZE = 1 + OtbnKeyWidth + OtbnNonceWidth; - // flash rsp data has 1 bit for seed_valid, the rest are for key - parameter uint FLASH_DATA_SIZE = 1 + FlashKeyWidth; - // lc program data has lc_state data and lc_cnt data - parameter uint LC_PROG_DATA_SIZE = LcStateWidth + LcCountWidth; - - parameter uint NUM_SRAM_EDN_REQ = 12; - parameter uint NUM_OTBN_EDN_REQ = 10; - - parameter uint CHK_TIMEOUT_CYC = 40; - - // When fatal alert triggered, all partitions and the DAI & LCI go to error state and status will - // be set to 1. - parameter bit [NumErrorEntries-1:0] FATAL_EXP_STATUS = '1; - - // lc does not have dai access - parameter int PART_BASE_ADDRS [NumPart-1] = { -% for part in parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - ${part_name_camel}Offset${"" if loop.last else ","} -% endfor - }; - - // lc does not have digest - parameter int PART_OTP_DIGEST_ADDRS [NumPart-1] = { -% for part in parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ -% if part["sw_digest"] or part["hw_digest"]: - ${part_name_camel}DigestOffset >> 2${"" if loop.last else ","} -% else: - -1${"" if loop.last else ","} // This partition does not have a digest. -% endif -% endfor - }; - - // types - typedef enum bit [1:0] { - OtpOperationDone, - OtpErr, - NumOtpCtrlIntr - } otp_intr_e; - - typedef enum bit [5:0] { -% for part in otp_mmap.config["partitions"]: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - Otp${part_name_camel}ErrIdx, -% endfor - OtpDaiErrIdx, - OtpLciErrIdx, - OtpTimeoutErrIdx, - OtpLfsrFsmErrIdx, - OtpScramblingFsmErrIdx, - OtpDerivKeyFsmErrIdx, - OtpBusIntegErrorIdx, - OtpDaiIdleIdx, - OtpCheckPendingIdx, - OtpStatusFieldSize - } otp_status_e; - - typedef enum bit [2:0] { - OtpNoError, - OtpMacroError, - OtpMacroEccCorrError, - OtpMacroEccUncorrError, - OtpMacroWriteBlankError, - OtpAccessError, - OtpCheckFailError, - OtpFsmStateError - } otp_err_code_e; - - typedef enum bit [1:0] { - OtpNoEccErr, - OtpEccCorrErr, - OtpEccUncorrErr - } otp_ecc_err_e; - - typedef enum bit [1:0] { - OtpNoAlert, - OtpCheckAlert, - OtpMacroAlert - } otp_alert_e; - - typedef struct packed { - bit read_lock; - bit write_lock; - } otp_part_access_lock_t; - - // OTP conditions when driving specific port. - typedef enum bit [2:0] { - DuringOTPInit, - DuringOTPDaiBusy, - DuringOTPDaiDigest, - DuringOTPRead, - DriveRandomly - } port_drive_condition_e; - - typedef virtual otp_ctrl_if otp_ctrl_vif; - - parameter otp_err_code_e OTP_TERMINAL_ERRS[4] = {OtpMacroEccUncorrError, - OtpCheckFailError, - OtpFsmStateError, - OtpMacroError}; - - // functions - function automatic int get_part_index(bit [TL_DW-1:0] addr); - int index; - for (index = 0; index < NumPart; index++) begin - if (PartInfo[index].offset > addr) begin - index--; - break; - end - end - if (index == NumPart) index--; - return index; - endfunction - - function automatic bit is_secret(bit [TL_DW-1:0] addr); - int part_index = get_part_index(addr); - return PartInfo[part_index].secret; - endfunction - - function automatic bit part_has_digest(int part_idx); - return PartInfo[part_idx].hw_digest || PartInfo[part_idx].sw_digest; - endfunction - - function automatic bit part_has_hw_digest(int part_idx); - return PartInfo[part_idx].hw_digest; - endfunction - - function automatic bit is_sw_digest(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - if (PartInfo[part_idx].sw_digest) begin - // If the partition contains a digest, it will be located in the last 64bit of the partition. - return {addr[TL_DW-1:3], 3'b0} == ((PartInfo[part_idx].offset + PartInfo[part_idx].size) - 8); - end else begin - return 0; - end - endfunction - - function automatic bit is_digest(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - if (PartInfo[part_idx].sw_digest || PartInfo[part_idx].hw_digest) begin - // If the partition contains a digest, it will be located in the last 64bit of the partition. - return {addr[TL_DW-1:3], 3'b0} == ((PartInfo[part_idx].offset + PartInfo[part_idx].size) - 8); - end else begin - return 0; - end - endfunction - - function automatic bit is_sw_part(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - return is_sw_part_idx(part_idx); - endfunction - - function automatic bit is_sw_part_idx(int part_idx); - return (PartInfo[part_idx].variant == Unbuffered); - endfunction - - function automatic bit is_hw_part(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - return is_hw_part_idx(part_idx); - endfunction - - function automatic bit is_hw_part_idx(int part_idx); - return (PartInfo[part_idx].variant == Buffered); - endfunction - - // Returns true if this partition supports ECC. Otherwise, no ECC errors are reported, and - // the single bit errors are not corrected. - function automatic bit part_has_integrity(int part_idx); - return PartInfo[part_idx].integrity; - endfunction - - // Resolve an offset within the software window as an offset within the whole otp_ctrl block. - function automatic bit [TL_AW-1:0] get_sw_window_offset(bit [TL_AW-1:0] dai_addr); - return dai_addr + SW_WINDOW_BASE_ADDR; - endfunction - - function automatic bit [TL_DW-1:0] normalize_dai_addr(bit [TL_DW-1:0] dai_addr); - normalize_dai_addr = (is_secret(dai_addr) || is_digest(dai_addr)) ? dai_addr >> 3 << 3 : - dai_addr >> 2 << 2; - endfunction - - // package sources - `include "otp_ctrl_ast_inputs_cfg.sv" - `include "otp_ctrl_env_cfg.sv" - `include "otp_ctrl_env_cov.sv" - `include "otp_ctrl_virtual_sequencer.sv" - `include "otp_ctrl_scoreboard.sv" - `include "otp_ctrl_env.sv" - `include "otp_ctrl_vseq_list.sv" - -endpackage diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_if.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_if.sv.tpl deleted file mode 100644 index 4fac06be38100..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_if.sv.tpl +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name -unbuf_parts_with_digest = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Unbuffered" and - (part["sw_digest"] or part["hw_digest"])] -parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] in ["Buffered", "Unbuffered"]] -buf_parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Buffered"] -%>\ -// This interface collect the broadcast output data from OTP, -// and drive input requests coming into OTP. -`define ECC_REG_PATH gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec - -// This only supports buffered partitions. -`define BUF_PART_OTP_CMD_PATH(i) ${"\\"} - tb.dut.gen_partitions[``i``].gen_buffered.u_part_buf.otp_cmd_o - -`define LC_PART_OTP_CMD_PATH ${"\\"} - tb.dut.gen_partitions[LifeCycleIdx].gen_lifecycle.u_part_buf.otp_cmd_o - -`define FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(i) ${"\\"} - if (forced_part_access_sel[``i``].read_lock) begin ${"\\"} - force tb.dut.part_access[``i``].read_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); ${"\\"} - force tb.dut.part_access_dai[``i``].read_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); ${"\\"} - end ${"\\"} - if (forced_part_access_sel[``i``].write_lock) begin ${"\\"} - force tb.dut.part_access[``i``].write_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); ${"\\"} - force tb.dut.part_access_dai[``i``].write_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); ${"\\"} - end - -`ifndef PRIM_GENERIC_OTP_PATH - `define PRIM_GENERIC_OTP_PATH${"\\"} - tb.dut.u_otp -`endif - -`ifndef PRIM_GENERIC_OTP_CMD_I_PATH - `define PRIM_GENERIC_OTP_CMD_I_PATH ${"\\"} - `PRIM_GENERIC_OTP_PATH.gen_generic.u_impl_generic.cmd_i -`endif - -interface otp_ctrl_if(input clk_i, input rst_ni); - import uvm_pkg::*; - import otp_ctrl_env_pkg::*; - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; - import cip_base_pkg::*; - - // Output from DUT - otp_broadcast_t otp_broadcast_o; - otp_keymgr_key_t keymgr_key_o; - otp_lc_data_t lc_data_o; - logic pwr_otp_done_o, pwr_otp_idle_o; - - // Inputs to DUT - logic pwr_otp_init_i, scan_en_i, scan_rst_ni, ext_voltage_h_io; - lc_ctrl_pkg::lc_tx_t lc_dft_en_i, lc_escalate_en_i, lc_check_byp_en_i, - lc_creator_seed_sw_rw_en_i, lc_owner_seed_sw_rw_en_i, - lc_seed_hw_rd_en_i; - prim_mubi_pkg::mubi4_t scanmode_i; - otp_ast_rsp_t otp_ast_pwr_seq_h_i; - ast_pkg::ast_obs_ctrl_t obs_ctrl_i; - - // Unused in prim_generic_otp memory. - logic [OtpTestCtrlWidth-1:0] otp_vendor_test_ctrl_i; - logic [OtpTestStatusWidth-1:0] otp_vendor_test_status_o; - logic [OtpTestVectWidth-1:0] cio_test_o; - logic [OtpTestVectWidth-1:0] cio_test_en_o; - - // Connect with lc_prog push_pull interface. - logic lc_prog_req, lc_prog_err; - logic lc_prog_err_dly1, lc_prog_no_sta_check; - - // Connect push_pull interfaces ack signals for assertion checks. - logic otbn_ack, lc_prog_ack; - logic [1:0] flash_acks; - logic [NumSramKeyReqSlots-1:0] sram_acks; - - // Variables for internal interface logic. - // `lc_escalate_en` is async, take two clock cycles to synchronize. - lc_ctrl_pkg::lc_tx_t lc_esc_dly1, lc_esc_dly2; - - // Variable for scoreboard. - // For `lc_escalate_en`, any value that is not `Off` is a `On`. - bit lc_esc_on; - - // Probe design signal for alert request. - logic alert_reqs; - - // Usually the `lc_check_byp_en` will be automatically set to `On` when LC program request is - // issued, and stays `On` until reset is issued. - // Set this variable to 0 after a LC program request might cause otp checks to fail. - bit lc_check_byp_en = 1; - - // Internal veriable to track which sw partitions have ECC reg error. - bit [NumPartUnbuf-1:0] force_sw_parts_ecc_reg; - - // DUT configuration object - otp_ctrl_ast_inputs_cfg dut_cfg; - - // for DV macros ID - string msg_id = "otp_ctrl_if"; - - // Lc_err could trigger during LC program, so check intr and status after lc_req is finished. - // Lc_err takes one clock cycle to propogate to intr signal. So avoid intr check if it happens - // during the transition. - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - lc_prog_err_dly1 <= 0; - lc_esc_dly1 <= lc_ctrl_pkg::Off; - lc_esc_dly2 <= lc_ctrl_pkg::Off; - lc_check_byp_en_i <= get_rand_lc_tx_val(); - lc_esc_on <= 0; - end else begin - lc_prog_err_dly1 <= lc_prog_err; - lc_esc_dly1 <= lc_escalate_en_i; - lc_esc_dly2 <= lc_esc_dly1; - if (lc_prog_req) begin - lc_check_byp_en_i <= lc_check_byp_en ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; - end - if (lc_esc_dly2 != lc_ctrl_pkg::Off && !lc_esc_on) begin - lc_esc_on <= 1; - end - end - end - - assign lc_prog_no_sta_check = lc_prog_err | lc_prog_err_dly1 | lc_prog_req | lc_esc_on; - - function automatic void drive_pwr_otp_init(logic val); - pwr_otp_init_i = val; - endfunction - - function automatic void drive_ext_voltage_h_io(logic val); - ext_voltage_h_io = val; - endfunction - - function automatic void drive_lc_creator_seed_sw_rw_en(lc_ctrl_pkg::lc_tx_t val); - lc_creator_seed_sw_rw_en_i = val; - endfunction - - function automatic void drive_lc_owner_seed_sw_rw_en(lc_ctrl_pkg::lc_tx_t val); - lc_owner_seed_sw_rw_en_i = val; - endfunction - - function automatic void drive_lc_dft_en(lc_ctrl_pkg::lc_tx_t val); - lc_dft_en_i = val; - endfunction - - function automatic void drive_lc_escalate_en(lc_ctrl_pkg::lc_tx_t val); - lc_escalate_en_i = val; - endfunction - - function automatic void drive_lc_seed_hw_rd_en(lc_ctrl_pkg::lc_tx_t val); - lc_seed_hw_rd_en_i = val; - endfunction - - function automatic bit under_error_states(); - return lc_esc_on | alert_reqs; - endfunction - - // SW partitions do not have any internal checks. - // Here we force internal ECC check to fail. - task automatic force_sw_check_fail( - bit[NumPartUnbuf-1:0] fail_idx = $urandom_range(1, (1'b1 << NumPartUnbuf) - 1)); - @(posedge clk_i); -% for part in unbuf_parts_with_digest: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (fail_idx[${part_name_camel}Idx]) begin - force tb.dut.gen_partitions[${part_name_camel}Idx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[${part_name_camel}Idx] = 1; - end -% endfor - endtask - - task automatic release_sw_check_fail(); - @(posedge clk_i); -% for part in unbuf_parts_with_digest: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (force_sw_parts_ecc_reg[${part_name_camel}Idx]) begin - release tb.dut.gen_partitions[${part_name_camel}Idx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[${part_name_camel}Idx] = 0; - end -% endfor - endtask - - // Force prim_generic_otp input cmd_i to a invalid value. - task automatic force_invalid_otp_cmd_i(); - @(posedge clk_i); - force `PRIM_GENERIC_OTP_CMD_I_PATH = prim_otp_pkg::cmd_e'(2'b10); - endtask - - task automatic release_invalid_otp_cmd_i(); - @(posedge clk_i); - release `PRIM_GENERIC_OTP_CMD_I_PATH; - endtask - - // Force part_buf partitions output otp_cmd_o to a invalid value. - task automatic force_invalid_part_cmd_o(int part_idx); - @(posedge clk_i); - case (part_idx) -% for part in buf_parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - ${part_name_camel}Idx: force `BUF_PART_OTP_CMD_PATH(${part_name_camel}Idx) = prim_otp_pkg::cmd_e'(2'b10); -% endfor - LifeCycleIdx: force `LC_PART_OTP_CMD_PATH = prim_otp_pkg::cmd_e'(2'b10); - default: begin - `uvm_fatal("otp_ctrl_if", - $sformatf("force invalid otp_cmd_o only supports buffered partitions: %0d", part_idx)) - end - endcase - endtask - - task automatic release_invalid_part_cmd_o(int part_idx); - @(posedge clk_i); - case (part_idx) -% for part in buf_parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - ${part_name_camel}Idx: release `BUF_PART_OTP_CMD_PATH(${part_name_camel}Idx); -% endfor - LifeCycleIdx: release `LC_PART_OTP_CMD_PATH; - default: begin - `uvm_fatal("otp_ctrl_if", - $sformatf("release invalid otp_cmd_o only supports buffered partitions: %0d", - part_idx)) - end - endcase - endtask - - // This task forces otp_ctrl's internal mubi signals to values that are not mubi::true or mubi:: - // false. Then scb will check if design treats these values as locking the partition access. - task automatic force_part_access_mubi(otp_part_access_lock_t forced_part_access_sel[NumPart-1]); - @(posedge clk_i); -% for part in parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(${part_name_camel}Idx) -% endfor - endtask - - task automatic release_part_access_mubi(); - @(posedge clk_i); - release tb.dut.part_access; - release tb.dut.part_access_dai; - endtask - - // Connectivity assertions for test related I/Os. - `ASSERT(LcOtpTestStatusO_A, otp_vendor_test_status_o == `PRIM_GENERIC_OTP_PATH.test_status_o) - `ASSERT(LcOtpTestCtrlI_A, otp_vendor_test_ctrl_i == `PRIM_GENERIC_OTP_PATH.test_ctrl_i) - - `ASSERT(CioTestOWithDftOn_A, lc_dft_en_i == lc_ctrl_pkg::On |-> - ${"##"}[2:3] cio_test_o == `PRIM_GENERIC_OTP_PATH.test_vect_o) - `ASSERT(CioTestOWithDftOff_A, lc_dft_en_i != lc_ctrl_pkg::On |-> ##[2:3] cio_test_o == 0) - `ASSERT(CioTestEnOWithDftOn_A, lc_dft_en_i == lc_ctrl_pkg::On |-> ##[2:3] cio_test_en_o == '1) - `ASSERT(CioTestEnOWithDftOff_A, lc_dft_en_i != lc_ctrl_pkg::On |-> ##[2:3] cio_test_en_o == 0) - - - `define OTP_ASSERT_WO_LC_ESC(NAME, SEQ) ${"\\"} - `ASSERT(NAME, SEQ, clk_i, !rst_ni || lc_esc_on || alert_reqs) - - // If pwr_otp_idle is set only if pwr_otp init is done - `OTP_ASSERT_WO_LC_ESC(OtpPwrDoneWhenIdle_A, pwr_otp_idle_o |-> pwr_otp_done_o) - - // otp_broadcast_o is valid only when otp init is done - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgValidOn_A, pwr_otp_done_o |-> - otp_broadcast_o.valid == lc_ctrl_pkg::On) - // If otp_broadcast is Off, then hw partition is not finished calculation, - // then otp init is not done - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgValidOff_A, otp_broadcast_o.valid == lc_ctrl_pkg::Off |-> - pwr_otp_done_o == 0) - // Once OTP init is done, otp_broadcast_o output value stays stable until next power cycle - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgStable_A, otp_broadcast_o.valid == lc_ctrl_pkg::On |=> - $stable(otp_broadcast_o)) - - // Otp_keymgr valid is related to part_digest, should not be changed after otp_pwr_init - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable0_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_root_key_share0_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable1_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_root_key_share1_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable2_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_seed_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable3_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.owner_seed_valid)) - - // During lc_prog_req, either otp_idle will be reset or lc_error is set - `OTP_ASSERT_WO_LC_ESC(LcProgReq_A, $rose(lc_prog_req) |=> - (pwr_otp_idle_o == 0 || $rose(lc_prog_err)) within lc_prog_req[*1:$]) - - // During fatal alert, check if otp outputs revert back to default value. - // Wait three clock cycles until error propogates to each FSM states and regs. - `define OTP_FATAL_ERR_ASSERT(NAME, SEQ) ${"\\"} - `ASSERT(FatalErr``NAME``, alert_reqs |-> ##3 SEQ) - - `OTP_FATAL_ERR_ASSERT(LcDataValid_A, lc_data_o.valid == 0 && lc_data_o.error == 1) - `OTP_FATAL_ERR_ASSERT(LcDataState_A, lc_data_o.state == - PartInvDefault[LcStateOffset*8+:LcStateSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataCount_A, lc_data_o.count == - PartInvDefault[LcTransitionCntOffset*8+:LcTransitionCntSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataTestUnlockToken_A, lc_data_o.test_unlock_token == - PartInvDefault[TestUnlockTokenOffset*8+:TestUnlockTokenSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataTestExitToken_A, lc_data_o.test_exit_token == - PartInvDefault[TestExitTokenOffset*8+:TestExitTokenSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataRmaToken_A, lc_data_o.rma_token == - PartInvDefault[RmaTokenOffset*8+:RmaTokenSize*8]) - - `OTP_FATAL_ERR_ASSERT(KeymgrKeyData_A, keymgr_key_o.creator_root_key_share0 == - PartInvDefault[CreatorRootKeyShare0Offset*8+:CreatorRootKeyShare0Size*8] && - keymgr_key_o.creator_root_key_share1 == - PartInvDefault[CreatorRootKeyShare1Offset*8+:CreatorRootKeyShare1Size*8]) - - `OTP_FATAL_ERR_ASSERT(HwCfgOValid_A, otp_broadcast_o.valid == lc_ctrl_pkg::Off) - `OTP_FATAL_ERR_ASSERT(HwCfg0OData_A, otp_broadcast_o.hw_cfg0_data == - PartInvDefault[HwCfg0Offset*8+:HwCfg0Size*8]) - `OTP_FATAL_ERR_ASSERT(HwCfg1OData_A, otp_broadcast_o.hw_cfg1_data == - PartInvDefault[HwCfg1Offset*8+:HwCfg1Size*8]) - - `OTP_FATAL_ERR_ASSERT(LcProgAck_A, lc_prog_ack == 0) - `OTP_FATAL_ERR_ASSERT(FlashAcks_A, flash_acks == 0) - `OTP_FATAL_ERR_ASSERT(SramAcks_A, sram_acks == 0) - `OTP_FATAL_ERR_ASSERT(OtbnAck_A, otbn_ack == 0) - - `undef OTP_ASSERT_WO_LC_ESC - `undef OTP_FATAL_ERR_ASSERT - `undef ECC_REG_PATH - `undef BUF_PART_OTP_CMD_PATH - `undef LC_PART_OTP_CMD_PATH - `undef PRIM_GENERIC_OTP_PATH - `undef PRIM_GENERIC_OTP_CMD_I_PATH - `undef FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL -endinterface diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_part_pkg.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_part_pkg.sv.tpl deleted file mode 100644 index 6c8e0154054e7..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_part_pkg.sv.tpl +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Package partition metadata. -// -${gen_comment} -<% -from topgen.lib import Name -%>\ -package otp_ctrl_part_pkg; - - import prim_util_pkg::vbits; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_pkg::*; - - //////////////////////////////////// - // Scrambling Constants and Types // - //////////////////////////////////// - - parameter int NumScrmblKeys = ${len(otp_mmap.config["scrambling"]["keys"])}; - parameter int NumDigestSets = ${len(otp_mmap.config["scrambling"]["digests"])}; - - parameter int ScrmblKeySelWidth = vbits(NumScrmblKeys); - parameter int DigestSetSelWidth = vbits(NumDigestSets); - parameter int ConstSelWidth = (ScrmblKeySelWidth > DigestSetSelWidth) ? - ScrmblKeySelWidth : - DigestSetSelWidth; - - typedef enum logic [ConstSelWidth-1:0] { - StandardMode, - ChainedMode - } digest_mode_e; - - typedef logic [NumScrmblKeys-1:0][ScrmblKeyWidth-1:0] key_array_t; - typedef logic [NumDigestSets-1:0][ScrmblKeyWidth-1:0] digest_const_array_t; - typedef logic [NumDigestSets-1:0][ScrmblBlockWidth-1:0] digest_iv_array_t; - - typedef enum logic [ConstSelWidth-1:0] { -% for key in otp_mmap.config["scrambling"]["keys"]: - ${key["name"]}${"" if loop.last else ","} -% endfor - } key_sel_e; - - typedef enum logic [ConstSelWidth-1:0] { -% for dig in otp_mmap.config["scrambling"]["digests"]: - ${dig["name"]}${"" if loop.last else ","} -% endfor - } digest_sel_e; - - // SEC_CM: SECRET.MEM.SCRAMBLE - parameter key_array_t RndCnstKey = { -% for key in otp_mmap.config["scrambling"]["keys"][::-1]: - ${"{0:}'h{1:0X}".format(otp_mmap.config["scrambling"]["key_size"] * 8, key["value"])}${"" if loop.last else ","} -% endfor - }; - - // SEC_CM: PART.MEM.DIGEST - // Note: digest set 0 is used for computing the partition digests. Constants at - // higher indices are used to compute the scrambling keys. - parameter digest_const_array_t RndCnstDigestConst = { -% for dig in otp_mmap.config["scrambling"]["digests"][::-1]: - ${"{0:}'h{1:0X}".format(otp_mmap.config["scrambling"]["cnst_size"] * 8, dig["cnst_value"])}${"" if loop.last else ","} -% endfor - }; - - parameter digest_iv_array_t RndCnstDigestIV = { -% for dig in otp_mmap.config["scrambling"]["digests"][::-1]: - ${"{0:}'h{1:0X}".format(otp_mmap.config["scrambling"]["iv_size"] * 8, dig["iv_value"])}${"" if loop.last else ","} -% endfor - }; - - - ///////////////////////////////////// - // Typedefs for Partition Metadata // - ///////////////////////////////////// - - typedef enum logic [1:0] { - Unbuffered, - Buffered, - LifeCycle - } part_variant_e; - - typedef struct packed { - part_variant_e variant; - // Offset and size within the OTP array, in Bytes. - logic [OtpByteAddrWidth-1:0] offset; - logic [OtpByteAddrWidth-1:0] size; - // Key index to use for scrambling. - key_sel_e key_sel; - // Attributes - logic secret; // Whether the partition is secret (and hence scrambled) - logic sw_digest; // Whether the partition has a software digest - logic hw_digest; // Whether the partition has a hardware digest - logic write_lock; // Whether the partition is write lockable (via digest) - logic read_lock; // Whether the partition is read lockable (via digest) - logic integrity; // Whether the partition is integrity protected - logic iskeymgr_creator; // Whether the partition has any creator key material - logic iskeymgr_owner; // Whether the partition has any owner key material - } part_info_t; - - parameter part_info_t PartInfoDefault = '{ - variant: Unbuffered, - offset: '0, - size: OtpByteAddrWidth'('hFF), - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b0, - hw_digest: 1'b0, - write_lock: 1'b0, - read_lock: 1'b0, - integrity: 1'b0, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }; - - //////////////////////// - // Partition Metadata // - //////////////////////// - - localparam part_info_t PartInfo [NumPart] = '{ -% for part in otp_mmap.config["partitions"]: - // ${part["name"]} - '{ - variant: ${part["variant"]}, - offset: ${otp_mmap.config["otp"]["byte_addr_width"]}'d${part["offset"]}, - size: ${part["size"]}, - key_sel: ${part["key_sel"] if part["key_sel"] != "NoKey" else "key_sel_e'('0)"}, - secret: 1'b${"1" if part["secret"] else "0"}, - sw_digest: 1'b${"1" if part["sw_digest"] else "0"}, - hw_digest: 1'b${"1" if part["hw_digest"] else "0"}, - write_lock: 1'b${"1" if part["write_lock"].lower() == "digest" else "0"}, - read_lock: 1'b${"1" if part["read_lock"].lower() == "digest" else "0"}, - integrity: 1'b${"1" if part["integrity"] else "0"}, - iskeymgr_creator: 1'b${"1" if part["iskeymgr_creator"] else "0"}, - iskeymgr_owner: 1'b${"1" if part["iskeymgr_owner"] else "0"} - }${"" if loop.last else ","} -% endfor - }; - - typedef enum { -% for part in otp_mmap.config["partitions"]: - ${Name.from_snake_case(part["name"]).as_camel_case()}Idx, -% endfor - // These are not "real partitions", but in terms of implementation it is convenient to - // add these at the end of certain arrays. - DaiIdx, - LciIdx, - KdiIdx, - // Number of agents is the last idx+1. - NumAgentsIdx - } part_idx_e; - - parameter int NumAgents = int'(NumAgentsIdx); - - // Breakout types for easier access of individual items. -% for part in otp_mmap.config["partitions"]: - % if part["bkout_type"]: - typedef struct packed {<% offset = part['offset'] + part['size'] %> - % for item in part["items"][::-1]: - % if offset != item['offset'] + item['size']: - logic [${(offset - item['size'] - item['offset']) * 8 - 1}:0] unallocated;<% offset = item['offset'] + item['size'] %> - % endif -<% - if item['ismubi']: - item_type = 'prim_mubi_pkg::mubi' + str(item["size"]*8) + '_t' - else: - item_type = 'logic [' + str(int(item["size"])*8-1) + ':0]' -%>\ - ${item_type} ${item["name"].lower()};<% offset -= item['size'] %> - % endfor - } otp_${part["name"].lower()}_data_t; - - // default value used for intermodule - parameter otp_${part["name"].lower()}_data_t OTP_${part["name"].upper()}_DATA_DEFAULT = '{<% offset = part['offset'] + part['size'] %> - % for k, item in enumerate(part["items"][::-1]): - % if offset != item['offset'] + item['size']: - unallocated: ${"{}'h{:0X}".format((offset - item['size'] - item['offset']) * 8, 0)}<% offset = item['offset'] + item['size'] %>, - % endif -<% - if item['ismubi']: - item_cast_pre = "prim_mubi_pkg::mubi" + str(item["size"]*8) + "_t'(" - item_cast_post = ")" - else: - item_cast_pre = "" - item_cast_post = "" -%>\ - ${item["name"].lower()}: ${item_cast_pre}${"{}'h{:0X}".format(item["size"] * 8, item["inv_default"])}${item_cast_post}${"," if k < len(part["items"])-1 else ""}<% offset -= item['size'] %> - % endfor - }; - % endif -% endfor - typedef struct packed { - // This reuses the same encoding as the life cycle signals for indicating valid status. - lc_ctrl_pkg::lc_tx_t valid; -% for part in otp_mmap.config["partitions"][::-1]: - % if part["bkout_type"]: - otp_${part["name"].lower()}_data_t ${part["name"].lower()}_data; - % endif -% endfor - } otp_broadcast_t; - - // default value for intermodule -<% - k = 0 - num_bkout = 0 - for part in otp_mmap.config["partitions"]: - if part["bkout_type"]: - num_bkout += 1 -%>\ - parameter otp_broadcast_t OTP_BROADCAST_DEFAULT = '{ - valid: lc_ctrl_pkg::Off, -% for part in otp_mmap.config["partitions"][::-1]: - % if part["bkout_type"]: - ${part["name"].lower()}_data: OTP_${part["name"].upper()}_DATA_DEFAULT${"" if k == num_bkout-1 else ","} -<% k+=1 %>\ - % endif -% endfor - }; - -<% offset = int(otp_mmap.config["partitions"][-1]["offset"]) + int(otp_mmap.config["partitions"][-1]["size"]) %> - // OTP invalid partition default for buffered partitions. - parameter logic [${offset * 8 - 1}:0] PartInvDefault = ${offset * 8}'({ - % for k, part in enumerate(otp_mmap.config["partitions"][::-1]): - ${int(part["size"])*8}'({ - % for item in part["items"][::-1]: - % if offset != item['offset'] + item['size']: - ${"{}'h{:0X}".format((offset - item['size'] - item['offset']) * 8, 0)}, // unallocated space<% offset = item['offset'] + item['size'] %> - % endif - ${"{}'h{:0X}".format(item["size"] * 8, item["inv_default"])}${("\n })," if k < len(otp_mmap.config["partitions"])-1 else "\n })});") if loop.last else ","}<% offset -= item['size'] %> - % endfor - % endfor - - /////////////////////////////////////////////// - // Parameterized Assignment Helper Functions // - /////////////////////////////////////////////// - - function automatic otp_ctrl_core_hw2reg_t named_reg_assign( - logic [NumPart-1:0][ScrmblBlockWidth-1:0] part_digest); - otp_ctrl_core_hw2reg_t hw2reg; - logic unused_sigs; - unused_sigs = ^part_digest; - hw2reg = '0; -% for k, part in enumerate(otp_mmap.config["partitions"]): -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - % if part["sw_digest"] or part["hw_digest"]: - hw2reg.${part["name"].lower()}_digest = part_digest[${part_name_camel}Idx]; - % endif -% endfor - return hw2reg; - endfunction : named_reg_assign - - function automatic part_access_t [NumPart-1:0] named_part_access_pre( - otp_ctrl_core_reg2hw_t reg2hw); - part_access_t [NumPart-1:0] part_access_pre; - logic unused_sigs; - unused_sigs = ^reg2hw; - // Default (this will be overridden by partition-internal settings). - part_access_pre = {{32'(2*NumPart)}{prim_mubi_pkg::MuBi8False}}; - // Note: these could be made a MuBi CSRs in the future. - // The main thing that is missing right now is proper support for W0C. -% for k, part in enumerate(otp_mmap.config["partitions"]): - % if part["read_lock"] == "CSR": - // ${part["name"]} - if (!reg2hw.${part["name"].lower()}_read_lock) begin -<% part_name = Name.from_snake_case(part["name"]) %>\ - part_access_pre[${part_name.as_camel_case()}Idx].read_lock = prim_mubi_pkg::MuBi8True; - end - % endif -% endfor - return part_access_pre; - endfunction : named_part_access_pre - - function automatic otp_broadcast_t named_broadcast_assign( - logic [NumPart-1:0] part_init_done, - logic [$bits(PartInvDefault)/8-1:0][7:0] part_buf_data); - otp_broadcast_t otp_broadcast; - logic valid, unused; - unused = 1'b0; - valid = 1'b1; -% for part in otp_mmap.config["partitions"]: - // ${part["name"]} -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - % if part["bkout_type"]: - valid &= part_init_done[${part_name_camel}Idx]; - otp_broadcast.${part["name"].lower()}_data = otp_${part["name"].lower()}_data_t'(part_buf_data[${part_name_camel}Offset +: ${part_name_camel}Size]); - % else: - unused ^= ^{part_init_done[${part_name_camel}Idx], - part_buf_data[${part_name_camel}Offset +: ${part_name_camel}Size]}; - % endif -% endfor - otp_broadcast.valid = lc_ctrl_pkg::lc_tx_bool_to_lc_tx(valid); - return otp_broadcast; - endfunction : named_broadcast_assign - - function automatic otp_keymgr_key_t named_keymgr_key_assign( - logic [NumPart-1:0][ScrmblBlockWidth-1:0] part_digest, - logic [$bits(PartInvDefault)/8-1:0][7:0] part_buf_data, - lc_ctrl_pkg::lc_tx_t lc_seed_hw_rd_en); - otp_keymgr_key_t otp_keymgr_key; - logic valid, unused; - unused = 1'b0; - // For now we use a fixed struct type here so that the - // interface to the keymgr remains stable. The type contains - // a superset of all options, so we have to initialize it to '0 here. - otp_keymgr_key = '0; -% for part in otp_mmap.config["partitions"]: - // ${part["name"]} -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - % if part["iskeymgr_creator"] or part["iskeymgr_owner"]: - valid = (part_digest[${part_name_camel}Idx] != 0); - % for item in part["items"]: -<% - item_name = Name.from_snake_case(item["name"]) - item_name_camel = item_name.as_camel_case() -%>\ - % if item["iskeymgr_creator"] or item["iskeymgr_owner"]: - otp_keymgr_key.${item["name"].lower()}_valid = valid; - if (lc_ctrl_pkg::lc_tx_test_true_strict(lc_seed_hw_rd_en)) begin - otp_keymgr_key.${item["name"].lower()} = - part_buf_data[${item_name_camel}Offset +: ${item_name_camel}Size]; - end else begin - otp_keymgr_key.${item["name"].lower()} = - PartInvDefault[${item_name_camel}Offset*8 +: ${item_name_camel}Size*8]; - end - % else: - % if not item["isdigest"]: - unused ^= ^part_buf_data[${item_name_camel}Offset +: ${item_name_camel}Size]; - % endif - % endif - % endfor - // This is not used since we consume the - // ungated digest values from the part_digest array. - unused ^= ^part_buf_data[${part_name_camel}DigestOffset +: ${part_name_camel}DigestSize]; - % else: - unused ^= ^{part_digest[${part_name_camel}Idx], - part_buf_data[${part_name_camel}Offset +: ${part_name_camel}Size]}; - % endif -% endfor - unused ^= valid; - return otp_keymgr_key; - endfunction : named_keymgr_key_assign - -endpackage : otp_ctrl_part_pkg diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_scoreboard.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_scoreboard.sv.tpl deleted file mode 100644 index 787611dc40d97..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_scoreboard.sv.tpl +++ /dev/null @@ -1,1476 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name - -read_locked_csr_parts = [part for part in otp_mmap.config["partitions"] if - part["read_lock"] == "CSR"] -write_locked_digest_parts = [part for part in otp_mmap.config["partitions"] if - part["write_lock"] == "Digest"] -buf_parts_without_lc = [part for part in otp_mmap.config["partitions"] if - part["variant"] == "Buffered"] -secret_parts = [part for part in otp_mmap.config["partitions"] if - part["secret"]] -## Partitions + LCI + DAI -num_err_code = len(otp_mmap.config["partitions"]) + 2 -%>\ -class otp_ctrl_scoreboard #(type CFG_T = otp_ctrl_env_cfg) - extends cip_base_scoreboard #( - .CFG_T(CFG_T), - .RAL_T(otp_ctrl_core_reg_block), - .COV_T(otp_ctrl_env_cov) - ); - `uvm_component_param_utils(otp_ctrl_scoreboard #(CFG_T)) - - // local variables - bit [TL_DW-1:0] otp_a [OTP_ARRAY_SIZE]; - - // lc_state and lc_cnt that stored in OTP - bit [LC_PROG_DATA_SIZE-1:0] otp_lc_data; - bit [EDN_BUS_WIDTH-1:0] edn_data_q[$]; - - // This flag is used when reset is issued during otp dai write access. - bit dai_wr_ip; - int dai_digest_ip = LifeCycleIdx; // Default to LC as it does not have digest. - bit ignore_digest_chk = 0; - - // This bit is used for DAI interface to mark if the read access is valid. - bit dai_read_valid; - - // This captures the regwen state as configured by the SW side (i.e. without HW modulation - // with the idle signal overlaid). - bit direct_access_regwen_state = 1; - - // ICEBOX(#17798): currently scb will skip checking the readout value if the ECC error is - // uncorrectable. Because if the error is uncorrectable, current scb does not track all the - // backdoor injected values. - // This issue proposes to track the otp_memory_array in mem_bkdr_if and once backdoor inject any - // value, mem_bkdr_if will update its otp_memory_array. - bit check_dai_rd_data = 1; - - // Status related variables - bit under_chk, under_dai_access; - bit [TL_DW-1:0] exp_status, status_mask; - - otp_alert_e exp_alert = OtpNoAlert; - - // TLM agent fifos - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(SRAM_DATA_SIZE))) - sram_fifos[NumSramKeyReqSlots]; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(OTBN_DATA_SIZE))) otbn_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE))) flash_addr_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE))) flash_data_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE))) - lc_prog_fifo; - - // local queues to hold incoming packets pending comparison - - `uvm_component_new - - function void build_phase(uvm_phase phase); - super.build_phase(phase); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - sram_fifos[i] = new($sformatf("sram_fifos[%0d]", i), this); - end - otbn_fifo = new("otbn_fifo", this); - flash_addr_fifo = new("flash_addr_fifo", this); - flash_data_fifo = new("flash_data_fifo", this); - lc_prog_fifo = new("lc_prog_fifo", this); - endfunction - - function void connect_phase(uvm_phase phase); - super.connect_phase(phase); - endfunction - - task run_phase(uvm_phase phase); - super.run_phase(phase); - fork - process_wipe_mem(); - process_otp_power_up(); - process_lc_esc(); - process_lc_prog_req(); - process_edn_req(); - check_otbn_rsp(); - check_flash_rsps(); - check_sram_rsps(); - recover_lc_prog_req(); - join_none - endtask - - // Once sequence uses backdoor method to clear memory, this task resets internal otp_a and - // resets `cfg.backdoor_clear_mem` to 0. - virtual task process_wipe_mem(); - forever begin - @(posedge cfg.backdoor_clear_mem) begin - bit [SCRAMBLE_DATA_SIZE-1:0] data; - otp_a = '{default:0}; - otp_lc_data = '{default:0}; -% for part in secret_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - // secret partitions have been scrambled before writing to OTP. - // here calculate the pre-srambled raw data when clearing internal OTP to all 0s. - data = descramble_data(0, ${part_name_camel}Idx); - for (int i = ${part_name_camel}Offset / TL_SIZE; - i <= ${part_name_camel}DigestOffset / TL_SIZE - 1; - i++) begin - otp_a[i] = ((i - ${part_name_camel}Offset / TL_SIZE) % 2) ? - data[SCRAMBLE_DATA_SIZE-1:TL_DW] : data[TL_DW-1:0]; - end -% endfor - `uvm_info(`gfn, "clear internal memory and digest", UVM_HIGH) - cfg.backdoor_clear_mem = 0; - dai_wr_ip = 0; - dai_digest_ip = LifeCycleIdx; - end - end - endtask - - // This task process the following logic in during otp_power_up: - // 1. After reset deasserted, otp access is locked until pwr_otp_done_o is set - // 2. After reset deasserted, if power otp_init request is on, and if testbench uses backdoor to - // clear OTP memory to all zeros, clear all digests and re-calculate secret partitions - virtual task process_otp_power_up(); - forever begin - wait (cfg.en_scb); - @(posedge cfg.otp_ctrl_vif.pwr_otp_done_o || cfg.under_reset || - cfg.otp_ctrl_vif.alert_reqs) begin - if (!cfg.under_reset && !cfg.otp_ctrl_vif.alert_reqs && cfg.en_scb) begin - otp_ctrl_part_pkg::otp_hw_cfg0_data_t exp_hw_cfg0_data; - otp_ctrl_part_pkg::otp_hw_cfg1_data_t exp_hw_cfg1_data; - otp_ctrl_pkg::otp_keymgr_key_t exp_keymgr_data; - otp_ctrl_pkg::otp_lc_data_t exp_lc_data; - bit [otp_ctrl_pkg::KeyMgrKeyWidth-1:0] exp_keymgr_key0, exp_keymgr_key1; - - if (PartInfo[dai_digest_ip].sw_digest || PartInfo[dai_digest_ip].hw_digest) begin - bit [TL_DW-1:0] otp_addr = PART_OTP_DIGEST_ADDRS[dai_digest_ip]; - otp_a[otp_addr] = cfg.mem_bkdr_util_h.read32(otp_addr << 2); - otp_a[otp_addr+1] = cfg.mem_bkdr_util_h.read32((otp_addr << 2) + 4); - dai_digest_ip = LifeCycleIdx; - end - predict_digest_csrs(); - - if (cfg.otp_ctrl_vif.under_error_states() == 0) begin - // Dai access is unlocked because the power init is done - void'(ral.direct_access_regwen.predict(direct_access_regwen_state)); - - // Dai idle is set because the otp init is done - exp_status[OtpDaiIdleIdx] = 1; - end - - // Hwcfg_o gets data from OTP HW cfg partition - exp_hw_cfg0_data = cfg.otp_ctrl_vif.under_error_states() ? - otp_ctrl_part_pkg::PartInvDefault[HwCfg0Offset*8 +: HwCfg0Size*8] : - otp_hw_cfg0_data_t'({<<32 {otp_a[HwCfg0Offset/4 +: HwCfg0Size/4]}}); - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.valid, lc_ctrl_pkg::On) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.hw_cfg0_data, exp_hw_cfg0_data) - - // Hwcfg_o gets data from OTP HW cfg partition - exp_hw_cfg1_data = cfg.otp_ctrl_vif.under_error_states() ? - otp_ctrl_part_pkg::PartInvDefault[HwCfg1Offset*8 +: HwCfg1Size*8] : - otp_hw_cfg1_data_t'({<<32 {otp_a[HwCfg1Offset/4 +: HwCfg1Size/4]}}); - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.valid, lc_ctrl_pkg::On) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.hw_cfg1_data, exp_hw_cfg1_data) - - if (!cfg.otp_ctrl_vif.under_error_states()) begin - // ---------------------- Check lc_data_o output ----------------------------------- - // Because initialization was succesful, the valid should be set and error should be - // reset. - exp_lc_data.valid = 1; - exp_lc_data.error = 0; - - // Secrets and tokens valid signals are depend on whether secret partitions are - // locked. - exp_lc_data.secrets_valid = get_otp_digest_val(Secret2Idx) ? On : Off; - exp_lc_data.test_tokens_valid = get_otp_digest_val(Secret0Idx) ? On : Off; - exp_lc_data.rma_token_valid = get_otp_digest_val(Secret2Idx) ? On : Off; - - // LC output is depend on LC partitions value. - exp_lc_data.count = otp_lc_data[0 +: LcCountWidth]; - exp_lc_data.state = otp_lc_data[LcCountWidth +: LcStateWidth]; - - // Token values are depend on secret partitions value. - exp_lc_data.test_unlock_token = - {<<32 {otp_a[TestUnlockTokenOffset/4 +: TestUnlockTokenSize/4]}}; - exp_lc_data.test_exit_token = - {<<32 {otp_a[TestExitTokenOffset/4 +: TestExitTokenSize/4]}}; - exp_lc_data.rma_token = {<<32 {otp_a[RmaTokenOffset/4 +: RmaTokenSize/4]}}; - - // Check otp_lc_data_t struct by item is easier to debug. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.valid, exp_lc_data.valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.error, exp_lc_data.error) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.state, exp_lc_data.state) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.count, exp_lc_data.count) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.secrets_valid, exp_lc_data.secrets_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_tokens_valid, - exp_lc_data.test_tokens_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_unlock_token, - exp_lc_data.test_unlock_token) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_exit_token, exp_lc_data.test_exit_token) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.rma_token_valid, exp_lc_data.rma_token_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.rma_token, exp_lc_data.rma_token) - - // Check otp_lc_data_t all together in case there is any missed item. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o, exp_lc_data) - - // ---------------------- Check keymgr_key_o output --------------------------------- - // Otp_keymgr outputs creator and owner keys from secret partitions. - // Depends on lc_seed_hw_rd_en_i, it will output the real keys or a constant - exp_keymgr_data = '0; -% for part in otp_mmap.config["partitions"]: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - % if part["iskeymgr_creator"] or part["iskeymgr_owner"]: - % for item in part["items"]: -<% - item_name = Name.from_snake_case(item["name"]) - item_name_camel = item_name.as_camel_case() -%>\ - % if item["iskeymgr_creator"] or item["iskeymgr_owner"]: - exp_keymgr_data.${item["name"].lower()}_valid = get_otp_digest_val(${part_name_camel}Idx) != 0; - if (cfg.otp_ctrl_vif.lc_seed_hw_rd_en_i == lc_ctrl_pkg::On) begin - exp_keymgr_data.${item["name"].lower()} = - {<<32 {otp_a[${item_name_camel}Offset/4 +: ${item_name_camel}Size/4]}}; - end else begin - exp_keymgr_data.${item["name"].lower()} = - PartInvDefault[${item_name_camel}Offset*8 +: ${item_name_camel}Size*8]; - end - // Check otp_keymgr_key_t struct by item is easier to debug. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.keymgr_key_o.${item["name"].lower()}_valid, - exp_keymgr_data.${item["name"].lower()}_valid) - % endif - % endfor - % endif -% endfor - - // Check otp_keymgr_key_t struct all together in case there is any missed item. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.keymgr_key_o, exp_keymgr_data) - - if (cfg.en_cov) begin - cov.keymgr_o_cg.sample(cfg.otp_ctrl_vif.lc_seed_hw_rd_en_i == lc_ctrl_pkg::On, - exp_keymgr_data.creator_root_key_share0_valid); - end - end - end else if (cfg.otp_ctrl_vif.alert_reqs) begin - // Ignore digest CSR check when otp_ctrl initialization is interrupted by fatal errors. - // SCB cannot predict how many partitions already finished initialization and updated - // the digest value to CSRs. - ignore_digest_chk = 1; - end - if (cfg.en_cov) begin - bit [NumPart-2:0] parts_locked; - foreach (parts_locked[i]) parts_locked[i] = (get_otp_digest_val(i) != 0); - cov.power_on_cg.sample(cfg.otp_ctrl_vif.lc_esc_on, parts_locked); - end - end - end - endtask - - // This task monitors internal escalation triggered by two methods: - // 1. Externally lc_escalation_en is set to lc_ctrl_pkg::On. - // 2. Internal fatal alert triggered and all partitions are driven to error states. - virtual task process_lc_esc(); - forever begin - wait(cfg.otp_ctrl_vif.alert_reqs == 1 && cfg.en_scb); - - if (cfg.otp_ctrl_vif.lc_esc_on == 0) `DV_CHECK_NE(exp_alert, OtpNoAlert) - - if (exp_alert != OtpCheckAlert) set_exp_alert("fatal_check_error", 1, 5); - - // If the lc_escalation is triggered by internal fatal alert, wait 2 negedge until status is - // updated internally - if (cfg.otp_ctrl_vif.lc_esc_on == 0) begin - cfg.clk_rst_vif.wait_n_clks(2); - exp_status[OtpCheckPendingIdx] = 0; - exp_status[OtpDaiIdleIdx] = 0; - end else begin - exp_status = '0; - // Only lc_esc_on will set these bits to 1. - exp_status[OtpDerivKeyFsmErrIdx:OtpLfsrFsmErrIdx] = '1; - end - - // Update status bits. - foreach (FATAL_EXP_STATUS[i]) begin - if (FATAL_EXP_STATUS[i]) begin - predict_err(.status_err_idx(otp_status_e'(i)), .err_code(OtpFsmStateError), - .update_esc_err(1)); - end - end - - // Update digest values and direct_access_regwen. - predict_rdata(1, 0, 0); - void'(ral.direct_access_regwen.predict(.value(0), .kind(UVM_PREDICT_READ))); - - // DAI access is locked until reset, so no need to backdoor read otp write value until reset. - - wait(cfg.otp_ctrl_vif.alert_reqs == 0); - end - endtask - - // This task monitors if lc_program req is interrupted by reset. - // If it happens, scb cannot predict how many bits have been written to OTP_CTRL. - // So here we will backdoor read back OTP lc partitions bits. - virtual task recover_lc_prog_req(); - forever begin - wait(cfg.otp_ctrl_vif.lc_prog_req == 1); - wait(cfg.otp_ctrl_vif.lc_prog_req == 0); - // Wait one 1ps to avoid race condition. - #1ps; - if (cfg.otp_ctrl_vif.rst_ni == 0) begin - for (int i = 0; i < LC_PROG_DATA_SIZE/32; i++) begin - otp_lc_data[i*32+:32] = cfg.mem_bkdr_util_h.read32(LifeCycleOffset + i * 4); - end - end - end - endtask - - virtual task process_lc_prog_req(); - forever begin - push_pull_item#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE)) rcv_item; - bit exp_err_bit; - bit [15:0] rcv_words [LC_PROG_DATA_SIZE/16]; - - lc_prog_fifo.get(rcv_item); - - // LCI is updated by OTP word. - rcv_words = {<< 16{rcv_item.h_data}}; - foreach (rcv_words[i]) begin - bit [15:0] curr_word = otp_lc_data[i*16 +: 16]; - if ((curr_word & rcv_words[i]) == curr_word) otp_lc_data[i*16 +: 16] = rcv_words[i]; - else exp_err_bit = 1; - end - - if (exp_err_bit) predict_err(OtpLciErrIdx, OtpMacroWriteBlankError); - else predict_no_err(OtpLciErrIdx); - - // LC program request data is valid means no OTP macro error. - `DV_CHECK_EQ(rcv_item.d_data, exp_err_bit) - - if (cfg.en_cov) cov.lc_prog_cg.sample(exp_err_bit); - end - endtask - - virtual task process_edn_req(); - forever begin - push_pull_item#(.DeviceDataWidth(EDN_DATA_WIDTH)) edn_item; - edn_fifos[0].get(edn_item); - edn_data_q.push_back(edn_item.d_data[EDN_BUS_WIDTH-1:0]); - end - endtask - - virtual task check_otbn_rsp(); - forever begin - push_pull_item#(.DeviceDataWidth(OTBN_DATA_SIZE)) rcv_item; - bit [SCRAMBLE_KEY_SIZE-1:0] edn_key2, edn_key1; - bit [SCRAMBLE_KEY_SIZE-1:0] sram_key; - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - bit [OtbnKeyWidth-1:0] key, exp_key; - bit [OtbnNonceWidth-1:0] nonce, exp_nonce; - bit seed_valid; - bit part_locked; - - otbn_fifo.get(rcv_item); - seed_valid = rcv_item.d_data[0]; - nonce = rcv_item.d_data[1+:OtbnNonceWidth]; - key = rcv_item.d_data[OtbnNonceWidth+1+:OtbnKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - - // seed is valid as long as secret1 is locked - `DV_CHECK_EQ(seed_valid, part_locked, "otbn seed_valid mismatch") - - // If edn_data_q matches the OTBN requested size, check OTBN outputs - if (edn_data_q.size() == NUM_OTBN_EDN_REQ) begin - {exp_nonce, edn_key2, edn_key1} = {<<32{edn_data_q}}; - - // check nonce value - `DV_CHECK_EQ(nonce, exp_nonce, "otbn nonce mismatch") - - // calculate key - sram_key = get_key_from_otp(part_locked, SramDataKeySeedOffset / 4); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key1), - .num_round(2)); - - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key2), - .num_round(2)); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, "otbn key mismatch") - - if (cfg.en_cov) cov.otbn_req_cg.sample(part_locked); - - // If during OTBN key request, the LFSR timer expired and trigger an EDN request to acquire - // two EDN keys, then ignore the OTBN output checking, because scb did not know which EDN - // keys are used for LFSR. - // Thus any edn_data_q size equal to (16+2*N) is exempted from checking. - end else if ((edn_data_q.size() - NUM_OTBN_EDN_REQ) % 2 != 0) begin - `uvm_error(`gfn, $sformatf("Unexpected edn_data_q size (%0d) during OTBN request", - edn_data_q.size())) - end - edn_data_q.delete(); - end - endtask - - virtual task check_flash_rsps(); - for (int i = FlashDataKey; i <= FlashAddrKey; i++) begin - automatic digest_sel_e sel_flash = digest_sel_e'(i); - fork - forever begin - push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE)) rcv_item; - bit [SCRAMBLE_KEY_SIZE-1:0] flash_key; - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - bit [FlashKeyWidth-1:0] key, exp_key; - bit seed_valid, part_locked; - int flash_key_index; - - if (sel_flash == FlashAddrKey) begin - flash_addr_fifo.get(rcv_item); - flash_key_index = FlashAddrKeySeedOffset / 4; - end else begin - flash_data_fifo.get(rcv_item); - flash_key_index = FlashDataKeySeedOffset / 4; - end - seed_valid = rcv_item.d_data[0]; - key = rcv_item.d_data[1+:FlashKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - `DV_CHECK_EQ(seed_valid, part_locked, - $sformatf("flash %0s seed_valid mismatch", sel_flash.name())) - - // calculate key - flash_key = get_key_from_otp(part_locked, flash_key_index); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[sel_flash]), - .key(flash_key), - .final_const(RndCnstDigestConst[sel_flash])); - - flash_key = get_key_from_otp(part_locked, flash_key_index + 4); - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[sel_flash]), - .key(flash_key), - .final_const(RndCnstDigestConst[sel_flash])); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, $sformatf("flash %s key mismatch", sel_flash.name())) - - if (cfg.en_cov) cov.flash_req_cg.sample(sel_flash, part_locked); - end - join_none; - end - endtask - - virtual task check_sram_rsps(); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - automatic int index = i; - fork - forever begin - push_pull_item#(.DeviceDataWidth(SRAM_DATA_SIZE)) rcv_item; - sram_key_t key, exp_key; - sram_nonce_t nonce, exp_nonce; - bit seed_valid, part_locked; - bit [SCRAMBLE_KEY_SIZE-1:0] edn_key2, edn_key1; - bit [SCRAMBLE_KEY_SIZE-1:0] sram_key; // key used as input to present algo - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - - sram_fifos[index].get(rcv_item); - seed_valid = rcv_item.d_data[0]; - nonce = rcv_item.d_data[1+:SramNonceWidth]; - key = rcv_item.d_data[SramNonceWidth+1+:SramKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - - // seed is valid as long as secret1 is locked - `DV_CHECK_EQ(seed_valid, part_locked, $sformatf("sram_%0d seed_valid mismatch", index)) - - // If edn_data_q matches the OTBN requested size, check OTBN outputs - if (edn_data_q.size() == NUM_SRAM_EDN_REQ) begin - {exp_nonce, edn_key2, edn_key1} = {<<32{edn_data_q}}; - - // check nonce value - `DV_CHECK_EQ(nonce, exp_nonce, $sformatf("sram_%0d nonce mismatch", index)) - - // calculate key - sram_key = get_key_from_otp(part_locked, SramDataKeySeedOffset / 4); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key1), - .num_round(2)); - - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key2), - .num_round(2)); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, $sformatf("sram_%0d key mismatch", index)) - if (cfg.en_cov) cov.sram_req_cg.sample(index, part_locked); - - end else if ((edn_data_q.size() - NUM_SRAM_EDN_REQ) % 2 != 0) begin - `uvm_error(`gfn, $sformatf("Unexpected edn_data_q size (%0d) during SRAM request", - edn_data_q.size())) - end - edn_data_q.delete(); - end - join_none - end - endtask - - virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); - bit write = item.is_write(); - uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - bit [TL_AW-1:0] addr_mask = ral.get_addr_mask(); - - bit addr_phase_read = (!write && channel == AddrChannel); - bit addr_phase_write = (write && channel == AddrChannel); - bit data_phase_read = (!write && channel == DataChannel); - bit data_phase_write = (write && channel == DataChannel); - - if (ral_name != "otp_ctrl_prim_reg_block") begin - process_core_tl_access(item, csr_addr, ral_name, addr_mask, - addr_phase_read, addr_phase_write, data_phase_read, data_phase_write); - end else begin - process_prim_tl_access(item, csr_addr, ral_name, addr_phase_write, data_phase_read); - end - endtask - - virtual function void process_prim_tl_access(tl_seq_item item, uvm_reg_addr_t csr_addr, - string ral_name, bit addr_phase_write, bit data_phase_read); - - uvm_reg csr; - dv_base_reg dv_reg; - csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr); - `DV_CHECK_NE_FATAL(csr, null) - `downcast(dv_reg, csr) - - if (addr_phase_write) begin - void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); - end else if (data_phase_read) begin - `DV_CHECK_EQ((csr.get_mirrored_value() | status_mask), (item.d_data | status_mask), - $sformatf("reg name: status, compare_mask %0h", status_mask)) - end - endfunction - - virtual function void process_core_tl_access(tl_seq_item item, uvm_reg_addr_t csr_addr, - string ral_name, bit [TL_AW-1:0] addr_mask, bit addr_phase_read, bit addr_phase_write, - bit data_phase_read, bit data_phase_write); - - bit do_read_check = 1; - uvm_reg csr; - dv_base_reg dv_reg; - string csr_name; - - `uvm_info(`gfn, $sformatf("sw state %d, reg state %d", direct_access_regwen_state, - `gmv(ral.direct_access_regwen)), UVM_LOW); - - // if access was to a valid csr, get the csr handle - if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin - csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr); - `DV_CHECK_NE_FATAL(csr, null) - `downcast(dv_reg, csr) - // SW CFG window - end else if ((csr_addr & addr_mask) inside - {[SW_WINDOW_BASE_ADDR : SW_WINDOW_BASE_ADDR + SW_WINDOW_SIZE]}) begin - if (data_phase_read) begin - bit [TL_AW-1:0] dai_addr = (csr_addr & addr_mask - SW_WINDOW_BASE_ADDR); - bit [TL_AW-1:0] otp_addr = dai_addr >> 2; - int part_idx = get_part_index(dai_addr); - bit [TL_DW-1:0] read_out; - int ecc_err = OtpNoEccErr; - - // We can't get an ECC error if the partition does not have integrity. - if (part_has_integrity(part_idx)) begin - ecc_err = read_a_word_with_ecc(dai_addr, read_out); - end else begin - ecc_err = read_a_word_with_ecc_raw(dai_addr, read_out); - end - - if (part_has_digest(part_idx) && cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[part_idx].sample(.read_lock(0), - .write_lock(get_digest_reg_val(part_idx) != 0), .is_write(0)); - end - - // Any alert that indicates the OTP block is in the final error state should not enter the - // logic here, but gated at `is_tl_mem_access_allowed` function. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.alert_reqs, 0) - - // ECC uncorrectable errors are gated by `is_tl_mem_access_allowed` function. - if (ecc_err != OtpNoEccErr && part_has_integrity(part_idx)) begin - - predict_err(otp_status_e'(part_idx), OtpMacroEccCorrError); - if (ecc_err == OtpEccCorrErr) begin - `DV_CHECK_EQ(item.d_data, otp_a[otp_addr], - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - end else begin - // Only check the first 16 bits because if ECC readout detects uncorrectable error, it - // won't continue read the remaining 16 bits. - `DV_CHECK_EQ(item.d_data & 16'hffff, read_out & 16'hffff, - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - end - // If there is an injected error, but the partition cannot detect it, we have to compare - // to the value read via the backdoor instead of otp_a[otp_addr] since otherwise the - // perturbed value does not get modelled correctly. - end else if (ecc_err != OtpNoEccErr && !part_has_integrity(part_idx)) begin - `DV_CHECK_EQ(item.d_data, read_out, - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - predict_no_err(otp_status_e'(part_idx)); - end else if (ecc_err == OtpNoEccErr) begin - `DV_CHECK_EQ(item.d_data, otp_a[otp_addr], - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - predict_no_err(otp_status_e'(part_idx)); - end - end - return; - end else begin - `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr)) - end - - csr_name = csr.get_name(); - - if (addr_phase_write) begin - if (cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs && csr_name == "direct_access_cmd") begin - cov.req_dai_access_after_alert_cg.sample(item.a_data); - end - - // Skip predict if the register is locked by `direct_access_regwen`. - // An exception is the direct_access_regwen which may always be written. - if (ral.direct_access_regwen.locks_reg_or_fld(dv_reg) && - `gmv(ral.direct_access_regwen) == 0 && - csr_name != "direct_access_regwen") return; - - void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); - end - - // process the csr req - // for write, update local variable and fifo at address phase - // for read, update predication at address phase and compare at data phase - case (csr_name) - // add individual case item for each csr - "intr_state": begin - if (data_phase_read) begin - // Disable intr_state checking when lc_program is in progress, because scb cannot - // accurately predict when program_error will be triggered. - // We will check the intr_state after lc_program request is done, and the error bit will - // be checked in the `process_lc_prog_req` task. - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check) do_read_check = 0; - if (do_read_check) begin - bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); - bit [NumOtpCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state); - - foreach (intr_exp[i]) begin - otp_intr_e intr = otp_intr_e'(i); - `DV_CHECK_CASE_EQ(cfg.intr_vif.pins[i], (intr_en[i] & intr_exp[i]), - $sformatf("Interrupt_pin: %0s", intr.name)); - if (cfg.en_cov) begin - cov.intr_cg.sample(i, intr_en[i], item.d_data[i]); - cov.intr_pins_cg.sample(i, cfg.intr_vif.pins[i]); - end - end - end - end - end - "intr_test": begin - if (addr_phase_write) begin - bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); - bit [NumOtpCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state) | item.a_data; - - void'(ral.intr_state.predict(.value(intr_exp))); - if (cfg.en_cov) begin - foreach (intr_exp[i]) begin - cov.intr_test_cg.sample(i, item.a_data[i], intr_en[i], intr_exp[i]); - end - end - end - end - "direct_access_cmd": begin - if (addr_phase_write && !cfg.otp_ctrl_vif.under_error_states()) begin - // here only normalize to 2 lsb, if is secret, will be reduced further - bit [TL_AW-1:0] dai_addr = normalize_dai_addr(`gmv(ral.direct_access_address)); - int part_idx = get_part_index(dai_addr); - bit sw_read_lock = 0; - void'(ral.direct_access_regwen.predict(0)); - under_dai_access = 1; - - // Check if it is sw partition read lock - this can be used in `DaiRead` branch and also - // coverage collection. -% for part in read_locked_csr_parts: -<% part_name = Name.from_snake_case(part["name"]) %>\ - % if loop.first: - if (part_idx == ${part_name.as_camel_case()}Idx) begin - % else: - end else if (part_idx == ${part_name.as_camel_case()}Idx) begin - % endif - sw_read_lock = `gmv(ral.${part_name.as_snake_case()}_read_lock) == 0; - % if loop.last: - end - %endif -% endfor - - // LC partition cannot be access via DAI - if (part_idx == LifeCycleIdx) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - if (item.a_data == DaiRead) predict_rdata(is_secret(dai_addr), 0, 0); - end else begin - // Collect coverage. - if (cfg.en_cov) begin - if (part_idx == Secret2Idx) begin - cov.dai_access_secret2_cg.sample( - !(cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On), - dai_cmd_e'(item.a_data)); - end else if (is_sw_part_idx(part_idx) && part_has_digest(part_idx) && - item.a_data inside {DaiRead, DaiWrite}) begin - cov.unbuf_access_lock_cg_wrap[part_idx].sample(.read_lock(sw_read_lock), - .write_lock(get_digest_reg_val(part_idx) != 0), - .is_write(item.a_data == DaiWrite)); - - end - end - - case (item.a_data) - DaiDigest: cal_digest_val(part_idx); - DaiRead: begin - // Check if it is sw partition read lock - check_dai_rd_data = 1; - - // SW partitions write read_lock_csr can lock read access. - if (sw_read_lock || - // Secret partitions cal digest can also lock read access. - // However, digest is always readable except SW partitions (Issue #5752). - (is_secret(dai_addr) && get_digest_reg_val(part_idx) != 0 && - !is_digest(dai_addr)) || - // If the partition has creator key material and lc_creator_seed_sw_rw is - // disable, then return access error. - (PartInfo[part_idx].iskeymgr_creator && !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), 0, 0); - end else if (sw_read_lock || - // Secret partitions cal digest can also lock read access. - // However, digest is always readable except SW partitions (Issue #5752). - (is_secret(dai_addr) && get_digest_reg_val(part_idx) != 0 && - !is_digest(dai_addr)) || - // If the partition has owner key material and lc_owner_seed_sw_rw is disable, - // then return access error. - (PartInfo[part_idx].iskeymgr_owner && !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), 0, 0); - - end else begin - bit [TL_DW-1:0] read_out0, read_out1; - bit [TL_AW-1:0] otp_addr = get_scb_otp_addr(); - int ecc_err = 0; - - // Backdoor read to check if there is any ECC error. - if (part_has_integrity(part_idx)) begin - ecc_err = read_a_word_with_ecc(dai_addr, read_out0); - if (is_secret(dai_addr) || is_digest(dai_addr)) begin - ecc_err = max2(read_a_word_with_ecc(dai_addr + 4, read_out1), ecc_err); - end - end else begin - ecc_err = read_a_word_with_ecc_raw(dai_addr, read_out0); - if (is_secret(dai_addr) || is_digest(dai_addr)) begin - ecc_err = max2(read_a_word_with_ecc_raw(dai_addr + 4, read_out1), ecc_err); - end - end - - if (ecc_err == OtpEccCorrErr && part_has_integrity(part_idx)) begin - predict_err(OtpDaiErrIdx, OtpMacroEccCorrError); - backdoor_update_otp_array(dai_addr); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - otp_a[otp_addr], otp_a[otp_addr+1]); - end else if (ecc_err == OtpEccUncorrErr && part_has_integrity(part_idx)) begin - predict_err(OtpDaiErrIdx, OtpMacroEccUncorrError); - // Max wait 20 clock cycles because scb did not know when exactly OTP will - // finish reading and reporting the uncorrectable error. - set_exp_alert("fatal_macro_error", 1, 20); - predict_rdata(1, 0, 0); - // Some partitions do not interpret/report ECC errors. In those cases - // we still need to model the read data correctly if it has been perturbed. - end else if (ecc_err inside {OtpEccCorrErr, OtpEccUncorrErr} && - !part_has_integrity(part_idx)) begin - predict_no_err(OtpDaiErrIdx); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - read_out0, read_out1); - // do not check direct_access_rdata_* on ECC errors in - // non-integrity partitions - check_dai_rd_data = 0; - end else begin - predict_no_err(OtpDaiErrIdx); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - otp_a[otp_addr], otp_a[otp_addr+1]); - end - end - end - DaiWrite: begin - bit[TL_AW-1:0] otp_addr = get_scb_otp_addr(); - bit is_write_locked; - // check if write locked - if (part_has_digest(part_idx)) begin - is_write_locked = get_digest_reg_val(part_idx) != 0; - end else begin - is_write_locked = 0; - end - - if (is_write_locked || (PartInfo[part_idx].iskeymgr_creator && - !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - end else if (is_write_locked || (PartInfo[part_idx].iskeymgr_owner && - !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - end else begin - predict_no_err(OtpDaiErrIdx); - // write digest - if (is_sw_digest(dai_addr)) begin - bit [TL_DW*2-1:0] curr_digest, prev_digest; - curr_digest = {`gmv(ral.direct_access_wdata[1]), - `gmv(ral.direct_access_wdata[0])}; - prev_digest = {otp_a[otp_addr+1], otp_a[otp_addr]}; - dai_wr_ip = 1; - // allow bit write - if ((prev_digest & curr_digest) == prev_digest) begin - update_digest_to_otp(part_idx, curr_digest); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end else if (is_digest(dai_addr)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - // write OTP memory - end else begin - dai_wr_ip = 1; - if (!is_secret(dai_addr)) begin - bit [TL_DW-1:0] wr_data = `gmv(ral.direct_access_wdata[0]); - // allow bit write - if ((otp_a[otp_addr] & wr_data) == otp_a[otp_addr]) begin - otp_a[otp_addr] = wr_data; - check_otp_idle(.val(0), .wait_clks(3)); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end else begin - bit [SCRAMBLE_DATA_SIZE-1:0] secret_data = {otp_a[otp_addr + 1], - otp_a[otp_addr]}; - bit [SCRAMBLE_DATA_SIZE-1:0] wr_data = {`gmv(ral.direct_access_wdata[1]), - `gmv(ral.direct_access_wdata[0])}; - wr_data = scramble_data(wr_data, part_idx); - secret_data = scramble_data(secret_data, part_idx); - if ((secret_data & wr_data) == secret_data) begin - otp_a[otp_addr] = `gmv(ral.direct_access_wdata[0]); - otp_a[otp_addr + 1] = `gmv(ral.direct_access_wdata[1]); - // wait until secret scrambling is done - check_otp_idle(.val(0), .wait_clks(34)); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end - end - end - end - default: begin - `uvm_fatal(`gfn, $sformatf("invalid cmd: %0d", item.a_data)) - end - endcase - // regwen is set to 0 only if the dai operation is successfully - if (`gmv(ral.intr_state.otp_error) == 0) void'(ral.direct_access_regwen.predict(0)); - end - end - end - "status": begin - if (addr_phase_read) begin - void'(ral.status.predict(.value(exp_status), .kind(UVM_PREDICT_READ))); - - // update status mask - status_mask = 0; - // Mask out check_pending field - we do not know how long it takes to process checks. - // Check failure can trigger all kinds of errors. - if (under_chk) status_mask = '1; - - // Mask out otp_dai access related field - we do not know how long it takes to finish - // DAI access. - if (under_dai_access) begin - status_mask[OtpDaiIdleIdx] = 1; - status_mask[OtpDaiErrIdx] = 1; - end - - // Mask out LCI error bit if lc_req is set. - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check) status_mask[OtpLciErrIdx] = 1; - - end else if (data_phase_read) begin - if (cfg.en_cov) begin - cov.collect_status_cov(item.d_data); - if (cfg.otp_ctrl_vif.alert_reqs) begin - cov.csr_rd_after_alert_cg_wrap.sample(csr.get_offset()); - end - end - - if (item.d_data[OtpDaiIdleIdx]) begin - check_otp_idle(1); - dai_wr_ip = 0; - dai_digest_ip = LifeCycleIdx; - end - - // STATUS register check with mask - if (do_read_check) begin - `DV_CHECK_EQ((csr.get_mirrored_value() | status_mask), (item.d_data | status_mask), - $sformatf("reg name: status, compare_mask %0h", status_mask)) - end - - // Check if OtpCheckPending is set correctly, then ignore checking until check is done - if (under_chk) begin - if (item.d_data[OtpCheckPendingIdx] == 0) begin - exp_status[OtpCheckPendingIdx] = 0; - under_chk = 0; - end - end - - if (under_dai_access && !cfg.otp_ctrl_vif.under_error_states()) begin - if (item.d_data[OtpDaiIdleIdx]) begin - under_dai_access = 0; - void'(ral.direct_access_regwen.predict(direct_access_regwen_state)); - void'(ral.intr_state.otp_operation_done.predict(1)); - end - end - end - // checked in this block above - do_read_check = 0; - end - "check_trigger": begin - if (addr_phase_write && cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs) begin - cov.issue_checks_after_alert_cg.sample(item.a_data); - end - - if (addr_phase_write && `gmv(ral.check_trigger_regwen) && item.a_data inside {[1:3]}) begin - bit [TL_DW-1:0] check_timeout = `gmv(ral.check_timeout) == 0 ? '1 : - `gmv(ral.check_timeout); - exp_status[OtpCheckPendingIdx] = 1; - under_chk = 1; - if (check_timeout <= CHK_TIMEOUT_CYC) begin - set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout)); - predict_err(OtpTimeoutErrIdx); - end else begin - if (get_field_val(ral.check_trigger.consistency, item.a_data)) begin - foreach (cfg.ecc_chk_err[i]) begin - if (cfg.ecc_chk_err[i] == OtpEccCorrErr && part_has_integrity(i)) begin - predict_err(otp_status_e'(i), OtpMacroEccCorrError); - end else if (cfg.ecc_chk_err[i] == OtpEccUncorrErr && - part_has_integrity(i)) begin - set_exp_alert("fatal_macro_error", 1, 40_000); - predict_err(otp_status_e'(i), OtpMacroEccUncorrError); - end - end - end - end - end - end - "direct_access_regwen": begin - if (addr_phase_write) begin - // This locks the DAI until the next reset. - if (!item.a_data[0]) begin - direct_access_regwen_state = 0; - void'(ral.direct_access_regwen.predict(0)); - end - end - end - // For error codes, if lc_prog in progress, err_code might update anytime in DUT. Ignore - // checking until req is acknowledged. - -% for k in range(num_err_code): -<% - # This code should depend on whether the error code is compact. This - # assumes it is not compact. -%>\ - "err_code_${k}": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(${k}, item.d_data, access_part_idx); - end - end -% endfor -% for part in write_locked_digest_parts: -<% part_name_snake = Name.from_snake_case(part["name"]).as_snake_case() %>\ - "${part_name_snake}_digest_0", "${part_name_snake}_digest_1"${": begin" if loop.last else ","} -% endfor - if (ignore_digest_chk) do_read_check = 0; - end -% for part in read_locked_csr_parts: -<% part_name_snake = Name.from_snake_case(part["name"]).as_snake_case() %>\ - "${part_name_snake}_read_lock", -% endfor - "direct_access_wdata_0", - "direct_access_wdata_1", - "direct_access_address", - "check_regwen", - "check_trigger_regwen", - "check_trigger", - "check_timeout", - "intr_enable", - "integrity_check_period", - "consistency_check_period", - "alert_test": begin - // Do nothing - end - // DAI read data - "direct_access_rdata_0", "direct_access_rdata_1": do_read_check = check_dai_rd_data; - default: begin - `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name())) - end - endcase - - // On reads, if do_read_check, is set, then check mirrored_value against item.d_data - if (data_phase_read) begin - if (do_read_check) begin - `DV_CHECK_EQ(csr.get_mirrored_value(), item.d_data, - $sformatf("reg name: %0s", csr.get_full_name())) - if (cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs) begin - cov.csr_rd_after_alert_cg_wrap.sample(csr.get_offset()); - end - end - void'(csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ))); - end - endfunction - - // If reset or lc_escalate_en is issued during otp program, this function will backdoor update - // otp memory write value because scb did not know how many cells haven been written. - // We won't update csr `direct_access_address` after fatal alert happened, so in this function - // we can directly call method `get_scb_otp_addr` to get the interrupted dai address. - virtual function void recover_interrupted_op(); - if (dai_wr_ip) begin - bit [TL_DW-1:0] otp_addr = get_scb_otp_addr(); - bit [TL_DW-1:0] dai_addr = otp_addr << 2; - backdoor_update_otp_array(dai_addr); - dai_wr_ip = 0; - end - endfunction - - virtual function void backdoor_update_otp_array(bit [TL_DW-1:0] dai_addr); - bit [TL_DW-1:0] otp_addr = dai_addr >> 2; - bit [TL_DW-1:0] readout_word, readout_word1; - int part_idx = get_part_index(dai_addr); - if (part_has_integrity(part_idx)) begin - void'(read_a_word_with_ecc(dai_addr, readout_word)); - void'(read_a_word_with_ecc(dai_addr + 4, readout_word1)); - end else begin - void'(read_a_word_with_ecc_raw(dai_addr, readout_word)); - void'(read_a_word_with_ecc_raw(dai_addr + 4, readout_word1)); - end - - otp_a[otp_addr] = readout_word; - - if (is_digest(dai_addr)) begin - otp_a[otp_addr+1] = readout_word1; - end else if (is_secret(dai_addr)) begin - bit [TL_DW*2-1:0] mem_rd_val, descrambled_val; - mem_rd_val = {readout_word1 ,readout_word}; - descrambled_val = descramble_data(mem_rd_val, part_idx); - otp_a[otp_addr+1] = descrambled_val[TL_DW*2-1:TL_DW]; - otp_a[otp_addr] = descrambled_val[TL_DW-1:0]; - end - endfunction - - virtual function bit [1:0] read_a_word_with_ecc(bit [TL_DW-1:0] dai_addr, - ref bit [TL_DW-1:0] readout_word); - prim_secded_pkg::secded_22_16_t ecc_rd_data0 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr); - prim_secded_pkg::secded_22_16_t ecc_rd_data1 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr + 2); - readout_word[15:0] = ecc_rd_data0.data; - readout_word[31:16] = ecc_rd_data1.data; - return max2(ecc_rd_data0.err, ecc_rd_data1.err); - endfunction - - // Returns the ECC error but does not correct the data bits (i.e. returns the raw data). - virtual function bit [1:0] read_a_word_with_ecc_raw(bit [TL_DW-1:0] dai_addr, - ref bit [TL_DW-1:0] readout_word); - prim_secded_pkg::secded_22_16_t ecc_rd_data0 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr); - prim_secded_pkg::secded_22_16_t ecc_rd_data1 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr + 2); - readout_word[15:0] = 16'hFFFF & cfg.mem_bkdr_util_h.read(dai_addr); - readout_word[31:16] = 16'hFFFF & cfg.mem_bkdr_util_h.read(dai_addr + 2); - return max2(ecc_rd_data0.err, ecc_rd_data1.err); - endfunction - - - virtual function void reset(string kind = "HARD"); - recover_interrupted_op(); - super.reset(kind); - // flush fifos - otbn_fifo.flush(); - flash_addr_fifo.flush(); - flash_data_fifo.flush(); - lc_prog_fifo.flush(); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - sram_fifos[i].flush(); - end - - direct_access_regwen_state = 1; - under_chk = 0; - under_dai_access = 0; - ignore_digest_chk = 0; - exp_status = `gmv(ral.status); - exp_alert = OtpNoAlert; - - edn_data_q.delete(); - - // Out of reset: lock dai access until power init is done - if (cfg.en_scb) void'(ral.direct_access_regwen.predict(0)); - endfunction - - virtual function void check_otp_idle(bit val, int wait_clks = 0); - fork - begin - fork - begin - // use negedge to avoid race condition - cfg.clk_rst_vif.wait_n_clks(wait_clks + 1); - `uvm_error(`gfn, - $sformatf("pwr_otp_idle output is %0b while expect %0b within %0d cycles", - cfg.otp_ctrl_vif.pwr_otp_idle_o, val, wait_clks)) - end - begin - wait(cfg.under_reset || cfg.otp_ctrl_vif.pwr_otp_idle_o == val || - // Due to OTP access arbitration, any KDI request during DAI access might block - // write secret until KDI request is completed. Since the KDI process time could - // vary depends on the push-pull-agent, we are going to ignore the checking if - // this scenario happens. - cfg.m_otbn_pull_agent_cfg.vif.req || - cfg.m_flash_data_pull_agent_cfg.vif.req || - cfg.m_flash_addr_pull_agent_cfg.vif.req || - cfg.m_sram_pull_agent_cfg[0].vif.req || - cfg.m_sram_pull_agent_cfg[1].vif.req || - cfg.m_sram_pull_agent_cfg[2].vif.req || - cfg.m_sram_pull_agent_cfg[3].vif.req || - cfg.m_lc_prog_pull_agent_cfg.vif.req || - // When lc_escalation is on, the DAI interface goes to ErrorSt, so ignore - // otp_idle checking. - cfg.otp_ctrl_vif.alert_reqs || - // Check timeout will keep doing background check, issue #5616 - exp_status[OtpTimeoutErrIdx]); - end - join_any - disable fork; - end - join_none - endfunction - - // predict digest registers - virtual function void predict_digest_csrs(); -% for part in write_locked_digest_parts: -<% part_name = Name.from_snake_case(part["name"]) %>\ - void'(ral.${part_name.as_snake_case()}_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[${part_name.as_camel_case()}Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.${part_name.as_snake_case()}_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[${part_name.as_camel_case()}Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - % if not loop.last: - - %endif -% endfor - endfunction - - function void update_digest_to_otp(int part_idx, bit [TL_DW*2-1:0] digest); - otp_a[PART_OTP_DIGEST_ADDRS[part_idx]] = digest[31:0]; - otp_a[PART_OTP_DIGEST_ADDRS[part_idx] + 1] = digest[63:32]; - endfunction - - function void check_phase(uvm_phase phase); - super.check_phase(phase); - // post test checks - ensure that all local fifos and queues are empty - endfunction - - // Calculate digest value for each partition - // According to the design spec, the calculation is based on 64-rounds of PRESENT cipher - // The 64-bit data_in state is initialized with a silicon creator constant, and each 128 bit - // chunk of partition data are fed in as keys - // The last 64-round PRESENT calculation will use a global digest constant as key input - function void cal_digest_val(int part_idx); - bit [TL_DW-1:0] mem_q[$]; - int array_size; - bit [SCRAMBLE_DATA_SIZE-1:0] digest; - - if (cfg.otp_ctrl_vif.under_error_states()) return; - - if (!part_has_hw_digest(part_idx) || get_digest_reg_val(part_idx) != 0) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else if (PartInfo[part_idx].iskeymgr_creator && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else if (PartInfo[part_idx].iskeymgr_owner && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else begin - predict_no_err(OtpDaiErrIdx); - dai_digest_ip = part_idx; - end - case (part_idx) -% for part in buf_parts_without_lc: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - ${part_name_camel}Idx: mem_q = otp_a[${part_name_camel}Offset / TL_SIZE : ${part_name_camel}DigestOffset / TL_SIZE - 1]; -% endfor - default: begin - `uvm_fatal(`gfn, $sformatf("Access unexpected partition %0d", part_idx)) - end - endcase - - array_size = mem_q.size(); - - // for secret partitions, need to use otp scrambled value as data input - if (PartInfo[part_idx].secret) begin - bit [TL_DW-1:0] scrambled_mem_q[$]; - for (int i = 0; i < array_size/2; i++) begin - bit [SCRAMBLE_DATA_SIZE-1:0] scrambled_data; - scrambled_data = scramble_data({mem_q[i*2+1], mem_q[i*2]}, part_idx); - scrambled_mem_q.push_back(scrambled_data[TL_DW-1:0]); - scrambled_mem_q.push_back(scrambled_data[SCRAMBLE_DATA_SIZE-1:TL_DW]); - end - mem_q = scrambled_mem_q; - end - - digest = otp_scrambler_pkg::cal_digest(part_idx, mem_q); - update_digest_to_otp(part_idx, digest); - endfunction - - - // this function go through present encode algo two or three iterations: - // first iteration with input key, - // second iteration with second_key, this iteration only happens if num_round is 2 - // third iteration with a final constant as key - // this is mainly used for unlock token hashing, key derivation - virtual function bit [SCRAMBLE_DATA_SIZE-1:0] present_encode_with_final_const( - bit [SCRAMBLE_DATA_SIZE-1:0] data, - bit [SCRAMBLE_KEY_SIZE-1:0] key, - bit [SCRAMBLE_KEY_SIZE-1:0] final_const, - bit [SCRAMBLE_KEY_SIZE-1:0] second_key = '0, - int num_round = 1); - bit [SCRAMBLE_DATA_SIZE-1:0] enc_data; - bit [SCRAMBLE_DATA_SIZE-1:0] intermediate_state; - crypto_dpi_present_pkg::sv_dpi_present_encrypt(data, key, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - // XOR the previous state into the digest result according to the Davies-Meyer scheme. - intermediate_state = data ^ enc_data; - - if (num_round == 2) begin - crypto_dpi_present_pkg::sv_dpi_present_encrypt(intermediate_state, second_key, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - intermediate_state = intermediate_state ^ enc_data; - end else if (num_round > 2) begin - `uvm_fatal(`gfn, $sformatf("does not support num_round: %0d > 2", num_round)) - end - - crypto_dpi_present_pkg::sv_dpi_present_encrypt(intermediate_state, final_const, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - // XOR the previous state into the digest result according to the Davies-Meyer scheme. - present_encode_with_final_const = intermediate_state ^ enc_data; - endfunction - - // Get address for scoreboard's otp_a array from the `direct_access_address` CSR - function bit [TL_DW-1:0] get_scb_otp_addr(); - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address); - get_scb_otp_addr = normalize_dai_addr(dai_addr) >> 2; - endfunction - - // This function predict OTP error related registers: intr_state, status, and err_code - virtual function void predict_err(otp_status_e status_err_idx, - otp_err_code_e err_code = OtpNoError, - bit update_esc_err = 0); - if (cfg.otp_ctrl_vif.under_error_states() && !update_esc_err) return; - - // Update intr_state - void'(ral.intr_state.otp_error.predict(.value(1), .kind(UVM_PREDICT_READ))); - // Update status - exp_status[status_err_idx] = 1; - - // Only first status errors up to the LCI have corresponding err_code - if (status_err_idx <= OtpLciErrIdx) begin - dv_base_reg_field err_code_flds[$]; - if (err_code == OtpNoError) begin - `uvm_error(`gfn, $sformatf("please set status error: %0s error code", status_err_idx.name)) - end - ral.err_code[status_err_idx].get_dv_base_reg_fields(err_code_flds); - - if (`gmv(err_code_flds[0]) inside {OTP_TERMINAL_ERRS}) begin - `uvm_info(`gfn, "terminal error cannot be updated", UVM_HIGH) - end else if (status_err_idx == OtpLciErrIdx && - `gmv(err_code_flds[0]) != OtpNoError) begin - `uvm_info(`gfn, "For LC partition, all errors are terminal error!", UVM_HIGH) - end else begin - void'(err_code_flds[0].predict(.value(err_code), .kind(UVM_PREDICT_READ))); - end - end - - endfunction - - virtual function void predict_no_err(otp_status_e status_err_idx); - if (cfg.otp_ctrl_vif.under_error_states()) return; - - exp_status[status_err_idx] = 0; - if (status_err_idx == OtpDaiErrIdx) exp_status[OtpDaiIdleIdx] = 1; - - if (status_err_idx <= OtpLciErrIdx) begin - dv_base_reg_field err_code_flds[$]; - ral.err_code[status_err_idx].get_dv_base_reg_fields(err_code_flds); - void'(err_code_flds[0].predict(OtpNoError)); - end - endfunction - - virtual function void predict_rdata(bit is_64_bits, bit [TL_DW-1:0] rdata0, - bit [TL_DW-1:0] rdata1 = 0); - void'(ral.direct_access_rdata[0].predict(.value(rdata0), .kind(UVM_PREDICT_READ))); - if (is_64_bits) begin - void'(ral.direct_access_rdata[1].predict(.value(rdata1), .kind(UVM_PREDICT_READ))); - end - endfunction - - // this function retrieves keys (128 bits) from scb's otp_array with a starting address - // if not locked, it will return 0 - // this is mainly used for scrambling key algo - virtual function bit [SCRAMBLE_KEY_SIZE-1:0] get_key_from_otp(bit locked, int start_i); - bit [SCRAMBLE_KEY_SIZE-1:0] key; - if (!locked) return 0; - for (int i = 0; i < 4; i++) key |= otp_a[i + start_i] << (TL_DW * i); - return key; - endfunction - - // The following two methods are all retrieving digest val. - // get_otp_digest_val: is the digest value from OTP memory - // get_digest_reg_val: is the digest value in register. This value is identical to OTP - // memory's digest value after a power cycle reset. - virtual function bit [TL_DW*2-1:0] get_otp_digest_val(int part_idx); - get_otp_digest_val[31:0] = otp_a[PART_OTP_DIGEST_ADDRS[part_idx]]; - get_otp_digest_val[63:32] = otp_a[PART_OTP_DIGEST_ADDRS[part_idx] + 1]; - endfunction - - virtual function bit [TL_DW*2-1:0] get_digest_reg_val(int part_idx); - bit [TL_DW*2-1:0] digest; - case (part_idx) -% for part in write_locked_digest_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_snake = part_name.as_snake_case() -%>\ - ${part_name.as_camel_case()}Idx: begin - digest = {`gmv(ral.${part_name_snake}_digest[1]), - `gmv(ral.${part_name_snake}_digest[0])}; - end -% endfor - default: `uvm_fatal(`gfn, $sformatf("Partition %0d does not have digest", part_idx)) - endcase - return digest; - endfunction - - virtual function bit is_tl_mem_access_allowed(input tl_seq_item item, input string ral_name, - output bit mem_byte_access_err, - output bit mem_wo_err, - output bit mem_ro_err, - output bit custom_err); - - uvm_reg_addr_t addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - bit [TL_AW-1:0] addr_mask = ral.get_addr_mask(); - bit [TL_AW-1:0] dai_addr = (csr_addr & addr_mask - SW_WINDOW_BASE_ADDR); - - bit mem_access_allowed = super.is_tl_mem_access_allowed(item, ral_name, mem_byte_access_err, - mem_wo_err, mem_ro_err, custom_err); - - if (ral_name == "otp_ctrl_prim_reg_block") return mem_access_allowed; - - // Ensure the address is within the memory window range. - // Also will skip checking if memory access is not allowed due to TLUL bus error. - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr : - cfg.ral_models[ral_name].mem_ranges[0].end_addr]} && - mem_access_allowed) begin - - // If sw partition is read locked, then access policy changes from RO to no access -% for part in read_locked_csr_parts: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (`gmv(ral.${part_name.as_snake_case()}_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + ${part_name_camel}Offset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + ${part_name_camel}Offset + - ${part_name_camel}Size - 1]}) begin - predict_err(Otp${part_name_camel}ErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - % if part["write_lock"] == "Digest": - cov.unbuf_access_lock_cg_wrap[${part_name_camel}Idx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(${part_name_camel}Idx) != 0), .is_write(0)); - % else: - // TODO: we should probably create a different covergroup - // for unbuffered partitions without digest. - cov.unbuf_access_lock_cg_wrap[${part_name_camel}Idx].sample(.read_lock(1), - .write_lock(0), .is_write(0)); - % endif - end - return 0; - end - end -% endfor - - // Check ECC uncorrectable fatal error. - if (dai_addr < LifeCycleOffset) begin - int part_idx = get_part_index(dai_addr); - bit [TL_DW-1:0] read_out; - int ecc_err = read_a_word_with_ecc(dai_addr, read_out); - if (ecc_err == OtpEccUncorrErr && part_has_integrity(part_idx)) begin - predict_err(otp_status_e'(part_idx), OtpMacroEccUncorrError); - set_exp_alert("fatal_macro_error", 1, 20); - custom_err = 1; - return 0; - end - end - end - - return mem_access_allowed; - endfunction - - virtual function bit predict_tl_err(tl_seq_item item, tl_channels_e channel, string ral_name); - if (ral_name == "otp_ctrl_prim_reg_block" && - cfg.otp_ctrl_vif.lc_dft_en_i != lc_ctrl_pkg::On) begin - if (channel == DataChannel) begin - `DV_CHECK_EQ(item.d_error, 1, - $sformatf({"On interface %0s, TL item: %0s, access gated by lc_dft_en_i"}, - ral_name, item.sprint(uvm_default_line_printer))) - - // In data read phase, check d_data when d_error = 1. - if (item.d_error && (item.d_opcode == tlul_pkg::AccessAckData)) begin - check_tl_read_value_after_error(item, ral_name); - end - end - return 1; - end - return super.predict_tl_err(item, channel, ral_name); - endfunction - - virtual function void set_exp_alert(string alert_name, bit is_fatal = 0, int max_delay = 0); - exp_alert = alert_name == "fatal_check_error" ? OtpCheckAlert : OtpMacroAlert; - super.set_exp_alert(alert_name, is_fatal, max_delay); - endfunction - -endclass diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_sec_cm_testplan.hjson b/hw/ip/otp_ctrl/data/otp_ctrl_sec_cm_testplan.hjson deleted file mode 100644 index 650a36067a49c..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_sec_cm_testplan.hjson +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Security countermeasures testplan extracted from the IP Hjson using reggen. -// -// This testplan is auto-generated only the first time it is created. This is -// because this testplan needs to be hand-editable. It is possible that these -// testpoints can go out of date if the spec is updated with new -// countermeasures. When `reggen` is invoked when this testplan already exists, -// It checks if the list of testpoints is up-to-date and enforces the user to -// make further manual updates. -// -// These countermeasures and their descriptions can be found here: -// .../otp_ctrl/data/otp_ctrl.hjson -// -// It is possible that the testing of some of these countermeasures may already -// be covered as a testpoint in a different testplan. This duplication is ok - -// the test would have likely already been developed. We simply map those tests -// to the testpoints below using the `tests` key. -// -// Please ensure that this testplan is imported in: -// .../otp_ctrl/data/otp_ctrl_testplan.hjson -{ - testpoints: [ - { - name: sec_cm_bus_integrity - desc: "Verify the countermeasure(s) BUS.INTEGRITY." - stage: V2S - tests: ["otp_ctrl_tl_intg_err"] - } - { - name: sec_cm_secret_mem_scramble - desc: "Verify the countermeasure(s) SECRET.MEM.SCRAMBLE." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_part_mem_digest - desc: "Verify the countermeasure(s) PART.MEM.DIGEST." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_dai_fsm_sparse - desc: "Verify the countermeasure(s) DAI.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_kdi_fsm_sparse - desc: "Verify the countermeasure(s) KDI.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_lci_fsm_sparse - desc: "Verify the countermeasure(s) LCI.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_part_fsm_sparse - desc: "Verify the countermeasure(s) PART.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_scrmbl_fsm_sparse - desc: "Verify the countermeasure(s) SCRMBL.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_timer_fsm_sparse - desc: "Verify the countermeasure(s) TIMER.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_dai_ctr_redun - desc: "Verify the countermeasure(s) DAI.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_kdi_seed_ctr_redun - desc: "Verify the countermeasure(s) KDI_SEED.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_kdi_entropy_ctr_redun - desc: "Verify the countermeasure(s) KDI_ENTROPY.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_lci_ctr_redun - desc: "Verify the countermeasure(s) LCI.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_part_ctr_redun - desc: "Verify the countermeasure(s) PART.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_scrmbl_ctr_redun - desc: "Verify the countermeasure(s) SCRMBL.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_timer_integ_ctr_redun - desc: "Verify the countermeasure(s) TIMER_INTEG.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_timer_cnsty_ctr_redun - desc: "Verify the countermeasure(s) TIMER_CNSTY.CTR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_timer_lfsr_redun - desc: "Verify the countermeasure(s) TIMER.LFSR.REDUN." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_dai_fsm_local_esc - desc: "Verify the countermeasure(s) DAI.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_sec_cm"] - } - { - name: sec_cm_lci_fsm_local_esc - desc: "Verify the countermeasure(s) LCI.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_kdi_fsm_local_esc - desc: "Verify the countermeasure(s) KDI.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_part_fsm_local_esc - desc: "Verify the countermeasure(s) PART.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_macro_errs"] - } - { - name: sec_cm_scrmbl_fsm_local_esc - desc: "Verify the countermeasure(s) SCRMBL.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_timer_fsm_local_esc - desc: "Verify the countermeasure(s) TIMER.FSM.LOCAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_sec_cm"] - } - { - name: sec_cm_dai_fsm_global_esc - desc: "Verify the countermeasure(s) DAI.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_sec_cm"] - } - { - name: sec_cm_lci_fsm_global_esc - desc: "Verify the countermeasure(s) LCI.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_kdi_fsm_global_esc - desc: "Verify the countermeasure(s) KDI.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_part_fsm_global_esc - desc: "Verify the countermeasure(s) PART.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_macro_errs"] - } - { - name: sec_cm_scrmbl_fsm_global_esc - desc: "Verify the countermeasure(s) SCRMBL.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc"] - } - { - name: sec_cm_timer_fsm_global_esc - desc: "Verify the countermeasure(s) TIMER.FSM.GLOBAL_ESC." - stage: V2S - tests: ["otp_ctrl_parallel_lc_esc", "otp_ctrl_sec_cm"] - } - { - name: sec_cm_part_data_reg_integrity - desc: "Verify the countermeasure(s) PART.DATA_REG.INTEGRITY." - stage: V2S - tests: ["otp_ctrl_init_fail"] - } - { - name: sec_cm_part_data_reg_bkgn_chk - desc: "Verify the countermeasure(s) PART.DATA_REG.BKGN_CHK." - stage: V2S - tests: ["otp_ctrl_check_fail"] - } - { - name: sec_cm_part_mem_regren - desc: "Verify the countermeasure(s) PART.MEM.REGREN." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_part_mem_sw_unreadable - desc: "Verify the countermeasure(s) PART.MEM.SW_UNREADABLE." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_part_mem_sw_unwritable - desc: "Verify the countermeasure(s) PART.MEM.SW_UNWRITABLE." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_lc_part_mem_sw_noaccess - desc: "Verify the countermeasure(s) LC_PART.MEM.SW_NOACCESS." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_access_ctrl_mubi - desc: "Verify the countermeasure(s) ACCESS.CTRL.MUBI." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_token_valid_ctrl_mubi - desc: "Verify the countermeasure(s) TOKEN_VALID.CTRL.MUBI." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_lc_ctrl_intersig_mubi - desc: "Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI." - stage: V2S - tests: ["otp_ctrl_dai_lock"] - } - { - name: sec_cm_test_bus_lc_gated - desc: "Verify the countermeasure(s) TEST.BUS.LC_GATED." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_test_tl_lc_gate_fsm_sparse - desc: "Verify the countermeasure(s) TEST_TL_LC_GATE.FSM.SPARSE." - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: sec_cm_direct_access_config_regwen - desc: "Verify the countermeasure(s) DIRECT_ACCESS.CONFIG.REGWEN." - stage: V2S - tests: ["otp_ctrl_regwen"] - } - { - name: sec_cm_check_trigger_config_regwen - desc: "Verify the countermeasure(s) CHECK_TRIGGER.CONFIG.REGWEN." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_check_config_regwen - desc: "Verify the countermeasure(s) CHECK.CONFIG.REGWEN." - stage: V2S - tests: ["otp_ctrl_smoke"] - } - { - name: sec_cm_macro_mem_integrity - desc: "Verify the countermeasure(s) MACRO.MEM.INTEGRITY." - stage: V2S - tests: ["otp_ctrl_macro_errs"] - } - { - name: sec_cm_macro_mem_cm - desc: "Verify the countermeasure(s) MACRO.MEM.CM." - stage: V2S - tests: ["N/A"] - } - ] -} diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_smoke_vseq.sv.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_smoke_vseq.sv.tpl deleted file mode 100644 index 904ff45494ba6..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_smoke_vseq.sv.tpl +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -${gen_comment} -<% -from topgen.lib import Name -%>\ -// smoke test vseq to walk through DAI states and request keys -`define PART_CONTENT_RANGE(i) ${"\\"} - {[PartInfo[``i``].offset : (PartInfo[``i``].offset + PartInfo[``i``].size - DIGEST_SIZE - 1)]} - -class otp_ctrl_smoke_vseq extends otp_ctrl_base_vseq; - `uvm_object_utils(otp_ctrl_smoke_vseq) - - `uvm_object_new - - rand bit do_req_keys, do_lc_trans; - rand bit access_locked_parts; - rand bit rand_wr, rand_rd, rd_sw_tlul_rd; - rand bit [TL_DW-1:0] dai_addr; - rand bit [TL_DW-1:0] wdata0, wdata1; - rand int num_dai_op; - rand otp_ctrl_part_pkg::part_idx_e part_idx; - rand bit check_regwen_val, check_trigger_regwen_val; - rand bit [TL_DW-1:0] check_timeout_val; - rand bit [1:0] check_trigger_val; - rand otp_ecc_err_e ecc_otp_err, ecc_chk_err; - - constraint no_access_err_c {access_locked_parts == 0;} - - // LC partition does not allow DAI access (the LC partition is always the last one) - constraint partition_index_c {part_idx inside {[0:LifeCycleIdx-1]};} - - constraint dai_wr_legal_addr_c { -% for part in otp_mmap.config["partitions"]: -<% - part_name = Name.from_snake_case(part["name"]) - part_name_camel = part_name.as_camel_case() -%>\ - if (part_idx == ${part_name_camel}Idx) - dai_addr inside `PART_CONTENT_RANGE(${part_name_camel}Idx); -% endfor - solve part_idx before dai_addr; - } - - constraint dai_wr_blank_addr_c { - dai_addr % 4 == 0; - if (PartInfo[part_idx].secret) dai_addr % 8 == 0; - } - - constraint num_trans_c { - if (cfg.smoke_test) { - num_trans == 1; - num_dai_op inside {[1:2]}; - } else { - num_trans inside {[1:2]}; - num_dai_op inside {[1:50]}; - } - } - - constraint regwens_c { - check_regwen_val dist {0 :/ 1, 1 :/ 9}; - check_trigger_regwen_val dist {0 :/ 1, 1 :/ 9}; - } - - constraint check_timeout_val_c { - check_timeout_val inside {0, [100_000:'1]}; - } - - constraint ecc_otp_err_c {ecc_otp_err == OtpNoEccErr;} - - constraint ecc_chk_err_c {ecc_chk_err == OtpNoEccErr;} - - constraint apply_reset_during_pwr_init_cycles_c { - apply_reset_during_pwr_init_cycles dist { - [1:5] :/ 4, - [6:2000] :/ 4, - [2001:4000] :/ 2}; - } - - virtual task dut_init(string reset_kind = "HARD"); - if (do_apply_reset) begin - lc_prog_blocking = 1; - super.dut_init(reset_kind); - csr_wr(ral.intr_enable, en_intr); - end - endtask - - virtual task pre_start(); - super.pre_start(); - num_dai_op.rand_mode(0); - check_lc_err(); - endtask - - virtual task check_lc_err(); - fork - forever begin - wait(cfg.otp_ctrl_vif.lc_prog_err == 1); - lc_prog_blocking = 0; - wait(lc_prog_blocking == 1); - end - join_none; - endtask - - task body(); - for (int i = 1; i <= num_trans; i++) begin - bit [TL_DW-1:0] tlul_val; - if (cfg.stop_transaction_generators()) break; - `uvm_info(`gfn, $sformatf("starting seq %0d/%0d", i, num_trans), UVM_LOW) - - // to avoid access locked OTP partions, issue reset and clear the OTP memory to all 0. - if (access_locked_parts == 0) begin - do_otp_ctrl_init = 1; - if (i > 1 && do_dut_init) dut_init(); - // after otp-init done, check status - cfg.clk_rst_vif.wait_clks(1); - if (!cfg.otp_ctrl_vif.lc_esc_on) begin - csr_rd_check(.ptr(ral.status.dai_idle), .compare_value(1)); - end - end - do_otp_ctrl_init = 0; - - `DV_CHECK_RANDOMIZE_FATAL(this) - // set consistency and integrity checks - csr_wr(ral.check_regwen, check_regwen_val); - csr_wr(ral.check_trigger_regwen, check_trigger_regwen_val); - csr_wr(ral.check_timeout, check_timeout_val); - trigger_checks(.val(check_trigger_val), .wait_done(1), .ecc_err(ecc_chk_err)); - - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_rd_locks(); - - // Backdoor write mubi to values that are not true or false. - force_mubi_part_access(); - - if (do_req_keys && !cfg.otp_ctrl_vif.alert_reqs) begin - req_otbn_key(); - req_flash_addr_key(); - req_flash_data_key(); - req_all_sram_keys(); - end - if (do_lc_trans && !cfg.otp_ctrl_vif.alert_reqs) begin - req_lc_transition(do_lc_trans, lc_prog_blocking); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - for (int i = 0; i < num_dai_op; i++) begin - bit [TL_DW-1:0] rdata0, rdata1, backdoor_rd_val; - if (cfg.stop_transaction_generators()) break; - - `DV_CHECK_RANDOMIZE_FATAL(this) - // recalculate part_idx in case some test turn off constraint dai_wr_legal_addr_c - part_idx = part_idx_e'(get_part_index(dai_addr)); - `uvm_info(`gfn, $sformatf("starting dai access seq %0d/%0d with addr %0h in partition %0d", - i, num_dai_op, dai_addr, part_idx), UVM_HIGH) - - // OTP write via DAI - if (rand_wr && !digest_calculated[part_idx]) begin - dai_wr(dai_addr, wdata0, wdata1); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - // Inject ECC error. - if (ecc_otp_err != OtpNoEccErr && dai_addr < LifeCycleOffset) begin - `uvm_info(`gfn, $sformatf("Injecting ecc error %0d at 0x%x", ecc_otp_err, dai_addr), - UVM_HIGH) - backdoor_rd_val = backdoor_inject_ecc_err(dai_addr, ecc_otp_err); - end - - if (rand_rd) begin - // OTP read via DAI, check data in scb - dai_rd(dai_addr, rdata0, rdata1); - end - - // if write sw partitions, check tlul window - if (is_sw_part(dai_addr) && rd_sw_tlul_rd) begin - uvm_reg_addr_t tlul_addr = cfg.ral.get_addr_from_offset(get_sw_window_offset(dai_addr)); - // tlul error rsp is checked in scoreboard - do_otp_rd = 1; - tl_access(.addr(tlul_addr), .write(0), .data(tlul_val), .blocking(1), .check_rsp(0)); - end - - // Backdoor restore injected ECC error, but should not affect fatal alerts. - if (ecc_otp_err != OtpNoEccErr && dai_addr < LifeCycleOffset) begin - `uvm_info(`gfn, $sformatf("Injecting ecc error %0d at 0x%x", ecc_otp_err, dai_addr), - UVM_HIGH) - cfg.mem_bkdr_util_h.write32({dai_addr[TL_DW-3:2], 2'b00}, backdoor_rd_val); - // Wait for two lock cycles to make sure the local escalation error propagates to other - // patitions and err_code reg. - cfg.clk_rst_vif.wait_clks(2); - end - - // Random lock sw partitions - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_rd_locks(); - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_digests(); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(tlul_val)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.status), .value(tlul_val)); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - // Read/write test access memory - otp_test_access(); - - // lock digests - `uvm_info(`gfn, "Trigger HW digest calculation", UVM_HIGH) - cal_hw_digests(); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.status), .value(tlul_val)); - - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - - if ($urandom_range(0, 1)) rd_digests(); - if (do_dut_init) dut_init(); - - // read and check digest in scb - rd_digests(); - - // send request to the interfaces again after partitions are locked - if (do_lc_trans && !cfg.otp_ctrl_vif.alert_reqs) begin - req_lc_transition(do_lc_trans, lc_prog_blocking); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - if (do_req_keys && !cfg.otp_ctrl_vif.alert_reqs && !cfg.smoke_test) begin - req_otbn_key(); - req_flash_addr_key(); - req_flash_data_key(); - req_all_sram_keys(); - end - - end - - endtask : body - -endclass : otp_ctrl_smoke_vseq - -`undef PART_CONTENT_RANGE diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson deleted file mode 100644 index 95b6081b7da89..0000000000000 --- a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - name: "otp_ctrl" - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/mem_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_fsm_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "otp_ctrl_sec_cm_testplan.hjson"] - testpoints: [ - { - name: wake_up - desc: ''' - Wake_up test walks through otp_ctrl's power-on initialization, read, program, and - digest functionalities. - - - drive pwrmgr's request pin to trigger OTP initialization after reset, check status - after OTP initialization - - write all-ones to a random address within OTP partition 0, wait until this operation - completes - - read out the random selected write address, check if the readout value is all-ones - - trigger a digest calculation for a Software partition, check if the OtpError - interrupt is set - - trigger a digest calculation for a non-software partition, expect operation completes - without the OtpError interrupt - - read out secrets through the hardware interfaces - ''' - stage: V1 - tests: ["otp_ctrl_wake_up"] - } - { - name: smoke - desc: ''' - OTP_CTRL smoke test provisions and locks partitions. - - - drive pwrmgr's request pin to trigger OTP initialization after reset, check status - after OTP initialization - - randomly read out keys pertaining to `key_manager`, `flash`, `sram`, `otbn` - - randomly issue LC program request - - write random values to random addresses within each OTP partition - - read out the random selected write addresses, check if the readout values are expected - - during read and write operations, check if direct_access_regwen is correctly set by HW - - perform a system-level reset and check corresponding CSRs are set correctly - - lock all partitions except life_cycle by triggering digest calculations - - read back and verify the digest - - perform a system-level reset to verify the corresponding CSRs exposing the digests - have been populated - - **Checks**: - - Assertion checks to ensure vendor specific I/Os: `otp_vendor_test_status_o`, - `otp_vendor_test_ctrl_i`, `cio_test_o`, and `cio_test_en_o` are connected currently - with `lc_dft_en_i` On and Off. - ''' - stage: V1 - tests: ["otp_ctrl_smoke"] - } - { - name: dai_access_partition_walk - desc: ''' - Similar to UVM's memory walk test, this test ensures every address in each partition - can be accessed successfully via DAI and TLUL interfacs according to its access policy. - ''' - stage: V2 - tests: ["otp_ctrl_partition_walk"] - } - { - name: init_fail - desc: ''' - Based on OTP_CTRL smoke test, this test creates OTP_CTRL's initialization failure: - - write and read OTP memory via DAI interface - - randomly issue DAI digest command to lock HW partitions - - keep writing to OTP memory via DAI interface without asserting reset - - if digests are not locked, backdoor inject ECC correctable or uncorrectable errors - - issue reset and power initialization - - if the injected errors are all correctable errors, disable the `lc_bypass_chk_en` - after LC program request to create an LC partition check failure - - If fatal error is triggered, this test will check: - - OTP initialization failure triggers fatal alert - - `status`, `intr_state`, `err_code` CSRs reflect correct fatal error - - If OTP initialization finished without any fatal error, this test will check: - - OTP initialization finishes with power init output goes to 1 - - `status`, `intr_state`, `err_code` CSRs reflect ECC correctable error - ''' - stage: V2 - tests: ["otp_ctrl_init_fail"] - } - { - name: partition_check - desc: ''' - Randomly program the partition check related CSRs including: - - `check_timeout` - - `integrity_check_period` - - `consistency_check_period` - - `check_trigger` - - Create a failure scenario by randomly picking one of these three methods: - - inject ECC errors into the OTP macro via backdoor - - set the `check_timeout` CSR with a very small value - - write to a random OTP partition after digest is issued but before reset is asserted - - **Checks**: - - the corresponding alerts are triggered - - the error_code register is set correctly - Note that due to limited simulation time, for background checks, this test only write - random value that is less than 20 to the check period. - ''' - stage: V2 - tests: ["otp_ctrl_check_fail", "otp_ctrl_background_chks"] - } - { - name: regwen_during_otp_init - desc: ''' - The `direct_access_regwen` is a RO register which controls the write-enable of other - reigsters. It is not verified by the common CSR tests. HW sets it to 0 when the DAI - interface is busy. - - Stimulus and checks: - - randomly read `direct_access_regwen` and verify that it returns 0 during OTP - initialization - - verify that the writes to the registers controlled by it do not go through during OTP - initialization - ''' - stage: V2 - tests: ["otp_ctrl_regwen"] - } - { - name: partition_lock - desc: ''' - This test will cover two methods of locking read and write: digest calculation and CSR - write. After locking the partitions, issue read or program sequences and check if the - operations are locked correctly, and check if the `AccessError` is set. - ''' - stage: V2 - tests: ["otp_ctrl_dai_lock"] - } - { - name: interface_key_check - desc: ''' - OTP_CTRL will generate keys to `flash`, `sram`, and `otbn` upon their requests. - Based on the DAI access sequence, this test will run key requests sequence in - parallel, and check if correct keys are generated. - ''' - stage: V2 - tests: ["otp_ctrl_parallel_key_req"] - } - { - name: lc_interactions - desc: ''' - Verify the procotols between OTP_CTRL and LC_CTRL. Based on the DAI access sequence, - run the following sequences in parallel: - - - request a LC state transition via the programming interface - - enable the `lc_escalation_en` signal - - **Checks**: - - if the LC program request has `AccessError`, check the LC program response sets - the `error` bit to 1 - - if `lc_escalation_en` is enabled, verify that alert is triggered and OTP_CTRL entered - terminal state - ''' - stage: V2 - tests: ["otp_ctrl_parallel_lc_req", "otp_ctrl_parallel_lc_esc"] - } - { name: otp_dai_errors - desc: ''' - Based on the otp_dai_lock test, this test will randomly run the following OTP errors: - - DAI interface writes non-blank OTP address - - DAI interface accesses LC partition - - DAI interface writes HW digests - - DAI interface writes non-empty memory - - **Checks**: - - `err_code` and `status` CSRs - - `otp_error` interrupt - ''' - stage: V2 - tests: ["otp_ctrl_dai_errs"] - } - { name: otp_macro_errors - desc: ''' - Randomly run the following OTP errors: - - MacroError - - MacroEccCorrError - - MacroEccUncorrError - - **Checks**: - - `err_code` and `status` CSRs - - `otp_error` interrupt - - if the error is unrecoverable, verify that alert is triggered and OTP_CTRL entered - terminal state - ''' - stage: V2 - tests: ["otp_ctrl_macro_errs"] - } - { - name: test_access - desc: ''' - This test checks if the test access to OTP macro is connected correctly. - - **Stimulus and Checks**: - - Write and check read results from the prim_tl_i/o. - - Ensure no error or alert occurs from DUT. - ''' - stage: V2 - tests: ["otp_ctrl_test_access"] - } - { - name: stress_all - desc: ''' - - combine above sequences in one test to run sequentially, except csr sequence - - randomly add reset between each sequence - ''' - stage: V2 - tests: ["{name}_stress_all"] - } - { - name: sec_cm_additional_check - desc: ''' - Verify the outcome of injecting faults to security countermeasures. - - Stimulus: - As mentioned in `prim_count_check`, `prim_fsm_check` and `prim_double_lfsr_check`. - - Checks: - - Check the value of status register according to where the fault is injected. - - Check OTP_CTRL is locked after the fatal fault injection by trying to access OTP_CTRL - via dai, kdi, and lci interfaces. - ''' - stage: V2S - tests: ["otp_ctrl_sec_cm"] - } - { - name: otp_ctrl_low_freq_read - desc: ''' - This test checks if OTP's read operation can operate successfully in a low clock - frequency before the clock is calibrated. - - **Stimulus and Checks**: - - Configure OTP_CTRL's clock to 6MHz low frequency. - - Backdoor write OTP memory. - - Use DAI access to read each memory address and compare if the value is correct. - - If DAI address is in a SW partition, read and check again via TLUL interface. - ''' - stage: V3 - tests: ["otp_ctrl_low_freq_read"] - } - ] - - covergroups: [ - { - name: power_on_cg - desc: '''Covers the following conditions when OTP_CTRL finishes power-on initialization: - - whether `lc_escalation_en` is On - - whether any partition (except life cycle partition) is locked - ''' - } - { - name: flash_req_cg - desc: '''Covers whether secret1 partition is locked during `flash` data or address - request.''' - } - { - name: sram_req_cg - desc: '''Covers whether secret1 partition is locked during all `srams` key request.''' - } - { - name: otbn_req_cg - desc: '''Covers whether secret1 partition is locked during `otbn` key request.''' - } - { - name: lc_prog_cg - desc: '''Covers whether the error bit is set during LC program request.''' - } - { - name: keymgr_o_cg - desc: '''Covers the following conditions when scoreboard checks `keymgr_o` value: - - whether secret2 partition is locked - - whether `lc_seed_hw_rd_en_i` is On - ''' - } - { - name: req_dai_access_after_alert_cg - desc: '''Covers if sequence issued various DAI requests after any fatal alert is - triggered.''' - } - { - name: issue_checks_after_alert_cg - desc: '''Covers if sequence issued various OTP_CTRL's background checks after any fatal alert - is triggered.''' - } - { - name: csr_rd_after_alert_cg - desc: '''Covers if the following CSRs are being read and the value is checked in scoreboard - after any fatal alert is triggered: - - unbuffered partitions' digest CSRs - - HW partition's digest CSRs - - secrets partitions' digest CSRs - - direct_access read data CSRs - - status CSR - - error_code CSR - ''' - } - { - name: dai_err_code_cg - desc: '''Covers all applicable error codes in DAI, and cross each error code with all - 7 partitions.''' - } - { - name: lci_err_code_cg - desc: '''Covers all applicable error codes in LCI.''' - } - { - name: unbuf_err_code_cg - desc: '''This is an array of covergroups to cover all applicable error codes in three - unbuffered partitions.''' - } - { - name: buf_err_code_cg - desc: '''This is an array of covergroups to cover all applicable error codes in five - buffered partitions.''' - } - { - name: unbuf_access_lock_cg_wrap_cg - desc: '''This is an array of covergroups to cover lock conditions below in three - unbuffered partitions: - - the partition is write-locked - - the partition is read-locked - - the current operation type - Then cross the three coverpoints.''' - } - { - name: dai_access_secret2_cg - desc: '''Covers whether `lc_creator_seed_sw_rw_en` is On during any DAI accesses.''' - } - { - name: status_csr_cg - desc: '''Covers the value of every bit in `status` CSR.''' - } - // The following covergroups are implemented in `otp_ctrl_cov_if.sv`. - { - name: lc_esc_en_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether LC program reqeust is in progress - - whether DAI interface is busy - ''' - } - { - name: flash_data_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - { - name: flash_addr_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - { - name: sram_0_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - { - name: sram_1_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - { - name: otbn_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - { - name: lc_prog_req_condition_cg - desc: '''Covers the following conditions when `lc_escalation_en` is On: - - whether any key requests is in progress - - whether DAI interface is busy - - whether lc_esc_en is On - ''' - } - ] -} diff --git a/hw/ip/otp_ctrl/doc/checklist.md b/hw/ip/otp_ctrl/doc/checklist.md deleted file mode 100644 index 1fab63e8fa9b4..0000000000000 --- a/hw/ip/otp_ctrl/doc/checklist.md +++ /dev/null @@ -1,271 +0,0 @@ -# OTP_CTRL Checklist - - -This checklist is for [Hardware Stage](../../../../doc/project_governance/development_stages.md) transitions for the [OTP_CTRL peripheral.](../README.md) -All checklist items refer to the content in the [Checklist.](../../../../doc/project_governance/checklist/README.md) - -## Design Checklist - -### D1 - -Type | Item | Resolution | Note/Collaterals ---------------|--------------------------------|-------------|------------------ -Documentation | [SPEC_COMPLETE][] | Done | [OTP_CTRL Design Spec](../README.md) -Documentation | [CSR_DEFINED][] | Done | -RTL | [CLKRST_CONNECTED][] | Done | -RTL | [IP_TOP][] | Done | -RTL | [IP_INSTANTIABLE][] | Done | -RTL | [PHYSICAL_MACROS_DEFINED_80][] | Done | -RTL | [FUNC_IMPLEMENTED][] | Done | -RTL | [ASSERT_KNOWN_ADDED][] | Done | -Code Quality | [LINT_SETUP][] | Done | - -[SPEC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#spec_complete -[CSR_DEFINED]: ../../../../doc/project_governance/checklist/README.md#csr_defined -[CLKRST_CONNECTED]: ../../../../doc/project_governance/checklist/README.md#clkrst_connected -[IP_TOP]: ../../../../doc/project_governance/checklist/README.md#ip_top -[IP_INSTANTIABLE]: ../../../../doc/project_governance/checklist/README.md#ip_instantiable -[PHYSICAL_MACROS_DEFINED_80]: ../../../../doc/project_governance/checklist/README.md#mem_instanced_80 -[FUNC_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#func_implemented -[ASSERT_KNOWN_ADDED]: ../../../../doc/project_governance/checklist/README.md#assert_known_added -[LINT_SETUP]: ../../../../doc/project_governance/checklist/README.md#lint_setup - -### D2 - -Type | Item | Resolution | Note/Collaterals ---------------|---------------------------|-------------|------------------ -Documentation | [NEW_FEATURES][] | Done | -Documentation | [BLOCK_DIAGRAM][] | Done | -Documentation | [DOC_INTERFACE][] | Done | -Documentation | [DOC_INTEGRATION_GUIDE][] | Waived | This checklist item has been added retrospectively. -Documentation | [MISSING_FUNC][] | Done | -Documentation | [FEATURE_FROZEN][] | Done | -RTL | [FEATURE_COMPLETE][] | Done | -RTL | [PORT_FROZEN][] | Done | -RTL | [ARCHITECTURE_FROZEN][] | Done | -RTL | [REVIEW_TODO][] | Done | -RTL | [STYLE_X][] | Done | -RTL | [CDC_SYNCMACRO][] | N/A | -Code Quality | [LINT_PASS][] | Done | -Code Quality | [CDC_SETUP][] | Waived | No block-level flow available - waived to top-level signoff. -Code Quality | [RDC_SETUP][] | Waived | No block-level flow available - waived to top-level signoff. -Code Quality | [AREA_CHECK][] | Done | -Code Quality | [TIMING_CHECK][] | Done | -Security | [SEC_CM_DOCUMENTED][] | Done | - -[NEW_FEATURES]: ../../../../doc/project_governance/checklist/README.md#new_features -[BLOCK_DIAGRAM]: ../../../../doc/project_governance/checklist/README.md#block_diagram -[DOC_INTERFACE]: ../../../../doc/project_governance/checklist/README.md#doc_interface -[DOC_INTEGRATION_GUIDE]: ../../../../doc/project_governance/checklist/README.md#doc_integration_guide -[MISSING_FUNC]: ../../../../doc/project_governance/checklist/README.md#missing_func -[FEATURE_FROZEN]: ../../../../doc/project_governance/checklist/README.md#feature_frozen -[FEATURE_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#feature_complete -[PORT_FROZEN]: ../../../../doc/project_governance/checklist/README.md#port_frozen -[ARCHITECTURE_FROZEN]: ../../../../doc/project_governance/checklist/README.md#architecture_frozen -[REVIEW_TODO]: ../../../../doc/project_governance/checklist/README.md#review_todo -[STYLE_X]: ../../../../doc/project_governance/checklist/README.md#style_x -[CDC_SYNCMACRO]: ../../../../doc/project_governance/checklist/README.md#cdc_syncmacro -[LINT_PASS]: ../../../../doc/project_governance/checklist/README.md#lint_pass -[CDC_SETUP]: ../../../../doc/project_governance/checklist/README.md#cdc_setup -[RDC_SETUP]: ../../../../doc/project_governance/checklist/README.md#rdc_setup -[AREA_CHECK]: ../../../../doc/project_governance/checklist/README.md#area_check -[TIMING_CHECK]: ../../../../doc/project_governance/checklist/README.md#timing_check -[SEC_CM_DOCUMENTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_documented - -### D2S - - Type | Item | Resolution | Note/Collaterals ---------------|------------------------------|-------------|------------------ -Security | [SEC_CM_ASSETS_LISTED][] | Done | -Security | [SEC_CM_IMPLEMENTED][] | Done | -Security | [SEC_CM_RND_CNST][] | Done | -Security | [SEC_CM_NON_RESET_FLOPS][] | Done | -Security | [SEC_CM_SHADOW_REGS][] | Done | -Security | [SEC_CM_RTL_REVIEWED][] | Done | -Security | [SEC_CM_COUNCIL_REVIEWED][] | Done | - -[SEC_CM_ASSETS_LISTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_assets_listed -[SEC_CM_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_implemented -[SEC_CM_RND_CNST]: ../../../../doc/project_governance/checklist/README.md#sec_cm_rnd_cnst -[SEC_CM_NON_RESET_FLOPS]: ../../../../doc/project_governance/checklist/README.md#sec_cm_non_reset_flops -[SEC_CM_SHADOW_REGS]: ../../../../doc/project_governance/checklist/README.md#sec_cm_shadow_regs -[SEC_CM_RTL_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_rtl_reviewed -[SEC_CM_COUNCIL_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_council_reviewed - -### D3 - - Type | Item | Resolution | Note/Collaterals ---------------|-------------------------|-------------|------------------ -Documentation | [NEW_FEATURES_D3][] | Done | -RTL | [TODO_COMPLETE][] | Done | -Code Quality | [LINT_COMPLETE][] | Done | Waiver files approved by TC on 2024-08-08. -Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. -Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. -Review | [REVIEW_RTL][] | Done | -Review | [REVIEW_DELETED_FF][] | Waived | No block-level flow available - waived to top-level signoff. -Review | [REVIEW_SW_CHANGE][] | Done | -Review | [REVIEW_SW_ERRATA][] | Done | -Review | Reviewer(s) | Done | adk@ vogelpi@ -Review | Signoff date | Done | 2024-08-08 - -[NEW_FEATURES_D3]: ../../../../doc/project_governance/checklist/README.md#new_features_d3 -[TODO_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#todo_complete -[LINT_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#lint_complete -[CDC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#cdc_complete -[RDC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#rdc_complete -[REVIEW_RTL]: ../../../../doc/project_governance/checklist/README.md#review_rtl -[REVIEW_DELETED_FF]: ../../../../doc/project_governance/checklist/README.md#review_deleted_ff -[REVIEW_SW_CHANGE]: ../../../../doc/project_governance/checklist/README.md#review_sw_change -[REVIEW_SW_ERRATA]: ../../../../doc/project_governance/checklist/README.md#review_sw_errata - -## Verification Checklist - -### V1 - - Type | Item | Resolution | Note/Collaterals ---------------|---------------------------------------|-------------|------------------ -Documentation | [DV_DOC_DRAFT_COMPLETED][] | Done | [OTP_CTRL DV document](../dv/README.md) -Documentation | [TESTPLAN_COMPLETED][] | Done | [OTP_CTRL Testplan](../dv/README.md#testplan) -Testbench | [TB_TOP_CREATED][] | Done | -Testbench | [PRELIMINARY_ASSERTION_CHECKS_ADDED][]| Done | -Testbench | [SIM_TB_ENV_CREATED][] | Done | -Testbench | [SIM_RAL_MODEL_GEN_AUTOMATED][] | Done | -Testbench | [CSR_CHECK_GEN_AUTOMATED][] | Done | -Testbench | [TB_GEN_AUTOMATED][] | Done | -Tests | [SIM_SMOKE_TEST_PASSING][] | Done | -Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | Done | -Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | N/A | -Tool Setup | [SIM_ALT_TOOL_SETUP][] | Done | -Regression | [SIM_SMOKE_REGRESSION_SETUP][] | Done | -Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | Done | -Regression | [FPV_REGRESSION_SETUP][] | N/A | -Coverage | [SIM_COVERAGE_MODEL_ADDED][] | Done | -Code Quality | [TB_LINT_SETUP][] | Done | -Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | N/A | Exception for IP modules -Review | [DESIGN_SPEC_REVIEWED][] | Done | -Review | [TESTPLAN_REVIEWED][] | Done | -Review | [STD_TEST_CATEGORIES_PLANNED][] | Done | Exception (Security, Power, Debug) -Review | [V2_CHECKLIST_SCOPED][] | Done | - -[DV_DOC_DRAFT_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_draft_completed -[TESTPLAN_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#testplan_completed -[TB_TOP_CREATED]: ../../../../doc/project_governance/checklist/README.md#tb_top_created -[PRELIMINARY_ASSERTION_CHECKS_ADDED]: ../../../../doc/project_governance/checklist/README.md#preliminary_assertion_checks_added -[SIM_TB_ENV_CREATED]: ../../../../doc/project_governance/checklist/README.md#sim_tb_env_created -[SIM_RAL_MODEL_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#sim_ral_model_gen_automated -[CSR_CHECK_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#csr_check_gen_automated -[TB_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#tb_gen_automated -[SIM_SMOKE_TEST_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_smoke_test_passing -[SIM_CSR_MEM_TEST_SUITE_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_csr_mem_test_suite_passing -[FPV_MAIN_ASSERTIONS_PROVEN]: ../../../../doc/project_governance/checklist/README.md#fpv_main_assertions_proven -[SIM_ALT_TOOL_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_alt_tool_setup -[SIM_SMOKE_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_smoke_regression_setup -[SIM_NIGHTLY_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_setup -[FPV_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#fpv_regression_setup -[SIM_COVERAGE_MODEL_ADDED]: ../../../../doc/project_governance/checklist/README.md#sim_coverage_model_added -[PRE_VERIFIED_SUB_MODULES_V1]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v1 -[TB_LINT_SETUP]: ../../../../doc/project_governance/checklist/README.md#tb_lint_setup -[DESIGN_SPEC_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#design_spec_reviewed -[TESTPLAN_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#testplan_reviewed -[STD_TEST_CATEGORIES_PLANNED]: ../../../../doc/project_governance/checklist/README.md#std_test_categories_planned -[V2_CHECKLIST_SCOPED]: ../../../../doc/project_governance/checklist/README.md#v2_checklist_scoped - -### V2 - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------------|-------------|------------------ -Documentation | [DESIGN_DELTAS_CAPTURED_V2][] | Done | -Documentation | [DV_DOC_COMPLETED][] | Done | -Testbench | [FUNCTIONAL_COVERAGE_IMPLEMENTED][] | Done | -Testbench | [ALL_INTERFACES_EXERCISED][] | Done | `prim_tl_o/i` has a simple prim_tl_agent support, but need to be replaced with auto-generated tl_agent once reggen tool is optimized. -Testbench | [ALL_ASSERTION_CHECKS_ADDED][] | Done | -Testbench | [SIM_TB_ENV_COMPLETED][] | Done | -Tests | [SIM_ALL_TESTS_PASSING][] | Done | -Tests | [FPV_ALL_ASSERTIONS_WRITTEN][] | N/A | -Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | N/A | -Tests | [SIM_FW_SIMULATED][] | N/A | -Regression | [SIM_NIGHTLY_REGRESSION_V2][] | Done | -Coverage | [SIM_CODE_COVERAGE_V2][] | Done | -Coverage | [SIM_FUNCTIONAL_COVERAGE_V2][] | Done | -Coverage | [FPV_CODE_COVERAGE_V2][] | N/A | -Coverage | [FPV_COI_COVERAGE_V2][] | N/A | -Integration | [PRE_VERIFIED_SUB_MODULES_V2][] | Done | Waived `prim_alert_sender` and `prim_lfsr` -Issues | [NO_HIGH_PRIORITY_ISSUES_PENDING][] | Done | -Issues | [ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED][] | Done | -Review | [DV_DOC_TESTPLAN_REVIEWED][] | Done | Reviewed on 05/24/2021 -Review | [V3_CHECKLIST_SCOPED][] | Done | - -[DESIGN_DELTAS_CAPTURED_V2]: ../../../../doc/project_governance/checklist/README.md#design_deltas_captured_v2 -[DV_DOC_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_completed -[FUNCTIONAL_COVERAGE_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#functional_coverage_implemented -[ALL_INTERFACES_EXERCISED]: ../../../../doc/project_governance/checklist/README.md#all_interfaces_exercised -[ALL_ASSERTION_CHECKS_ADDED]: ../../../../doc/project_governance/checklist/README.md#all_assertion_checks_added -[SIM_TB_ENV_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#sim_tb_env_completed -[SIM_ALL_TESTS_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_all_tests_passing -[FPV_ALL_ASSERTIONS_WRITTEN]: ../../../../doc/project_governance/checklist/README.md#fpv_all_assertions_written -[FPV_ALL_ASSUMPTIONS_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#fpv_all_assumptions_reviewed -[SIM_FW_SIMULATED]: ../../../../doc/project_governance/checklist/README.md#sim_fw_simulated -[SIM_NIGHTLY_REGRESSION_V2]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_v2 -[SIM_CODE_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#sim_code_coverage_v2 -[SIM_FUNCTIONAL_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#sim_functional_coverage_v2 -[FPV_CODE_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#fpv_code_coverage_v2 -[FPV_COI_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#fpv_coi_coverage_v2 -[PRE_VERIFIED_SUB_MODULES_V2]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v2 -[NO_HIGH_PRIORITY_ISSUES_PENDING]: ../../../../doc/project_governance/checklist/README.md#no_high_priority_issues_pending -[ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED]:../../../../doc/project_governance/checklist/README.md#all_low_priority_issues_root_caused -[DV_DOC_TESTPLAN_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_testplan_reviewed -[V3_CHECKLIST_SCOPED]: ../../../../doc/project_governance/checklist/README.md#v3_checklist_scoped - -### V2S - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------------|-------------|------------------ -Documentation | [SEC_CM_TESTPLAN_COMPLETED][] | Done | -Tests | [FPV_SEC_CM_VERIFIED][] | Done | -Tests | [SIM_SEC_CM_VERIFIED][] | Done | -Coverage | [SIM_COVERAGE_REVIEWED][] | Done | -Review | [SEC_CM_DV_REVIEWED][] | Done | - -[SEC_CM_TESTPLAN_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_testplan_completed -[FPV_SEC_CM_VERIFIED]: ../../../../doc/project_governance/checklist/README.md#fpv_sec_cm_verified -[SIM_SEC_CM_VERIFIED]: ../../../../doc/project_governance/checklist/README.md#sim_sec_cm_verified -[SIM_COVERAGE_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sim_coverage_reviewed -[SEC_CM_DV_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_dv_reviewed - -### V3 - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------|-------------|------------------ -Documentation | [DESIGN_DELTAS_CAPTURED_V3][] | Not Started | -Tests | [X_PROP_ANALYSIS_COMPLETED][] | Not Started | -Tests | [FPV_ASSERTIONS_PROVEN_AT_V3][] | Not Started | -Regression | [SIM_NIGHTLY_REGRESSION_AT_V3][] | Not Started | -Coverage | [SIM_CODE_COVERAGE_AT_100][] | Not Started | -Coverage | [SIM_FUNCTIONAL_COVERAGE_AT_100][]| Not Started | -Coverage | [FPV_CODE_COVERAGE_AT_100][] | Not Started | -Coverage | [FPV_COI_COVERAGE_AT_100][] | Not Started | -Code Quality | [ALL_TODOS_RESOLVED][] | Not Started | -Code Quality | [NO_TOOL_WARNINGS_THROWN][] | Not Started | -Code Quality | [TB_LINT_COMPLETE][] | Not Started | -Integration | [PRE_VERIFIED_SUB_MODULES_V3][] | Not Started | -Issues | [NO_ISSUES_PENDING][] | Not Started | -Review | Reviewer(s) | Not Started | -Review | Signoff date | Not Started | - -[DESIGN_DELTAS_CAPTURED_V3]: ../../../../doc/project_governance/checklist/README.md#design_deltas_captured_v3 -[X_PROP_ANALYSIS_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#x_prop_analysis_completed -[FPV_ASSERTIONS_PROVEN_AT_V3]: ../../../../doc/project_governance/checklist/README.md#fpv_assertions_proven_at_v3 -[SIM_NIGHTLY_REGRESSION_AT_V3]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_at_v3 -[SIM_CODE_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#sim_code_coverage_at_100 -[SIM_FUNCTIONAL_COVERAGE_AT_100]:../../../../doc/project_governance/checklist/README.md#sim_functional_coverage_at_100 -[FPV_CODE_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#fpv_code_coverage_at_100 -[FPV_COI_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#fpv_coi_coverage_at_100 -[ALL_TODOS_RESOLVED]: ../../../../doc/project_governance/checklist/README.md#all_todos_resolved -[NO_TOOL_WARNINGS_THROWN]: ../../../../doc/project_governance/checklist/README.md#no_tool_warnings_thrown -[TB_LINT_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#tb_lint_complete -[PRE_VERIFIED_SUB_MODULES_V3]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v3 -[NO_ISSUES_PENDING]: ../../../../doc/project_governance/checklist/README.md#no_issues_pending diff --git a/hw/ip/otp_ctrl/doc/interfaces.md b/hw/ip/otp_ctrl/doc/interfaces.md deleted file mode 100644 index 188b26c539ed2..0000000000000 --- a/hw/ip/otp_ctrl/doc/interfaces.md +++ /dev/null @@ -1,303 +0,0 @@ -# Hardware Interfaces - -## Parameters - -The following table lists the instantiation parameters of OTP. -Note that parameters prefixed with `RndCnst` are random netlist constants that need to be regenerated via topgen before the tapeout (typically by the silicon creator). - -Parameter | Default (Max) | Top Earlgrey | Description -----------------------------|---------------|--------------|--------------- -`AlertAsyncOn` | 2'b11 | 2'b11 | -`RndCnstLfsrSeed` | (see RTL) | (see RTL) | Seed to be used for the internal 40bit partition check timer LFSR. This needs to be replaced by the silicon creator before the tapeout. -`RndCnstLfsrPerm` | (see RTL) | (see RTL) | Permutation to be used for the internal 40bit partition check timer LFSR. This needs to be replaced by the silicon creator before the tapeout. -`RndCnstKey` | (see RTL) | (see RTL) | Random scrambling keys for secret partitions, to be used in the [scrambling datapath](#scrambling-datapath). -`RndCnstDigestConst` | (see RTL) | (see RTL) | Random digest finalization constants, to be used in the [scrambling datapath](#scrambling-datapath). -`RndCnstDigestIV` | (see RTL) | (see RTL) | Random digest initialization vectors, to be used in the [scrambling datapath](#scrambling-datapath). -`RndCnstRawUnlockToken` | (see RTL) | (see RTL) | Global RAW unlock token to be used for the first life cycle transition. See also [conditional life cycle transitions](../../lc_ctrl/README.md#conditional-transitions). - -## Signals - - -Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`otp_ctrl`** has the following hardware interfaces defined -- Primary Clock: **`clk_i`** -- Other Clocks: **`clk_edn_i`** -- Bus Device Interfaces (TL-UL): **`core_tl`**, **`prim_tl`** -- Bus Host Interfaces (TL-UL): *none* - -## Peripheral Pins for Chip IO - -| Pin name | Direction | Description | -|:-----------|:------------|:------------------------------------------------------------------| -| test[7:0] | output | Test-related GPIOs. Only active in DFT-enabled life cycle states. | - -## [Inter-Module Signals](https://opentitan.org/book/doc/contributing/hw/comportability/index.html#inter-signal-handling) - -| Port Name | Package::Struct | Type | Act | Width | Description | -|:-------------------------|:---------------------------------|:--------|:------|--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| otp_ext_voltage_h | | io | none | 1 | | -| otp_ast_pwr_seq | otp_ctrl_pkg::otp_ast_req | uni | req | 1 | Power sequencing signals to AST (VDD domain). | -| otp_ast_pwr_seq_h | otp_ctrl_pkg::otp_ast_rsp | uni | rcv | 1 | Power sequencing signals coming from AST (VCC domain). | -| edn | edn_pkg::edn | req_rsp | req | 1 | Entropy request to the entropy distribution network for LFSR reseeding and ephemeral key derivation. | -| pwr_otp | pwrmgr_pkg::pwr_otp | req_rsp | rsp | 1 | Initialization request/acknowledge from/to power manager. | -| lc_otp_vendor_test | otp_ctrl_pkg::lc_otp_vendor_test | req_rsp | rsp | 1 | Vendor test control signals from/to the life cycle TAP. | -| lc_otp_program | otp_ctrl_pkg::lc_otp_program | req_rsp | rsp | 1 | Life cycle state transition interface. | -| otp_lc_data | otp_ctrl_pkg::otp_lc_data | uni | req | 1 | Life cycle state output holding the current life cycle state, the value of the transition counter and the tokens needed for life cycle transitions. | -| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Life cycle escalation enable coming from life cycle controller. This signal moves all FSMs within OTP into the error state. | -| lc_creator_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Provision enable qualifier coming from life cycle controller. This signal enables SW read / write access to the RMA_TOKEN and CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. | -| lc_owner_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Provision enable qualifier coming from life cycle controller. This signal enables SW read / write access to the OWNER_SEED. | -| lc_seed_hw_rd_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Seed read enable coming from life cycle controller. This signal enables HW read access to the CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. | -| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Test enable qualifier coming from life cycle controller. This signals enables the TL-UL access port to the proprietary OTP IP. | -| lc_check_byp_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Life cycle partition check bypass signal. This signal causes the life cycle partition to bypass consistency checks during life cycle state transitions in order to prevent spurious consistency check failures. | -| otp_keymgr_key | otp_ctrl_pkg::otp_keymgr_key | uni | req | 1 | Key output to the key manager holding CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1. | -| flash_otp_key | otp_ctrl_pkg::flash_otp_key | req_rsp | rsp | 1 | Key derivation interface for FLASH scrambling. | -| sram_otp_key | otp_ctrl_pkg::sram_otp_key | req_rsp | rsp | 4 | Array with key derivation interfaces for SRAM scrambling devices. | -| otbn_otp_key | otp_ctrl_pkg::otbn_otp_key | req_rsp | rsp | 1 | Key derivation interface for OTBN scrambling devices. | -| otp_broadcast | otp_ctrl_part_pkg::otp_broadcast | uni | req | 1 | Output of the HW partitions with breakout data types. | -| obs_ctrl | ast_pkg::ast_obs_ctrl | uni | rcv | 1 | AST observability control signals. | -| otp_obs | logic | uni | req | 8 | AST observability bus. | -| core_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | -| prim_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | - -## Interrupts - -| Interrupt Name | Type | Description | -|:-------------------|:-------|:-----------------------------------------------------------------------------------------------------------------------------| -| otp_operation_done | Event | A direct access command or digest calculation operation has completed. | -| otp_error | Event | An error has occurred in the OTP controller. Check the [`ERR_CODE`](registers.md#err_code) register to get more information. | - -## Security Alerts - -| Alert Name | Description | -|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------| -| fatal_macro_error | This alert triggers if hardware detects an uncorrectable error during an OTP transaction, for example an uncorrectable ECC error in the OTP array. | -| fatal_check_error | This alert triggers if any of the background checks fails. This includes the digest checks and concurrent ECC checks in the buffer registers. | -| fatal_bus_integ_error | This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. | -| fatal_prim_otp_alert | Fatal alert triggered inside the OTP primitive, including fatal TL-UL bus integrity faults of the test interface. | -| recov_prim_otp_alert | Recoverable alert triggered inside the OTP primitive. | - -## Security Countermeasures - -| Countermeasure ID | Description | -|:-------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| OTP_CTRL.BUS.INTEGRITY | End-to-end bus integrity scheme. | -| OTP_CTRL.SECRET.MEM.SCRAMBLE | Secret partitions are scrambled with a full-round PRESENT cipher. | -| OTP_CTRL.PART.MEM.DIGEST | Integrity of buffered partitions is ensured via a 64bit digest. | -| OTP_CTRL.DAI.FSM.SPARSE | The direct access interface FSM is sparsely encoded. | -| OTP_CTRL.KDI.FSM.SPARSE | The key derivation interface FSM is sparsely encoded. | -| OTP_CTRL.LCI.FSM.SPARSE | The life cycle interface FSM is sparsely encoded. | -| OTP_CTRL.PART.FSM.SPARSE | The partition FSMs are sparsely encoded. | -| OTP_CTRL.SCRMBL.FSM.SPARSE | The scramble datapath FSM is sparsely encoded. | -| OTP_CTRL.TIMER.FSM.SPARSE | The background check timer FSM is sparsely encoded. | -| OTP_CTRL.DAI.CTR.REDUN | The direct access interface address counter employs a cross-counter implementation. | -| OTP_CTRL.KDI_SEED.CTR.REDUN | The key derivation interface counter employs a cross-counter implementation. | -| OTP_CTRL.KDI_ENTROPY.CTR.REDUN | The key derivation entropy counter employs a cross-counter implementation. | -| OTP_CTRL.LCI.CTR.REDUN | The life cycle interface address counter employs a cross-counter implementation. | -| OTP_CTRL.PART.CTR.REDUN | The address counter of buffered partitions employs a cross-counter implementation. | -| OTP_CTRL.SCRMBL.CTR.REDUN | The srambling datapath counter employs a cross-counter implementation. | -| OTP_CTRL.TIMER_INTEG.CTR.REDUN | The background integrity check timer employs a duplicated counter implementation. | -| OTP_CTRL.TIMER_CNSTY.CTR.REDUN | The background consistency check timer employs a duplicated counter implementation. | -| OTP_CTRL.TIMER.LFSR.REDUN | The background check LFSR is duplicated. | -| OTP_CTRL.DAI.FSM.LOCAL_ESC | The direct access interface FSM is moved into an invalid state upon local escalation. | -| OTP_CTRL.LCI.FSM.LOCAL_ESC | The life cycle interface FSM is moved into an invalid state upon local escalation. | -| OTP_CTRL.KDI.FSM.LOCAL_ESC | The key derivation interface FSM is moved into an invalid state upon local escalation. | -| OTP_CTRL.PART.FSM.LOCAL_ESC | The partition FSMs are moved into an invalid state upon local escalation. | -| OTP_CTRL.SCRMBL.FSM.LOCAL_ESC | The scramble datapath FSM is moved into an invalid state upon local escalation. | -| OTP_CTRL.TIMER.FSM.LOCAL_ESC | The background check timer FSM is moved into an invalid state upon local escalation. | -| OTP_CTRL.DAI.FSM.GLOBAL_ESC | The direct access interface FSM is moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.LCI.FSM.GLOBAL_ESC | The life cycle interface FSM is moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.KDI.FSM.GLOBAL_ESC | The key derivation interface FSM is moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.PART.FSM.GLOBAL_ESC | The partition FSMs are moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.SCRMBL.FSM.GLOBAL_ESC | The scramble datapath FSM is moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.TIMER.FSM.GLOBAL_ESC | The background check timer FSM is moved into an invalid state upon global escalation via life cycle. | -| OTP_CTRL.PART.DATA_REG.INTEGRITY | All partition buffer registers are protected with ECC on 64bit blocks. | -| OTP_CTRL.PART.DATA_REG.BKGN_CHK | The digest of buffered partitions is recomputed and checked at pseudorandom intervals in the background. | -| OTP_CTRL.PART.MEM.REGREN | Unbuffered ('software') partitions can be read-locked via a CSR until the next system reset. | -| OTP_CTRL.PART.MEM.SW_UNREADABLE | Secret buffered partitions become unreadable to software once they are locked via the digest. | -| OTP_CTRL.PART.MEM.SW_UNWRITABLE | All partitions become unwritable by software once they are locked via the digest. | -| OTP_CTRL.LC_PART.MEM.SW_NOACCESS | The life cycle partition is not directly readable nor writable via software. | -| OTP_CTRL.ACCESS.CTRL.MUBI | The access control signals going from the partitions to the DAI are MUBI encoded. | -| OTP_CTRL.TOKEN_VALID.CTRL.MUBI | The token valid signals going to the life cycle controller are MUBI encoded. | -| OTP_CTRL.LC_CTRL.INTERSIG.MUBI | The life cycle control signals are multibit encoded. | -| OTP_CTRL.TEST.BUS.LC_GATED | Prevent access to test signals and the OTP backdoor interface in non-test lifecycle states. | -| OTP_CTRL.TEST_TL_LC_GATE.FSM.SPARSE | The control FSM inside the TL-UL gating primitive is sparsely encoded. | -| OTP_CTRL.DIRECT_ACCESS.CONFIG.REGWEN | The direct access CSRs are REGWEN protected. | -| OTP_CTRL.CHECK_TRIGGER.CONFIG.REGWEN | The check trigger CSR is REGWEN protected. | -| OTP_CTRL.CHECK.CONFIG.REGWEN | The check CSR is REGWEN protected. | -| OTP_CTRL.MACRO.MEM.INTEGRITY | The OTP macro employs a vendor-specific integrity scheme at the granularity of the native 16bit OTP words. The scheme is able to at least detect single bit errors. | -| OTP_CTRL.MACRO.MEM.CM | The OTP macro may contain additional vendor-specific countermeasures. | - - - - -The OTP controller contains various interfaces that connect to other comportable IPs within OpenTitan, and these are briefly explained further below. - -### EDN Interface - -The entropy request interface that talks to EDN in order to fetch fresh entropy for ephemeral SRAM scrambling key derivation and the LFSR counters for background checks. -It is comprised of the `otp_edn_o` and `otp_edn_i` signals and follows a req / ack protocol. - -See also [EDN documentation](../../edn/README.md). - -### Power Manager Interface - -The power manager interface is comprised of three signals overall: an initialization request (`pwr_otp_i.otp_init`), an initialization done response (`pwr_otp_o.otp_done`) and an idle indicator (`pwr_otp_o.otp_idle`). - -The power manager asserts `pwr_otp_i.otp_init` in order to signal to the OTP controller that it can start initialization, and the OTP controller signals completion of the initialization sequence by asserting `pwr_otp_o.otp_done` (the signal will remain high until reset). - -The idle indication signal `pwr_otp_o.otp_idle` indicates whether there is an ongoing write operation in the Direct Access Interface (DAI) or Life Cycle Interface (LCI), and the power manager uses that indication to determine whether a power down request needs to be aborted. - -Since the power manager may run in a different clock domain, the `pwr_otp_i.otp_init` signal is synchronized within the OTP controller. -The power manager is responsible for synchronizing the `pwr_otp_o.otp_done` and `pwr_otp_o.otp_idle` signals. - -See also [power manager documentation](../../../top_earlgrey/ip_autogen/pwrmgr/README.md). - -### Life Cycle Interfaces - -The interface to the life cycle controller can be split into three functional sub-interfaces (vendor test, state output, state transitions), and these are explained in more detail below. -Note that the OTP and life cycle controllers are supposed to be in the same clock domain, hence no additional signal synchronization is required. -See also [life cycle controller documentation](../../lc_ctrl/README.md) for more details. - -#### Vendor Test Signals - -The `lc_otp_vendor_test_i` and `lc_otp_vendor_test_o` signals are connected to a 32bit control and a 32bit status register in the life cycle TAP, respectively, and are directly routed to the `prim_otp` wrapper. -These control and status signals may be used by the silicon creator to exercise the OTP programming smoke checks on the VENDOR_TEST partition. -The signals are gated with the life cycle state inside the life cycle controller such that they do not have any effect in production life cycle states. - -#### State, Counter and Token Output - -After initialization, the life cycle partition contents, as well as the tokens and personalization status is output to the life cycle controller via the `otp_lc_data_o` struct. -The life cycle controller uses this information to determine the life cycle state, and steer the appropriate qualifier signals. -Some of these qualifier signals (`lc_dft_en_i`, `lc_creator_seed_sw_rw_en_i`, `lc_seed_hw_rd_en_i` and `lc_escalate_en_i`) are fed back to the OTP controller in order to ungate testing logic to the OTP macro; enable SW write access to the `SECRET2` partition; enable hardware read access to the root key in the `SECRET2` partition; or to push the OTP controller into escalation state. - -A possible sequence for the signals described is illustrated below. -```wavejson -{signal: [ - {name: 'clk_i', wave: 'p.................'}, - {name: 'otp_lc_data_o.valid', wave: '0.|...|.1.|...|...'}, - {name: 'otp_lc_data_o.state', wave: '03|...|...|...|...'}, - {name: 'otp_lc_data_o.count', wave: '03|...|...|...|...'}, - {}, - {name: 'otp_lc_data_o.test_unlock_token', wave: '0.|...|.3.|...|...'}, - {name: 'otp_lc_data_o.test_exit_token', wave: '0.|...|.3.|...|...'}, - {name: 'otp_lc_data_o.test_tokens_valid', wave: '0.|...|.3.|...|...'}, - {}, - {name: 'otp_lc_data_o.rma_token', wave: '0.|.3.|...|...|...'}, - {name: 'otp_lc_data_o.rma_token_valid', wave: '0.|.3.|...|...|...'}, - {}, - {name: 'otp_lc_data_o.secrets_valid', wave: '0.|.3.|...|...|...'}, - {}, - {name: 'lc_creator_seed_sw_rw_en_i', wave: '0.|...|...|.4.|...'}, - {name: 'lc_seed_hw_rd_en_i', wave: '0.|...|...|.4.|...'}, - {name: 'lc_dft_en_i', wave: '0.|...|...|.4.|...'}, - {}, - {name: 'lc_escalate_en_i', wave: '0.|...|...|...|.5.'}, -]} -``` - -Note that the `otp_lc_data_o.valid` signal is only asserted after the `LIFE_CYCLE`, `SECRET0` and `SECRET2` partitions have successfully initialized, since the life cycle collateral contains information from all three partitions. -The `otp_lc_data_o.test_tokens_valid` and `otp_lc_data_o.rma_token_valid` signals are multibit valid signals indicating whether the corresponding tokens are valid. -The ``otp_lc_data_o.secrets_valid`` signal is a multibit valid signal that is set to `lc_ctrl_pkg::On` iff the `SECRET2` partition containing the root keys has been locked with a digest. - - -#### State Transitions - -In order to perform life cycle state transitions, the life cycle controller can present the new value of the life cycle state and counter via the programming interface as shown below: - -```wavejson -{signal: [ - {name: 'clk_i', wave: 'p.......'}, - {name: 'lc_otp_program_i.req', wave: '01.|..0.'}, - {name: 'lc_otp_program_i.state', wave: '03.|..0.'}, - {name: 'lc_otp_program_i.count', wave: '03.|..0.'}, - {name: 'lc_otp_program_o.ack', wave: '0..|.10.'}, - {name: 'lc_otp_program_o.err', wave: '0..|.40.'}, -]} -``` - -The request must remain asserted until the life cycle controller has responded. -An error is fatal and indicates that the OTP programming operation has failed. - -Note that the new state must not clear any bits that have already been programmed to OTP - i.e., the new state must be incrementally programmable on top of the previous state. -There are hence some implications on the life cycle encoding due to the ECC employed, see [life cycle state encoding](../../lc_ctrl/README.md#life-cycle-manufacturing-state-encodings) for details. - -Note that the behavior of the `lc_otp_program_i.otp_test_ctrl` signal is vendor-specific, and hence the signal is set to `x` in the timing diagram above. -The purpose of this signal is to control vendor-specific test mechanisms, and its value will only be forwarded to the OTP macro in RAW, TEST_* and RMA states. -In all other life cycle states this signal will be clamped to zero. - -### Interface to Key Manager - -The interface to the key manager is a simple struct that outputs the CREATOR_ROOT_KEY_SHARE0 and CREATOR_ROOT_KEY_SHARE1 keys via `otp_keymgr_key_o` if these secrets have been provisioned and locked (via CREATOR_KEY_LOCK). -Otherwise, this signal is tied to a random netlist constant. - -Since the key manager may run in a different clock domain, key manager is responsible for synchronizing the `otp_keymgr_key_o` signals. - -### Interface to Flash Scrambler - -The interface to the FLASH scrambling device is a simple req/ack interface that provides the flash controller with the two 128bit keys for data and address scrambling. - -The keys can be requested as illustrated below: - -```wavejson -{signal: [ - {name: 'clk_i', wave: 'p...........'}, - {name: 'flash_otp_key_i.data_req', wave: '01.|..0.|...'}, - {name: 'flash_otp_key_i.addr_req', wave: '01.|....|..0'}, - {name: 'flash_otp_key_o.data_ack', wave: '0..|.10.|...'}, - {name: 'flash_otp_key_o.addr_ack', wave: '0..|....|.10'}, - {name: 'flash_otp_key_o.key', wave: '0..|.30.|.40'}, - {name: 'flash_otp_key_o.seed_valid', wave: '0..|.10.|.10'}, -]} -``` - -The keys are derived from the FLASH_DATA_KEY_SEED and FLASH_ADDR_KEY_SEED values stored in the `SECRET1` partition using the [scrambling primitive](#scrambling-datapath). -If the key seeds have not yet been provisioned, the keys are derived from all-zero constants, and the `flash_otp_key_o.seed_valid` signal will be set to 0 in the response. -The resulting scrambling key is still ephemeral (i.e., it is derived using entropy from CSRNG) and okay to be used. - -Note that the req/ack protocol runs on the OTP clock. -It is the task of the scrambling device to synchronize the handshake protocol by instantiating the `prim_sync_reqack.sv` primitive as shown below. - -![OTP Key Req Ack](../doc/otp_ctrl_key_req_ack.svg) - -Note that the key and nonce output signals on the OTP controller side are guaranteed to remain stable for at least 62 OTP clock cycles after the `ack` signal is pulsed high, because the derivation of a 64bit half-key takes at least two passes through the 31-cycle PRESENT primitive. -Hence, if the scrambling device clock is faster or in the same order of magnitude as the OTP clock, the data can be directly sampled upon assertion of `src_ack_o`. -If the scrambling device runs on a significantly slower clock than OTP, an additional register (as indicated with dashed grey lines in the figure) has to be added. - -### Interfaces to SRAM and OTBN Scramblers - -The interfaces to the SRAM and OTBN scrambling devices follow a req / ack protocol, where the scrambling device first requests a new ephemeral key by asserting the request channel (`sram_otp_key_i[*]`, `otbn_otp_key_i`). -The OTP controller then fetches entropy from EDN and derives an ephemeral key using the SRAM_DATA_KEY_SEED and the [PRESENT scrambling data path](#scrambling-datapath). -Finally, the OTP controller returns a fresh ephemeral key via the response channels (`sram_otp_key_o[*]`, `otbn_otp_key_o`), which complete the req / ack handshake. -The wave diagram below illustrates this process for the OTBN scrambling device. - -```wavejson -{signal: [ - {name: 'clk_i', wave: 'p.......'}, - {name: 'otbn_otp_key_i.req', wave: '01.|..0.'}, - {name: 'otbn_otp_key_o.ack', wave: '0..|.10.'}, - {name: 'otbn_otp_key_o.nonce', wave: '0..|.30.'}, - {name: 'otbn_otp_key_o.key', wave: '0..|.30.'}, - {name: 'otbn_otp_key_o.seed_valid', wave: '0..|.10.'}, -]} -``` - -If the key seeds have not yet been provisioned, the keys are derived from all-zero constants, and the `*.seed_valid` signal will be set to 0 in the response. -The resulting scrambling key is still ephemeral (i.e., it is derived using entropy from CSRNG) and okay to be used. -It should be noted that this mechanism requires the EDN and entropy distribution network to be operational, and a key derivation request will block if they are not. - -Note that the req/ack protocol runs on the OTP clock. -It is the task of the scrambling device to perform the synchronization as described in the previous subsection on the [flash scrambler interface](#interface-to-flash-scrambler). - -### Hardware Config Bits - -The bits of the HW_CFG* partitions are output via the `otp_ctrl_otp_broadcast_o` struct. -IPs that consume collateral stored in this partition shall connect to this struct via the topgen feature, and break out the appropriate bits by either accessing the correct index or using the struct fields. -These fields are autogenerated from the memory map items allocated to the HW_CFG* partitions, and the autogenerated struct type can be found in the `otp_ctrl_part_pkg.sv` package. -Note that it is the task of the receiving IP to synchronize these bits accordingly to the local clock. -For convenience, a valid bit is also available in that struct. -The valid bit indicates that the HW_CFG* partitions have initialized. - -## Parameter and Memory Map Changes after D3/V3 - -Note that all instantiation parameters can be changed without affecting D3/V3 status of the module. -Similarly, it is permissible to change the contents (partition size, adding and removing items) of the `CREATOR_SW_CFG`, `OWNER_SW_CFG` and `HW_CFG*` partitions without affecting D3 status. -Note however that partition size changes may affect V3 coverage metrics, hence if the size any of the above three partitions is changed, V3 needs to be re-assessed. diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_behavioral_model.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_behavioral_model.svg deleted file mode 100644 index a5dab4a4bfc21..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_behavioral_model.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_blockdiag.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_blockdiag.svg deleted file mode 100644 index f2169883ce4b2..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_blockdiag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_buf_part_fsm.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_buf_part_fsm.svg deleted file mode 100644 index d06037468e3c2..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_buf_part_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_dai_fsm.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_dai_fsm.svg deleted file mode 100644 index f84a80cc0f0f0..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_dai_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_digest_mechanism.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_digest_mechanism.svg deleted file mode 100644 index dac2323afce33..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_digest_mechanism.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_digests.md b/hw/ip/otp_ctrl/doc/otp_ctrl_digests.md deleted file mode 100644 index ddb4029750b9d..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_digests.md +++ /dev/null @@ -1,17 +0,0 @@ - - -| Digest Name | Affected Partition | Calculated by HW | -|:---------------------------------------------------------------------------:|:-------------------------:|:------------------:| -| [VENDOR_TEST_DIGEST](#Reg_vendor_test_digest_0) | VENDOR_TEST | no | -| [CREATOR_SW_CFG_DIGEST](#Reg_creator_sw_cfg_digest_0) | CREATOR_SW_CFG | no | -| [OWNER_SW_CFG_DIGEST](#Reg_owner_sw_cfg_digest_0) | OWNER_SW_CFG | no | -| [ROT_CREATOR_AUTH_CODESIGN_DIGEST](#Reg_rot_creator_auth_codesign_digest_0) | ROT_CREATOR_AUTH_CODESIGN | no | -| [ROT_CREATOR_AUTH_STATE_DIGEST](#Reg_rot_creator_auth_state_digest_0) | ROT_CREATOR_AUTH_STATE | no | -| [HW_CFG0_DIGEST](#Reg_hw_cfg0_digest_0) | HW_CFG0 | yes | -| [HW_CFG1_DIGEST](#Reg_hw_cfg1_digest_0) | HW_CFG1 | yes | -| [SECRET0_DIGEST](#Reg_secret0_digest_0) | SECRET0 | yes | -| [SECRET1_DIGEST](#Reg_secret1_digest_0) | SECRET1 | yes | -| [SECRET2_DIGEST](#Reg_secret2_digest_0) | SECRET2 | yes | diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_field_descriptions.md b/hw/ip/otp_ctrl/doc/otp_ctrl_field_descriptions.md deleted file mode 100644 index 700506ae7c1b7..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_field_descriptions.md +++ /dev/null @@ -1,101 +0,0 @@ - - -| Partition | Item | Size [B] | Description | -|:-------------------------:|:-----------------------------------------------:|:----------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| CREATOR_SW_CFG | CREATOR_SW_CFG_AST_CFG | 156 | AST configuration data. These values get blindly copied to the AST CSRs during ROM execution. | -| | CREATOR_SW_CFG_AST_INIT_EN | 4 | Controls whether or not the CREATOR_SW_CFG_AST_CFG values get copied to the AST CSRs during ROM execution. A value of kMultiBitBool4True enables copying; all other values disable. | -| | CREATOR_SW_CFG_ROM_EXT_SKU | 4 | SKU identifier metadata. Unused by SiliconCreator software. | -| | CREATOR_SW_CFG_SIGVERIFY_SPX_EN | 4 | Controls whether or not SPHINCS+ signature verification will be executed when the ROM attempts to boot the ROM_EXT. A value of kSigverifySpxDisabledOtp disables SPHINCS+ signature verification, while all other values enable it. Note, SPHINCS+ signature verification is always disabled in TEST_UNLOCKED* LC states. | -| | CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG | 4 | The default scrambling, ECC, and high endurance configuration settings for flash data pages set during ROM execution. | -| | CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG | 4 | The scrambling, ECC, and high endurance configuration settings for the boot data flash info pages set during ROM execution. | -| | CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE | 4 | Scrambling and ECC configuration overrides (set by the ROM) for the Creator and OwnerSeed flash info pages (pages 1 and 2 in partition 0) that are hardwired to the keygmr. By default, scrambling and ECC on these flash info pages must be enabled in order to successfully crank the keygmr (in the ROM_EXT). However, values of kMultiBitBool4True for each subfield in this field will disable this requirement. See the HW_INFO_CFG_OVERRIDE flash_ctrl CSR for more details. | -| | CREATOR_SW_CFG_RNG_EN | 4 | Whether or not to enable use of hardware generated entropy (from the entropy complex via EDN) in the `rnd_uint32` function. A value of kHardenedBoolTrue enables the use of hardware generated entropy, while all other values disable. | -| | CREATOR_SW_CFG_JITTER_EN | 4 | Whether or not to enable clock jitter. A value of kMultiBitBool4False disables, while all other values enable. | -| | CREATOR_SW_CFG_RET_RAM_RESET_MASK | 4 | Reset reason mask used to initialize (by overwriting with random data) retention SRAM during ROM execution. A value of 0 only initializes retention SRAM on power-on-resets.See rstmgr RESET_INFO CSR documentation for more details. | -| | CREATOR_SW_CFG_MANUF_STATE | 4 | Manufacturing state binding field. For use by SiliconCreators or SiliconOwners to bind ROM_EXT images to a specific device or set of devices. | -| | CREATOR_SW_CFG_ROM_EXEC_EN | 4 | Whether or not to enable execution of ROM. A value of 0 disables, while all other values enable. This enables provisioning flows to attach JTAG connections and halt the CPU before the device has been fully provisioned. All SKUs should set this field to a non-zero value. Provisioning flows shall take care to program this field at the appropriate time during. | -| | CREATOR_SW_CFG_CPUCTRL | 4 | Value to write to the Ibex CPUCTRL CSR during ROM execution. This field controls settings such as ICACHE enablement. See Ibex documentation for more information. | -| | CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT | 4 | Value of the min_security_version_rom_ext field of the default boot data. | -| | CREATOR_SW_CFG_MIN_SEC_VER_BL0 | 4 | Value of the min_security_version_bl0 field of the default boot data. | -| | CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN | 4 | Whether or not to enable the default boot data in PROD and PROD_END life cycle states. A value of kHardenedBoolTrue enables, all other values disable. If left disabled, provisioning flows are required to setup boot data pages prior to enabling ROM execution. | -| | CREATOR_SW_CFG_RMA_SPIN_EN | 4 | Whether or not to enable a busy-wait delay loop in the ROM, when a specific SW strapping configuration is applied during boot, to provide time to trigger an RMA lifecycle transition over JTAG. A value of kHardenedBoolTrue enables, all other values disable. | -| | CREATOR_SW_CFG_RMA_SPIN_CYCLES | 4 | The number of Ibex clock cycles to spin for when waiting for an RMA transition. Used in combination with the CREATOR_SW_CFG_RMA_SPIN_EN field. | -| | CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS | 4 | The repetition count health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS | 4 | The repetition count symbol health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS | 4 | The adaptive proportion health test high thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS | 4 | The adaptive proportion health test low thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS | 4 | The bucket health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS | 4 | The Markov health test high thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS | 4 | The Markov health test low thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS | 4 | The external health test high thresholds to enable the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS | 4 | The external health test low thresholds to enable the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_ALERT_THRESHOLD | 4 | The alert threshold to configure the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST | 4 | A CRC32 digest of all entropy_src health test threshold configuration fields above. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details. | -| | CREATOR_SW_CFG_SRAM_KEY_RENEW_EN | 4 | Whether or not the ROM should request SRAM to be rescrambled with a new key on every boot. kHardenedBoolFalse disables, while all other values enable. | -| | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN | 4 | Enablement of the ROM_EXT immutable code section. A value of kHardenedBoolTrue enables the feature. All other values disable it. | -| | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET | 4 | Relative offset from the start of the ROM_EXT slot to find the immutable code section at. | -| | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH | 4 | Length (in bytes) of the immutable code section. | -| | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH | 32 | SHA256 hash of the immutable ROM_EXT section. | -| | CREATOR_SW_CFG_RESERVED | 32 | Unused bits in the CREATOR_SW_CFG OTP partition. These can be claimed by software as needed. | -| OWNER_SW_CFG | OWNER_SW_CFG_ROM_ERROR_REPORTING | 4 | The shutdown error reporting verbosity used by the ROM. Should be configured to one of several `shutdown_error_redact_t` values. See `sw/device/silicon_creator/lib/shutdown.h` for more details. | -| | OWNER_SW_CFG_ROM_BOOTSTRAP_DIS | 4 | Whether or not to disable ROM bootstrap mechanism. A value of kHardenedBoolTrue disable bootstrap mechanism in the ROM, while all other values enable it. Note, the provisioning flow should take care when to program this field if it is used by a SKU, as there is no way to get firmware into flash in a PROD LC state if a valid ROM_EXT does not already exist in flash once this value is configured to true. | -| | OWNER_SW_CFG_ROM_ALERT_CLASS_EN | 4 | A four byte packed field, where each byte controls whether or not the ROM enables each alert class (A through D) of the alert_handler. The byte-sized subfields are arranged from D to A, MSB to LSB. Each byte should be set to an `alert_enable_t` value accordingly. See the alert_handler documentation for more details. | -| | OWNER_SW_CFG_ROM_ALERT_ESCALATION | 4 | A four byte packed field, where each byte controls the escalation configuration for each alert class (A through D) of the alert_handler configured by the ROM. The byte-sized subfields are arranged from D to A, MSB to LSB. Each byte should be set to an `alert_escalate_t` value accordingly. See the alert_handler documentation for more details. | -| | OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION | 320 | The alert classifications (A through D) for each alert source of the alert_handler to be configured by the ROM. The field consists of a contiguous 320-byte block, or 80 32-bit words. The four bytes in each word encode the configuration of a single alert source across four lifecycle states, in order from LSB to MSB: PROD, PROD_END, DEV, and RMA. Each byte should be set to an `alert_class_t` value accordingly. The order of the 80 32-bit words, from LSB to MSB can be found in the EARLGREY_ALERTS list in `rules/const.bzl`. See the alert_handler documentation for more details. | -| | OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION | 64 | Same as the `OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION` field, except these configuration correspond to the local alert sources found in the `EARLGREY_LOC_ALERTS list in `rules/const.bzl`. | -| | OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH | 16 | The alert accumulation threshold values for each alert class (A through D) of the alert_handler to be configured by the ROM. This field consists of four 32-bit words encoding the accumulation thresholds for each alert class A through D arranged LSW to MSW. See the alert_handler documentation for more details. | -| | OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES | 16 | Same as the `OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH` field, except each value corresponds to the interrupt timeout configuration of an alert class. | -| | OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES | 64 | The alert escalation phase durations, measured in clock cycles, the ROM will configure the four alert phases for each alert class of the alert_handler. This field consists of a contiguous 64-byte block, or an array of four 128-bit fields. Each 128-bit subfield encodes four 32-bit words that contain the alert phase cycle count configurations for alert escalation phases 0 to 3, from LSW to MSW. Each 128-bit subfield is contains all cofigurations for a single alert class, arranged from class A to D, from LS to MS. For example, the cycle durations of each escalation phase in this field should be configured as such, from LSB to MSB: ......... . See the alert_handler documentation for more details. | -| | OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD | 4 | The expected CRC32 digest over all of the alert_handler configurations set up by the ROM for a device operating in the PROD LC state. The ROM reads this field and checks it against a digest it computes over the alert_handler configuration it programmed. This field is expected to be automatically computed by the `otp_alert_digest()` Bazel rule. See the `alert_config_crc32()` function in the SiliconCreator alert_handler driver for more details on what configurations are included in this digest. | -| | OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END | 4 | Same as the `OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD` field, except the expected digest is for chips operating in the PROD_END LC state. | -| | OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV | 4 | Same as the `OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD` field, except the expected digest is for chips operating in the DEV LC state. | -| | OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA | 4 | Same as the `OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD` field, except the expected digest is for chips operating in the RMA LC state. | -| | OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES | 4 | Watchdog timer bite threshold (in cycles) configured by the ROM. | -| | OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN | 4 | Whether or not to configure the attestation SW binding CSRs of the keymgr with the value in ROM_EXT manifest or the measurement of the OTP CreatorSwCfg, OwnerSwCfg, and secure boot key integrity digest. A value of kHardenedBoolTrue uses the ROM computed OTP measurements, while all other values trigger the use of the binding values included in the ROM_EXT manifest. | -| | OWNER_SW_CFG_MANUF_STATE | 4 | Manufacturing state binding field. For use by SiliconCreators or SiliconOwners to bind BL0 images to a specific device or set of devices. | -| | OWNER_SW_CFG_ROM_RSTMGR_INFO_EN | 4 | A two byte packed word that indicates the expected rstmgr alert and CPU info dump enable states, configured in the rstmgr's ALERT_INFO_CTRL and CPU_INFO_CTRL CSRs respectively. The expected format of this fields is {0,0,kHardenedBool*,kHardenedBool*}, read MSB to LSB, where the left most kHardenedBool* entry indicates the expected enablement state of the ALERT_INFO_CTRL, and the right most indicates the enablement state of the CPU_INFO_CTRL. Since the ROM expects both to be disabled upon handing over execution control to the ROM_EXT, this entire OTP field **should be left unprovisioned, or set to all 0**. | -| | OWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN | 4 | Unused. Set to 0. | -| | OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG | 12 | Alert configuration values for the sensor_ctrl block that will be configured by the ROM. This field is 12 bytes long, where each byte contains two 4-bit packed subfields, encoding two four bit boolean values (kMultiBitBool4False or kMultiBitBool4True), as follows (read MSB to LSB): {fatality, enablement}. For example, the byte 0x69 would encode the alert is: 1) recoverable, and 2) disabled. Currently, there are only 11 alerts in sensor_ctrl to configure, thus only the least significant bytes in this field are used. | -| | OWNER_SW_CFG_ROM_SRAM_READBACK_EN | 4 | This field encodes the enablements of the readback security features for the main and retention SRAMs to be configured by the ROM. This field is four bytes, but the LSB contains two 4-bit packed kMultiBitBool4* values that indicate the enablement of the feature for the retention SRAM and main SRAM, from MSB to LSB respectively. See the READBACK CSR of the sram_ctrl for more details on this feature. | -| | OWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN | 4 | Whether or not the ROM should preserve the reset reasons CSR state in the rstmgr, or clear it. A value of kHardenedBoolTrue preserves the CSR, while other values trigger the ROM to clear the CSR after copying the reason to the retention SRAM. | -| | OWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE | 4 | Two packed 16-bit values that indicate whether the ROM should perform a validation check on the the reset reasons during boot. The validation check is a hardening mechanism that checks the reset reasons for consistency at two different points in time. Both packed values should be the same. Values of kHardenedBoolFalse will instruct the ROM to skip the reset reasons validation check, while all other values will instruct the ROM to perform the check. | -| | OWNER_SW_CFG_ROM_BANNER_EN | 4 | Whether or not the ROM should print a banner message to the console UART during boot. A value of kHardenedBoolFalse disables the message printing, while all other values enable it. | -| | OWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN | 4 | Whether or not the ROM should use the flash ECC exception handler during execution. A value of kHardenedBoolTrue allows the ROM to use an the exception handler that recovers gracefully and continues the boot process if a flash ECC error is encountered during verification of a specific ROM_EXT slot. This enables the ROM to attempt booting the next ROM_EXT slot if the first slot attempted has been corrupted. All other values trigger default ROM exception handling, which is all exceptions trigger a chip shutdown and reset. | -| | OWNER_SW_CFG_RESERVED | 128 | Unused bits in the OWNER_SW_CFG OTP partition. These can be claimed by software as needed. | -| ROT_CREATOR_AUTH_CODESIGN | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE0 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY0 | 64 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE1 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY1 | 64 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE2 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY2 | 64 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE3 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY3 | 64 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE0 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY0 | 32 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG0 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE1 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY1 | 32 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG1 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE2 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY2 | 32 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG2 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE3 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY3 | 32 | | -| | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG3 | 4 | | -| | ROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH | 32 | | -| ROT_CREATOR_AUTH_STATE | ROT_CREATOR_AUTH_STATE_ECDSA_KEY0 | 4 | | -| | ROT_CREATOR_AUTH_STATE_ECDSA_KEY1 | 4 | | -| | ROT_CREATOR_AUTH_STATE_ECDSA_KEY2 | 4 | | -| | ROT_CREATOR_AUTH_STATE_ECDSA_KEY3 | 4 | | -| | ROT_CREATOR_AUTH_STATE_SPX_KEY0 | 4 | | -| | ROT_CREATOR_AUTH_STATE_SPX_KEY1 | 4 | | -| | ROT_CREATOR_AUTH_STATE_SPX_KEY2 | 4 | | -| | ROT_CREATOR_AUTH_STATE_SPX_KEY3 | 4 | | -| HW_CFG0 | DEVICE_ID | 32 | Unique device identifier that is always exposed through the lifecycle JTAG tap. See OpenTitan documentation on Device Identifiers. | -| | MANUF_STATE | 32 | Field to capture manufacturing status. Currently unused. Set to 0. | -| HW_CFG1 | EN_SRAM_IFETCH | 1 | Enablement of execute from SRAM switch in the sram_ctrl (see EXEC CSR). A kMultiBitBool8True value enables, while all other values disable. | -| | EN_CSRNG_SW_APP_READ | 1 | Enablement of CSRNG software application interface. A kMultiBitBool8True value enables, while all other values disable. Enablement is required to extract output from CSRNG via software. | -| | DIS_RV_DM_LATE_DEBUG | 1 | Disablement of RV_DM late debug feature (see rv_dm documentation). A kMultiBitBool8True disables the late debug feature and renders the rv_dm fully ungated in DEV lifecycle states. All other values gate rv_dm reachability based on the value of LATE_DEBUG_ENABLE CSR in the rv_dm block. | diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_kdi_fsm.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_kdi_fsm.svg deleted file mode 100644 index 0f91a212c440d..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_kdi_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_key_req_ack.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_key_req_ack.svg deleted file mode 100644 index c5cd58b5c1578..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_key_req_ack.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_lci_fsm.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_lci_fsm.svg deleted file mode 100644 index 63459e87af287..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_lci_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_mmap.md b/hw/ip/otp_ctrl/doc/otp_ctrl_mmap.md deleted file mode 100644 index ee030099dbeee..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_mmap.md +++ /dev/null @@ -1,122 +0,0 @@ - - -| Index | Partition | Size [B] | Access Granule | Item | Byte Address | Size [B] | -|:-------:|:-------------------------:|:----------:|:----------------:|:---------------------------------------------------------------------------:|:--------------:|:----------:| -| 0 | VENDOR_TEST | 64 | 32bit | SCRATCH | 0x000 | 56 | -| | | | 64bit | [VENDOR_TEST_DIGEST](#Reg_vendor_test_digest_0) | 0x038 | 8 | -| 1 | CREATOR_SW_CFG | 368 | 32bit | CREATOR_SW_CFG_AST_CFG | 0x040 | 156 | -| | | | 32bit | CREATOR_SW_CFG_AST_INIT_EN | 0x0DC | 4 | -| | | | 32bit | CREATOR_SW_CFG_ROM_EXT_SKU | 0x0E0 | 4 | -| | | | 32bit | CREATOR_SW_CFG_SIGVERIFY_SPX_EN | 0x0E4 | 4 | -| | | | 32bit | CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG | 0x0E8 | 4 | -| | | | 32bit | CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG | 0x0EC | 4 | -| | | | 32bit | CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE | 0x0F0 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_EN | 0x0F4 | 4 | -| | | | 32bit | CREATOR_SW_CFG_JITTER_EN | 0x0F8 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RET_RAM_RESET_MASK | 0x0FC | 4 | -| | | | 32bit | CREATOR_SW_CFG_MANUF_STATE | 0x100 | 4 | -| | | | 32bit | CREATOR_SW_CFG_ROM_EXEC_EN | 0x104 | 4 | -| | | | 32bit | CREATOR_SW_CFG_CPUCTRL | 0x108 | 4 | -| | | | 32bit | CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT | 0x10C | 4 | -| | | | 32bit | CREATOR_SW_CFG_MIN_SEC_VER_BL0 | 0x110 | 4 | -| | | | 32bit | CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN | 0x114 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RMA_SPIN_EN | 0x118 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RMA_SPIN_CYCLES | 0x11C | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS | 0x120 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS | 0x124 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS | 0x128 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS | 0x12C | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS | 0x130 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS | 0x134 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS | 0x138 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS | 0x13C | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS | 0x140 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_ALERT_THRESHOLD | 0x144 | 4 | -| | | | 32bit | CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST | 0x148 | 4 | -| | | | 32bit | CREATOR_SW_CFG_SRAM_KEY_RENEW_EN | 0x14C | 4 | -| | | | 32bit | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN | 0x150 | 4 | -| | | | 32bit | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET | 0x154 | 4 | -| | | | 32bit | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH | 0x158 | 4 | -| | | | 32bit | CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH | 0x15C | 32 | -| | | | 32bit | CREATOR_SW_CFG_RESERVED | 0x17C | 32 | -| | | | 64bit | [CREATOR_SW_CFG_DIGEST](#Reg_creator_sw_cfg_digest_0) | 0x1A8 | 8 | -| 2 | OWNER_SW_CFG | 712 | 32bit | OWNER_SW_CFG_ROM_ERROR_REPORTING | 0x1B0 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_BOOTSTRAP_DIS | 0x1B4 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_CLASS_EN | 0x1B8 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_ESCALATION | 0x1BC | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION | 0x1C0 | 320 | -| | | | 32bit | OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION | 0x300 | 64 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH | 0x340 | 16 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES | 0x350 | 16 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES | 0x360 | 64 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD | 0x3A0 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END | 0x3A4 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV | 0x3A8 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA | 0x3AC | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES | 0x3B0 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN | 0x3B4 | 4 | -| | | | 32bit | OWNER_SW_CFG_MANUF_STATE | 0x3B8 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_RSTMGR_INFO_EN | 0x3BC | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN | 0x3C0 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG | 0x3C4 | 12 | -| | | | 32bit | OWNER_SW_CFG_ROM_SRAM_READBACK_EN | 0x3D0 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN | 0x3D4 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE | 0x3D8 | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_BANNER_EN | 0x3DC | 4 | -| | | | 32bit | OWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN | 0x3E0 | 4 | -| | | | 32bit | OWNER_SW_CFG_RESERVED | 0x3E4 | 128 | -| | | | 64bit | [OWNER_SW_CFG_DIGEST](#Reg_owner_sw_cfg_digest_0) | 0x470 | 8 | -| 3 | ROT_CREATOR_AUTH_CODESIGN | 472 | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE0 | 0x478 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY0 | 0x47C | 64 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE1 | 0x4BC | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY1 | 0x4C0 | 64 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE2 | 0x500 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY2 | 0x504 | 64 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE3 | 0x544 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY3 | 0x548 | 64 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE0 | 0x588 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY0 | 0x58C | 32 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG0 | 0x5AC | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE1 | 0x5B0 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY1 | 0x5B4 | 32 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG1 | 0x5D4 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE2 | 0x5D8 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY2 | 0x5DC | 32 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG2 | 0x5FC | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE3 | 0x600 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY3 | 0x604 | 32 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG3 | 0x624 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH | 0x628 | 32 | -| | | | 64bit | [ROT_CREATOR_AUTH_CODESIGN_DIGEST](#Reg_rot_creator_auth_codesign_digest_0) | 0x648 | 8 | -| 4 | ROT_CREATOR_AUTH_STATE | 40 | 32bit | ROT_CREATOR_AUTH_STATE_ECDSA_KEY0 | 0x650 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_ECDSA_KEY1 | 0x654 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_ECDSA_KEY2 | 0x658 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_ECDSA_KEY3 | 0x65C | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_SPX_KEY0 | 0x660 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_SPX_KEY1 | 0x664 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_SPX_KEY2 | 0x668 | 4 | -| | | | 32bit | ROT_CREATOR_AUTH_STATE_SPX_KEY3 | 0x66C | 4 | -| | | | 64bit | [ROT_CREATOR_AUTH_STATE_DIGEST](#Reg_rot_creator_auth_state_digest_0) | 0x670 | 8 | -| 5 | HW_CFG0 | 72 | 32bit | DEVICE_ID | 0x678 | 32 | -| | | | 32bit | MANUF_STATE | 0x698 | 32 | -| | | | 64bit | [HW_CFG0_DIGEST](#Reg_hw_cfg0_digest_0) | 0x6B8 | 8 | -| 6 | HW_CFG1 | 16 | 32bit | EN_SRAM_IFETCH | 0x6C0 | 1 | -| | | | 32bit | EN_CSRNG_SW_APP_READ | 0x6C1 | 1 | -| | | | 32bit | DIS_RV_DM_LATE_DEBUG | 0x6C2 | 1 | -| | | | 64bit | [HW_CFG1_DIGEST](#Reg_hw_cfg1_digest_0) | 0x6C8 | 8 | -| 7 | SECRET0 | 40 | 64bit | TEST_UNLOCK_TOKEN | 0x6D0 | 16 | -| | | | 64bit | TEST_EXIT_TOKEN | 0x6E0 | 16 | -| | | | 64bit | [SECRET0_DIGEST](#Reg_secret0_digest_0) | 0x6F0 | 8 | -| 8 | SECRET1 | 88 | 64bit | FLASH_ADDR_KEY_SEED | 0x6F8 | 32 | -| | | | 64bit | FLASH_DATA_KEY_SEED | 0x718 | 32 | -| | | | 64bit | SRAM_DATA_KEY_SEED | 0x738 | 16 | -| | | | 64bit | [SECRET1_DIGEST](#Reg_secret1_digest_0) | 0x748 | 8 | -| 9 | SECRET2 | 88 | 64bit | RMA_TOKEN | 0x750 | 16 | -| | | | 64bit | CREATOR_ROOT_KEY_SHARE0 | 0x760 | 32 | -| | | | 64bit | CREATOR_ROOT_KEY_SHARE1 | 0x780 | 32 | -| | | | 64bit | [SECRET2_DIGEST](#Reg_secret2_digest_0) | 0x7A0 | 8 | -| 10 | LIFE_CYCLE | 88 | 32bit | LC_TRANSITION_CNT | 0x7A8 | 48 | -| | | | 32bit | LC_STATE | 0x7D8 | 40 | diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_overview.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_overview.svg deleted file mode 100644 index ef2adaf1f99f8..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_overview.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_partitions.md b/hw/ip/otp_ctrl/doc/otp_ctrl_partitions.md deleted file mode 100644 index e19aad14717b8..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_partitions.md +++ /dev/null @@ -1,57 +0,0 @@ - - -| Partition | Secret | Buffered | Integrity | WR Lockable | RD Lockable | Description | -|:-------------------------:|:--------:|:----------:|:-----------:|:-------------:|:-------------:|:--------------------------------------------------------------------| -| VENDOR_TEST | no | no | no | yes (Digest) | yes (CSR) | Vendor test partition. | -| | | | | | | This is reserved for manufacturing smoke checks. The OTP wrapper | -| | | | | | | control logic inside prim_otp is allowed to read/write to this | -| | | | | | | region. ECC uncorrectable errors seen on the functional prim_otp | -| | | | | | | interface will not lead to an alert for this partition. | -| | | | | | | Instead, such errors will be reported as correctable ECC errors. | -| CREATOR_SW_CFG | no | no | yes | yes (Digest) | yes (CSR) | Software configuration partition. | -| | | | | | | This is for device-specific calibration data, e.g, clock, LDO, RNG, | -| | | | | | | and configuration settings set by the ROM. | -| OWNER_SW_CFG | no | no | yes | yes (Digest) | yes (CSR) | Software configuration partition. | -| | | | | | | This contains data that changes software behavior in the ROM, for | -| | | | | | | example enabling defensive features in ROM or selecting failure | -| | | | | | | modes if verification fails. | -| ROT_CREATOR_AUTH_CODESIGN | no | no | yes | yes (Digest) | yes (CSR) | This OTP partition is used to store four P-256 keys | -| | | | | | | and four Sphincs+ keys. The partition requires 464 | -| | | | | | | bytes of software visible storage. The partition is | -| | | | | | | locked at manufacturing time to protect against | -| | | | | | | malicious write attempts. | -| ROT_CREATOR_AUTH_STATE | no | no | yes | yes (Digest) | yes (CSR) | This OTP partition is used to capture the state of | -| | | | | | | each key slot. Each key can be in one of the | -| | | | | | | following states: BLANK, ENABLED, DISABLED. The | -| | | | | | | encoded values are such that transitions between | -| | | | | | | BLANK -> ENABLED -> DISABLED are possible without | -| | | | | | | causing ECC errors (this is a mechanism similar to | -| | | | | | | how we manage life cycle state transitions). The | -| | | | | | | partition is left unlocked to allow STATE updates in | -| | | | | | | the field. The ROM_EXT is required to lock access to | -| | | | | | | the OTP Direct Access Interface to prevent DoS | -| | | | | | | attacks from malicious code executing on Silicon | -| | | | | | | Owner partitions. DAI write locking is available in | -| | | | | | | EarlGrey. | -| HW_CFG0 | no | yes | yes | yes (Digest) | no | Hardware configuration 0 partition. | -| | | | | | | This contains a device identifier and manufacturing state. | -| HW_CFG1 | no | yes | yes | yes (Digest) | no | Hardware configuration 1 partition. | -| | | | | | | This contains several hardware feature switches. | -| SECRET0 | yes | yes | yes | yes (Digest) | yes (Digest) | Secret partition 0. | -| | | | | | | This contains TEST lifecycle unlock tokens. | -| SECRET1 | yes | yes | yes | yes (Digest) | yes (Digest) | Secret partition 1. | -| | | | | | | This contains SRAM and flash scrambling keys. | -| SECRET2 | yes | yes | yes | yes (Digest) | yes (Digest) | Secret partition 2. | -| | | | | | | This contains RMA unlock token, creator root key, and creator seed. | -| LIFE_CYCLE | no | yes | yes | no | no | Lifecycle partition. | -| | | | | | | This contains lifecycle transition count and state. This partition | -| | | | | | | cannot be locked since the life cycle state needs to advance to RMA | -| | | | | | | in-field. Note that while this partition is not marked secret, it | -| | | | | | | is not readable nor writeable via the DAI. Only the LC controller | -| | | | | | | can access this partition, and even via the LC controller it is not | -| | | | | | | possible to read the raw manufacturing life cycle state in encoded | -| | | | | | | form, since that encoding is considered a netlist secret. The LC | -| | | | | | | controller only exposes a decoded version of this state. | diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_prim_otp.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_prim_otp.svg deleted file mode 100644 index df6b31f078ed9..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_prim_otp.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/otp_ctrl_unbuf_part_fsm.svg b/hw/ip/otp_ctrl/doc/otp_ctrl_unbuf_part_fsm.svg deleted file mode 100644 index cd1a7ca1d7052..0000000000000 --- a/hw/ip/otp_ctrl/doc/otp_ctrl_unbuf_part_fsm.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/doc/programmers_guide.md b/hw/ip/otp_ctrl/doc/programmers_guide.md deleted file mode 100644 index 58bf230e2404f..0000000000000 --- a/hw/ip/otp_ctrl/doc/programmers_guide.md +++ /dev/null @@ -1,261 +0,0 @@ -# Programmer's Guide - -During provisioning and manufacturing, SW interacts with the OTP controller mostly through the Direct Access Interface (DAI), which is described below. -Afterwards during production, SW is expected to perform only read accesses via the exposed CSRs and CSR windows, since all write access to the partitions has been locked down. - -The following sections provide some general guidance, followed by an explanation of the DAI and a detailed OTP memory map. -Typical programming sequences are explained at the end of the Programmer's guide. - -## General Guidance - -### Initialization - -The OTP controller initializes automatically upon power-up and is fully operational by the time the processor boots. -The only initialization steps that SW should perform are: - -1. Check that the OTP controller has successfully initialized by reading [`STATUS`](registers.md#status). I.e., make sure that none of the ERROR bits are set, and that the DAI is idle ([`STATUS.DAI_IDLE`](registers.md#status)). -2. Set up the periodic background checks: - - Choose whether to enable periodic [background checks](#partition-checks) by programming nonzero mask values to [`INTEGRITY_CHECK_PERIOD`](registers.md#integrity_check_period) and [`CONSISTENCY_CHECK_PERIOD`](registers.md#consistency_check_period). - - Choose whether such checks shall be subject to a timeout by programming a nonzero timeout cycle count to [`CHECK_TIMEOUT`](registers.md#check_timeout). - - It is recommended to lock down the background check registers via [`CHECK_REGWEN`](registers.md#check_regwen), once the background checks have been set up. - -If needed, one-off integrity and consistency checks can be triggered via [`CHECK_TRIGGER`](registers.md#check_trigger). -If this functionality is not needed, it is recommended to lock down the trigger register via [`CHECK_TRIGGER_REGWEN`](registers.md#check_trigger_regwen). - -Later on during the boot process, SW may also choose to block read access to the SW managed partitions via the associated partition lock registers, e.g. [`CREATOR_SW_CFG_READ_LOCK`](registers.md#creator_sw_cfg_read_lock) or [`OWNER_SW_CFG_READ_LOCK`](registers.md#owner_sw_cfg_read_lock). - -### Reset Considerations - -It is important to note that values in OTP **can be corrupted** if a reset occurs during a programming operation. -This should be of minor concern for SW, however, since all partitions except for the LIFE_CYCLE partition are being provisioned in secure and controlled environments, and not in the field. -The LIFE_CYCLE partition is the only partition that is modified in the field - but that partition is entirely owned by the life cycle controller and not by SW. - -### Programming Already Programmed Regions - -OTP words cannot be programmed twice, and doing so may damage the memory array. -Hence the OTP controller performs a blank check and returns an error if a write operation is issued to an already programmed location. - -### Potential Side-Effects on Flash via Life Cycle - -It should be noted that the locked status of the partition holding the creator root key (i.e., the value of the [`SECRET2_DIGEST_0`](registers.md#secret2_digest)) determines the ID_STATUS of the device, which in turn determines SW accessibility of creator seed material in flash and OTP. -That means that creator-seed-related collateral needs to be provisioned to Flash **before** the OTP digest lockdown mechanism is triggered, since otherwise accessibility to the corresponding flash region is lost. -See the [life cycle controller documentation](../../lc_ctrl/README.md#id-state-of-the-device) for more details. - -## Direct Access Interface - -OTP has to be programmed via the Direct Access Interface, which is comprised of the following CSRs: - -CSR Name | Description --------------------------------------|------------------------------------ -[`DIRECT_ACCESS_WDATA_0`](registers.md#direct_access_wdata) | Low 32bit word to be written. -[`DIRECT_ACCESS_WDATA_1`](registers.md#direct_access_wdata) | High 32bit word to be written. -[`DIRECT_ACCESS_RDATA_0`](registers.md#direct_access_rdata) | Low 32bit word that has been read. -[`DIRECT_ACCESS_RDATA_1`](registers.md#direct_access_rdata) | High 32bit word that has been read. -[`DIRECT_ACCESS_ADDRESS`](registers.md#direct_access_address) | byte address for the access. -[`DIRECT_ACCESS_CMD`](registers.md#direct_access_cmd) | Command register to trigger a read or a write access. -[`DIRECT_ACCESS_REGWEN`](registers.md#direct_access_regwen) | Write protection register for DAI. - -See further below for a detailed [Memory Map](#direct-access-memory-map) of the address space accessible via the DAI. - -### Readout Sequence - -A typical readout sequence looks as follows: - -1. Check whether the DAI is idle by reading the [`STATUS`](registers.md#status) register. -2. Write the byte address for the access to [`DIRECT_ACCESS_ADDRESS`](registers.md#direct_access_address). -Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit. -3. Trigger a read command by writing 0x1 to [`DIRECT_ACCESS_CMD`](registers.md#direct_access_cmd). -4. Poll the [`STATUS`](registers.md#status) until the DAI state goes back to idle. -Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed. -5. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)). -6. If the region accessed has a 32bit access granule, the 32bit chunk of read data can be read from [`DIRECT_ACCESS_RDATA_0`](registers.md#direct_access_rdata). -If the region accessed has a 64bit access granule, the 64bit chunk of read data can be read from the [`DIRECT_ACCESS_RDATA_0`](registers.md#direct_access_rdata) and [`DIRECT_ACCESS_RDATA_1`](registers.md#direct_access_rdata) registers. -7. Go back to 1. and repeat until all data has been read. - -The hardware will set [`DIRECT_ACCESS_REGWEN`](registers.md#direct_access_regwen) to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers. - -### Programming Sequence - -A typical programming sequence looks as follows: - -1. Check whether the DAI is idle by reading the [`STATUS`](registers.md#status) register. -2. If the region to be accessed has a 32bit access granule, place a 32bit chunk of data into [`DIRECT_ACCESS_WDATA_0`](registers.md#direct_access_wdata). -If the region to be accessed has a 64bit access granule, both the [`DIRECT_ACCESS_WDATA_0`](registers.md#direct_access_wdata) and [`DIRECT_ACCESS_WDATA_1`](registers.md#direct_access_wdata) registers have to be used. -3. Write the byte address for the access to [`DIRECT_ACCESS_ADDRESS`](registers.md#direct_access_address). -Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit. -4. Trigger a write command by writing 0x2 to [`DIRECT_ACCESS_CMD`](registers.md#direct_access_cmd). -5. Poll the [`STATUS`](registers.md#status) until the DAI state goes back to idle. -Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed. -6. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)). -7. Go back to 1. and repeat until all data has been written. - -The hardware will set [`DIRECT_ACCESS_REGWEN`](registers.md#direct_access_regwen) to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers. - -Note that SW is responsible for keeping track of already programmed OTP word locations during the provisioning phase. -**It is imperative that SW does not write the same word location twice**, since this can lead to ECC inconsistencies, thereby potentially rendering the device useless. - -### Digest Calculation Sequence - -The hardware digest computation for the hardware and secret partitions can be triggered as follows: - -1. Check whether the DAI is idle by reading the [`STATUS`](registers.md#status) register. -3. Write the partition base address to [`DIRECT_ACCESS_ADDRESS`](registers.md#direct_access_address). -4. Trigger a digest calculation command by writing 0x4 to [`DIRECT_ACCESS_CMD`](registers.md#direct_access_cmd). -5. Poll the [`STATUS`](registers.md#status) until the DAI state goes back to idle. -Alternatively, the `otp_operation_done` interrupt can be enabled up to notify the processor once an access has completed. -6. If the status register flags a DAI error, additional handling is required (see [Section on Error handling](#error-handling)). - -The hardware will set [`DIRECT_ACCESS_REGWEN`](registers.md#direct_access_regwen) to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers. - -It should also be noted that the effect of locking a partition via the digest only takes effect **after** the next system reset. -To prevent integrity check failures SW must therefore ensure that no more programming operations are issued to the affected partition after initiating the digest calculation sequence. - -### Software Integrity Handling - -As opposed to buffered partitions, the digest and integrity handling of unbuffered partitions is entirely up to software. -The only hardware-assisted feature in unbuffered partitions is the digest lock, which locks write access to an unbuffered partition once a nonzero value has been programmed to the 64bit digest location. - -In a similar vein, it should be noted that the system-wide bus-integrity metadata does not travel alongside the data end-to-end in the OTP controller (i.e., the bus-integrity metadata bits are not stored into the OTP memory array). -This means that data written to and read from the OTP macro is not protected by the bus integrity feature at all stages. -In case of buffered partitions this does not pose a concern since data integrity in these partitions is checked via the hardware assisted digest mechanism. -In case of unbuffered partitions however, the data integrity checking is entirely up to software. -I.e., if data is read from an unbuffered partition (either through the DAI or CSR windows), software should perform an integrity check on that data. - -## Error Handling - -The agents that can access the OTP macro (DAI, LCI, buffered/unbuffered partitions) expose detailed error codes that can be used to root cause any failure. -The error codes are defined in the table below, and the corresponding `otp_err_e` enum type can be found in the `otp_ctrl_pkg`. -The table also lists which error codes are supported by which agent. - -Errors that are not "recoverable" are severe errors that move the corresponding partition or DAI/LCI FSM into a terminal error state, where no more commands can be accepted (a system reset is required to restore functionality in that case). -Errors that are "recoverable" are less severe and do not cause the FSM to jump into a terminal error state. - -Note that error codes that originate in the physical OTP macro are prefixed with `Macro*`. - -Error Code | Enum Name | Recoverable | DAI | LCI | Unbuf | Buf | Description ------------|------------------------|-------------|-----|-----|-------|-------|------------- -0x0 | `NoError` | - | x | x | x | x | No error has occurred. -0x1 | `MacroError` | no | x | x | x | x | Returned if the OTP macro command did not complete successfully due to a macro malfunction. -0x2 | `MacroEccCorrError` | yes | x | - | x | x | A correctable ECC error has occurred during a read operation in the OTP macro. -0x3 | `MacroEccUncorrError` | no | x | - | x* | x | An uncorrectable ECC error has occurred during a read operation in the OTP macro. Note (*): This error is collapsed into `MacroEccCorrError` if the partition is a vendor test partition. It then becomes a recoverable error. -0x4 | `MacroWriteBlankError` | yes / no* | x | x | - | - | This error is returned if a write operation attempted to clear an already programmed bit location. Note (*): This error is recoverable if encountered in the DAI, but unrecoverable if encountered in the LCI. -0x5 | `AccessError` | yes | x | - | x | - | An access error has occurred (e.g. write to write-locked region, or read to a read-locked region). -0x6 | `CheckFailError` | no | - | - | x | x | An unrecoverable ECC, integrity or consistency error has been detected. -0x7 | `FsmStateError` | no | x | x | x | x | The FSM has been glitched into an invalid state, or escalation has been triggered and the FSM has been moved into a terminal error state. - -All non-zero error codes listed above trigger an `otp_error` interrupt. -In addition, all unrecoverable OTP `Macro*` errors (codes 0x1, 0x3) trigger a `fatal_macro_error` alert, while all remaining unrecoverable errors trigger a `fatal_check_error` alert. - -If software receives an `otp_error` interrupt, but all error codes read back as 0x0 (`NoError`), this should be treated as a fatal error condition, and the system should be shut down as soon as possible. - -Note that the `MacroWriteBlankError` will only be generated if the write attempt over already written data fails within the OTP macro after applying any means supported within it to enable a write on existing data, e.g., a bit-reversal option. -Also note that while this error is marked as a recoverable error, the affected OTP word may be in an inconsistent state after this error has been returned. -This can cause several issues when the word is accessed again (either as part of a regular read operation, as part of the readout at boot, or as part of a background check). -It is important that SW ensures that each word is only written once, since this can render the device useless. - -## Direct Access Memory Map - -The table below provides a detailed overview of the items stored in the OTP partitions. -Some of the items that are buffered in registers is readable via memory mapped CSRs, and these CSRs are linked in the table below. -Items that are not linked can only be accessed via the direct programming interface (if the partition is not locked via the corresponding digest). -It should be noted that CREATOR_SW_CFG and OWNER_SW_CFG are accessible through a memory mapped window, and content of these partitions is not buffered. -Hence, a read access to those windows will take in the order of 10-20 cycles until the read returns. - -Sizes below are specified in multiples of 32bit words. - -{{#include otp_ctrl_mmap.md}} - -Note that since the content in the SECRET* partitions are scrambled using a 64bit PRESENT cipher, read and write access through the DAI needs to occur at a 64bit granularity. -Also, all digests (no matter whether they are SW or HW digests) have an access granule of 64bit. - -The table below lists digests locations, and the corresponding locked partitions. - -{{#include otp_ctrl_digests.md}} - -Write access to the affected partition will be locked if the digest has a nonzero value. - -For the software partition digests, it is entirely up to software to decide on the digest algorithm to be used. -Hardware will determine the lock condition only based on whether a non-zero value is present at that location or not. - -For the hardware partitions, hardware calculates this digest and uses it for [background verification](#partition-checks). -Digest calculation can be triggered via the DAI. - -Finally, it should be noted that the RMA_TOKEN and CREATOR_ROOT_KEY_SHARE0 / CREATOR_ROOT_KEY_SHARE1 items can only be programmed when the device is in the DEV, PROD, PROD_END and RMA stages. -Please consult the [life cycle controller documentation](../../lc_ctrl/README.md) documentation for more information. - -## OTP Field Descriptions - -The table below describes what each field in the OTP partitions is used for. - -{{#include otp_ctrl_field_descriptions.md}} - -## Examples - -### Provisioning Items - -The following represents a typical provisioning sequence for items in all partitions (except for the LIFE_CYCLE partition, which is not software-programmable): - -1. [Program](#programming-sequence) the item in 32bit or 64bit chunks via the DAI. -2. [Read back](#readout-sequence) and verify the item via the DAI. -3. If the item is exposed via CSRs or a CSR window, perform a full-system reset and verify whether those fields are correctly populated. - -Note that any unrecoverable errors during the programming steps, or mismatches during the readback and verification steps indicate that the device might be malfunctioning (possibly due to fabrication defects) and hence the device may have to be scrapped. -This is however rare and should not happen after fabrication testing. - -### Locking Partitions - -Once a partition has been fully populated, write access to that partition has to be permanently locked. -For the HW_CFG* and SECRET* partitions, this can be achieved as follows: - -1. [Trigger](#digest-calculation-sequence) a digest calculation via the DAI. -2. [Read back](#readout-sequence) and verify the digest location via the DAI. -3. Perform a full-system reset and verify that the corresponding CSRs exposing the 64bit digest have been populated ([`HW_CFG_DIGEST_0`](registers.md#hw_cfg_digest), [`SECRET0_DIGEST_0`](registers.md#secret0_digest), [`SECRET1_DIGEST_0`](registers.md#secret1_digest) or [`SECRET2_DIGEST_0`](registers.md#secret2_digest)). - -It should be noted that locking only takes effect after a system reset since the affected partitions first have to re-sense the digest values. -Hence, it is critical that SW ensures that no more data is written to the partition to be locked after triggering the hardware digest calculation. -Otherwise, the device will likely be rendered inoperable as this can lead to permanent digest mismatch errors after system reboot. - -For the [`CREATOR_SW_CFG`](registers.md#creator_sw_cfg) and [`OWNER_SW_CFG`](registers.md#owner_sw_cfg) partitions, the process is similar, but computation and programming of the digest is entirely up to software: - -1. Compute a 64bit digest over the relevant parts of the partition, and [program](#programming-sequence) that value to [`CREATOR_SW_CFG_DIGEST_0`](registers.md#creator_sw_cfg_digest) or [`OWNER_SW_CFG_DIGEST_0`](registers.md#owner_sw_cfg_digest) via the DAI. Note that digest accesses through the DAI have an access granule of 64bit. -2. [Read back](#readout-sequence) and verify the digest location via the DAI. -3. Perform a full-system reset and verify that the corresponding digest CSRs [`CREATOR_SW_CFG_DIGEST_0`](registers.md#creator_sw_cfg_digest) or [`OWNER_SW_CFG_DIGEST_0`](registers.md#owner_sw_cfg_digest) have been populated with the correct 64bit value. - -Note that any unrecoverable errors during the programming steps, or mismatches during the read-back and verification steps indicate that the device might be malfunctioning (possibly due to fabrication defects) and hence the device may have to be scrapped. -This is however rare and should not happen after fabrication testing. - -## Device Interface Functions (DIFs) - -- [Device Interface Functions](../../../../sw/device/lib/dif/dif_otp_ctrl.h) - -# Additional Notes - -## OTP IP Assumptions - -It is assumed the OTP IP employed in production has reasonable physical defense characteristics. -Specifically which defensive features will likely be use case dependent, but at a minimum they should have the properties below. -Note some properties are worded with "SHALL" and others with "SHOULD". -"SHALL" refers to features that must be present, while "SHOULD" refers to features that are ideal, but optional. - -- The contents shall not be observable via optical microscopy (for example anti-fuse technology). -- The IP lifetime shall not be limited by the amount of read cycles performed. -- If the IP contains field programmability (internal charge pumps and LDOs), there shall be mechanisms in place to selectively disable this function based on device context. -- If the IP contains redundant columns, rows, pages or banks for yield improvement, it shall provide a mechanism to lock down arbitrary manipulation of page / bank swapping during run-time. -- The IP shall be clear on what bits must be manipulated by the user, what bits are automatically manipulated by hardware (for example ECC or redundancy) and what areas the user can influence. -- The IP shall be compatible, through the use of a proprietary wrapper or shim, with an open-source friendly IO interface. -- The IP should functionally support the programming of already programmed bits without information leakage. -- The IP should offer SCA resistance: - - For example, the content may be stored differentially. - - For example, the sensing exhibits similar power signatures no matter if the stored bit is 0 or 1. -- The IP interface shall be memory-like if beyond a certain size. -- When a particular location is read, a fixed width output is returned; similar when a particular location is programmed, a fixed width input is supplied. -- The IP does not output all stored bits in parallel. -- The contents should be electrically hidden. For example, it should be difficult for an attacker to energize the fuse array and observe how the charge leaks. -- The IP should route critical nets at lower metal levels to avoid probing. -- The IP should contain native detectors for fault injection attacks. -- The IP should contain mechanisms to guard against interrupted programming - either through malicious intent or unexpected power loss and glitched address lines. -- The IP should contain mechanisms for error corrections (single bit errors). - - For example ECC or redundant bits voting / or-ing. - - As error correction mechanisms are technology dependent, that information should not be exposed to the open-source controller, instead the controller should simply receive information on whether a read / program was successful. -- The IP should have self-test functionality to assess the health of the storage and analog structures. -- The IP may contain native PUF-like functionality. diff --git a/hw/ip/otp_ctrl/doc/registers.md b/hw/ip/otp_ctrl/doc/registers.md deleted file mode 100644 index 435a5ddb2f2a2..0000000000000 --- a/hw/ip/otp_ctrl/doc/registers.md +++ /dev/null @@ -1,1043 +0,0 @@ -# Registers - - -## Summary of the **`core`** interface's registers - -| Name | Offset | Length | Description | -|:---------------------------------------------------------------------------------------|:---------|---------:|:----------------------------------------------------------------------------------------------------| -| otp_ctrl.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| otp_ctrl.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| otp_ctrl.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| otp_ctrl.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| otp_ctrl.[`STATUS`](#status) | 0x10 | 4 | OTP status register. | -| otp_ctrl.[`ERR_CODE_0`](#err_code) | 0x14 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_1`](#err_code) | 0x18 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_2`](#err_code) | 0x1c | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_3`](#err_code) | 0x20 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_4`](#err_code) | 0x24 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_5`](#err_code) | 0x28 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_6`](#err_code) | 0x2c | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_7`](#err_code) | 0x30 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_8`](#err_code) | 0x34 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_9`](#err_code) | 0x38 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_10`](#err_code) | 0x3c | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_11`](#err_code) | 0x40 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`ERR_CODE_12`](#err_code) | 0x44 | 4 | This register holds information about error conditions that occurred in the agents | -| otp_ctrl.[`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) | 0x48 | 4 | Register write enable for all direct access interface registers. | -| otp_ctrl.[`DIRECT_ACCESS_CMD`](#direct_access_cmd) | 0x4c | 4 | Command register for direct accesses. | -| otp_ctrl.[`DIRECT_ACCESS_ADDRESS`](#direct_access_address) | 0x50 | 4 | Address register for direct accesses. | -| otp_ctrl.[`DIRECT_ACCESS_WDATA_0`](#direct_access_wdata) | 0x54 | 4 | Write data for direct accesses. | -| otp_ctrl.[`DIRECT_ACCESS_WDATA_1`](#direct_access_wdata) | 0x58 | 4 | Write data for direct accesses. | -| otp_ctrl.[`DIRECT_ACCESS_RDATA_0`](#direct_access_rdata) | 0x5c | 4 | Read data for direct accesses. | -| otp_ctrl.[`DIRECT_ACCESS_RDATA_1`](#direct_access_rdata) | 0x60 | 4 | Read data for direct accesses. | -| otp_ctrl.[`CHECK_TRIGGER_REGWEN`](#check_trigger_regwen) | 0x64 | 4 | Register write enable for !!CHECK_TRIGGER. | -| otp_ctrl.[`CHECK_TRIGGER`](#check_trigger) | 0x68 | 4 | Command register for direct accesses. | -| otp_ctrl.[`CHECK_REGWEN`](#check_regwen) | 0x6c | 4 | Register write enable for !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD. | -| otp_ctrl.[`CHECK_TIMEOUT`](#check_timeout) | 0x70 | 4 | Timeout value for the integrity and consistency checks. | -| otp_ctrl.[`INTEGRITY_CHECK_PERIOD`](#integrity_check_period) | 0x74 | 4 | This value specifies the maximum period that can be generated pseudo-randomly. | -| otp_ctrl.[`CONSISTENCY_CHECK_PERIOD`](#consistency_check_period) | 0x78 | 4 | This value specifies the maximum period that can be generated pseudo-randomly. | -| otp_ctrl.[`VENDOR_TEST_READ_LOCK`](#vendor_test_read_lock) | 0x7c | 4 | Runtime read lock for the VENDOR_TEST partition. | -| otp_ctrl.[`CREATOR_SW_CFG_READ_LOCK`](#creator_sw_cfg_read_lock) | 0x80 | 4 | Runtime read lock for the CREATOR_SW_CFG partition. | -| otp_ctrl.[`OWNER_SW_CFG_READ_LOCK`](#owner_sw_cfg_read_lock) | 0x84 | 4 | Runtime read lock for the OWNER_SW_CFG partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_CODESIGN_READ_LOCK`](#rot_creator_auth_codesign_read_lock) | 0x88 | 4 | Runtime read lock for the ROT_CREATOR_AUTH_CODESIGN partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_STATE_READ_LOCK`](#rot_creator_auth_state_read_lock) | 0x8c | 4 | Runtime read lock for the ROT_CREATOR_AUTH_STATE partition. | -| otp_ctrl.[`VENDOR_TEST_DIGEST_0`](#vendor_test_digest) | 0x90 | 4 | Integrity digest for the VENDOR_TEST partition. | -| otp_ctrl.[`VENDOR_TEST_DIGEST_1`](#vendor_test_digest) | 0x94 | 4 | Integrity digest for the VENDOR_TEST partition. | -| otp_ctrl.[`CREATOR_SW_CFG_DIGEST_0`](#creator_sw_cfg_digest) | 0x98 | 4 | Integrity digest for the CREATOR_SW_CFG partition. | -| otp_ctrl.[`CREATOR_SW_CFG_DIGEST_1`](#creator_sw_cfg_digest) | 0x9c | 4 | Integrity digest for the CREATOR_SW_CFG partition. | -| otp_ctrl.[`OWNER_SW_CFG_DIGEST_0`](#owner_sw_cfg_digest) | 0xa0 | 4 | Integrity digest for the OWNER_SW_CFG partition. | -| otp_ctrl.[`OWNER_SW_CFG_DIGEST_1`](#owner_sw_cfg_digest) | 0xa4 | 4 | Integrity digest for the OWNER_SW_CFG partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_CODESIGN_DIGEST_0`](#rot_creator_auth_codesign_digest) | 0xa8 | 4 | Integrity digest for the ROT_CREATOR_AUTH_CODESIGN partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_CODESIGN_DIGEST_1`](#rot_creator_auth_codesign_digest) | 0xac | 4 | Integrity digest for the ROT_CREATOR_AUTH_CODESIGN partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_STATE_DIGEST_0`](#rot_creator_auth_state_digest) | 0xb0 | 4 | Integrity digest for the ROT_CREATOR_AUTH_STATE partition. | -| otp_ctrl.[`ROT_CREATOR_AUTH_STATE_DIGEST_1`](#rot_creator_auth_state_digest) | 0xb4 | 4 | Integrity digest for the ROT_CREATOR_AUTH_STATE partition. | -| otp_ctrl.[`HW_CFG0_DIGEST_0`](#hw_cfg0_digest) | 0xb8 | 4 | Integrity digest for the HW_CFG0 partition. | -| otp_ctrl.[`HW_CFG0_DIGEST_1`](#hw_cfg0_digest) | 0xbc | 4 | Integrity digest for the HW_CFG0 partition. | -| otp_ctrl.[`HW_CFG1_DIGEST_0`](#hw_cfg1_digest) | 0xc0 | 4 | Integrity digest for the HW_CFG1 partition. | -| otp_ctrl.[`HW_CFG1_DIGEST_1`](#hw_cfg1_digest) | 0xc4 | 4 | Integrity digest for the HW_CFG1 partition. | -| otp_ctrl.[`SECRET0_DIGEST_0`](#secret0_digest) | 0xc8 | 4 | Integrity digest for the SECRET0 partition. | -| otp_ctrl.[`SECRET0_DIGEST_1`](#secret0_digest) | 0xcc | 4 | Integrity digest for the SECRET0 partition. | -| otp_ctrl.[`SECRET1_DIGEST_0`](#secret1_digest) | 0xd0 | 4 | Integrity digest for the SECRET1 partition. | -| otp_ctrl.[`SECRET1_DIGEST_1`](#secret1_digest) | 0xd4 | 4 | Integrity digest for the SECRET1 partition. | -| otp_ctrl.[`SECRET2_DIGEST_0`](#secret2_digest) | 0xd8 | 4 | Integrity digest for the SECRET2 partition. | -| otp_ctrl.[`SECRET2_DIGEST_1`](#secret2_digest) | 0xdc | 4 | Integrity digest for the SECRET2 partition. | -| otp_ctrl.[`SW_CFG_WINDOW`](#sw_cfg_window) | 0x800 | 2048 | Any read to this window directly maps to the corresponding offset in the creator and owner software | - -## INTR_STATE -Interrupt State Register -- Offset: `0x0` -- Reset default: `0x0` -- Reset mask: `0x3` - -### Fields - -```wavejson -{"reg": [{"name": "otp_operation_done", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "otp_error", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 200}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------------|:-----------------------------------------------------------------------------------------------------------------| -| 31:2 | | | | Reserved | -| 1 | rw1c | 0x0 | otp_error | An error has occurred in the OTP controller. Check the [`ERR_CODE`](#err_code) register to get more information. | -| 0 | rw1c | 0x0 | otp_operation_done | A direct access command or digest calculation operation has completed. | - -## INTR_ENABLE -Interrupt Enable Register -- Offset: `0x4` -- Reset default: `0x0` -- Reset mask: `0x3` - -### Fields - -```wavejson -{"reg": [{"name": "otp_operation_done", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "otp_error", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 200}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------------|:-----------------------------------------------------------------------------| -| 31:2 | | | | Reserved | -| 1 | rw | 0x0 | otp_error | Enable interrupt when [`INTR_STATE.otp_error`](#intr_state) is set. | -| 0 | rw | 0x0 | otp_operation_done | Enable interrupt when [`INTR_STATE.otp_operation_done`](#intr_state) is set. | - -## INTR_TEST -Interrupt Test Register -- Offset: `0x8` -- Reset default: `0x0` -- Reset mask: `0x3` - -### Fields - -```wavejson -{"reg": [{"name": "otp_operation_done", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "otp_error", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 200}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------------|:----------------------------------------------------------------------| -| 31:2 | | | | Reserved | -| 1 | wo | 0x0 | otp_error | Write 1 to force [`INTR_STATE.otp_error`](#intr_state) to 1. | -| 0 | wo | 0x0 | otp_operation_done | Write 1 to force [`INTR_STATE.otp_operation_done`](#intr_state) to 1. | - -## ALERT_TEST -Alert Test Register -- Offset: `0xc` -- Reset default: `0x0` -- Reset mask: `0x1f` - -### Fields - -```wavejson -{"reg": [{"name": "fatal_macro_error", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_check_error", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_bus_integ_error", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_prim_otp_alert", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "recov_prim_otp_alert", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 230}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:----------------------|:-------------------------------------------------| -| 31:5 | | | | Reserved | -| 4 | wo | 0x0 | recov_prim_otp_alert | Write 1 to trigger one alert event of this kind. | -| 3 | wo | 0x0 | fatal_prim_otp_alert | Write 1 to trigger one alert event of this kind. | -| 2 | wo | 0x0 | fatal_bus_integ_error | Write 1 to trigger one alert event of this kind. | -| 1 | wo | 0x0 | fatal_check_error | Write 1 to trigger one alert event of this kind. | -| 0 | wo | 0x0 | fatal_macro_error | Write 1 to trigger one alert event of this kind. | - -## STATUS -OTP status register. -- Offset: `0x10` -- Reset default: `0x0` -- Reset mask: `0xfffff` - -### Fields - -```wavejson -{"reg": [{"name": "VENDOR_TEST_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CREATOR_SW_CFG_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "OWNER_SW_CFG_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ROT_CREATOR_AUTH_CODESIGN_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ROT_CREATOR_AUTH_STATE_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "HW_CFG0_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "HW_CFG1_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SECRET0_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SECRET1_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SECRET2_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "LIFE_CYCLE_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DAI_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "LCI_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "TIMEOUT_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "LFSR_FSM_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SCRAMBLING_FSM_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "KEY_DERIV_FSM_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "BUS_INTEG_ERROR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "DAI_IDLE", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "CHECK_PENDING", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 12}], "config": {"lanes": 1, "fontsize": 10, "vspace": 330}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:--------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:20 | | | | Reserved | -| 19 | ro | 0x0 | CHECK_PENDING | Set to 1 if an integrity or consistency check triggered by the LFSR timer or via [`CHECK_TRIGGER`](#check_trigger) is pending. | -| 18 | ro | 0x0 | DAI_IDLE | Set to 1 if the DAI is idle and ready to accept commands. | -| 17 | ro | 0x0 | BUS_INTEG_ERROR | This bit is set to 1 if a fatal bus integrity fault is detected. This error triggers a fatal_bus_integ_error alert. | -| 16 | ro | 0x0 | KEY_DERIV_FSM_ERROR | Set to 1 if the key derivation FSM has reached an invalid state. This raises an fatal_check_error alert and is an unrecoverable error condition. | -| 15 | ro | 0x0 | SCRAMBLING_FSM_ERROR | Set to 1 if the scrambling datapath FSM has reached an invalid state. This raises an fatal_check_error alert and is an unrecoverable error condition. | -| 14 | ro | 0x0 | LFSR_FSM_ERROR | Set to 1 if the LFSR timer FSM has reached an invalid state. This raises an fatal_check_error alert and is an unrecoverable error condition. | -| 13 | ro | 0x0 | TIMEOUT_ERROR | Set to 1 if an integrity or consistency check times out. This raises an fatal_check_error alert and is an unrecoverable error condition. | -| 12 | ro | 0x0 | LCI_ERROR | Set to 1 if an error occurred in the LCI. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 11 | ro | 0x0 | DAI_ERROR | Set to 1 if an error occurred in the DAI. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 10 | ro | 0x0 | LIFE_CYCLE_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 9 | ro | 0x0 | SECRET2_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 8 | ro | 0x0 | SECRET1_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 7 | ro | 0x0 | SECRET0_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 6 | ro | 0x0 | HW_CFG1_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 5 | ro | 0x0 | HW_CFG0_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 4 | ro | 0x0 | ROT_CREATOR_AUTH_STATE_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 3 | ro | 0x0 | ROT_CREATOR_AUTH_CODESIGN_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 2 | ro | 0x0 | OWNER_SW_CFG_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 1 | ro | 0x0 | CREATOR_SW_CFG_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | -| 0 | ro | 0x0 | VENDOR_TEST_ERROR | Set to 1 if an error occurred in this partition. If set to 1, SW should check the [`ERR_CODE`](#err_code) register at the corresponding index. | - -## ERR_CODE -This register holds information about error conditions that occurred in the agents -interacting with the OTP macro via the internal bus. The error codes should be checked -if the partitions, DAI or LCI flag an error in the [`STATUS`](#status) register, or when an -[`INTR_STATE.otp_error`](#intr_state) has been triggered. Note that all errors trigger an otp_error -interrupt, and in addition some errors may trigger either an fatal_macro_error or an -fatal_check_error alert. -- Reset default: `0x0` -- Reset mask: `0x7` - -### Instances - -| Name | Offset | -|:------------|:---------| -| ERR_CODE_0 | 0x14 | -| ERR_CODE_1 | 0x18 | -| ERR_CODE_2 | 0x1c | -| ERR_CODE_3 | 0x20 | -| ERR_CODE_4 | 0x24 | -| ERR_CODE_5 | 0x28 | -| ERR_CODE_6 | 0x2c | -| ERR_CODE_7 | 0x30 | -| ERR_CODE_8 | 0x34 | -| ERR_CODE_9 | 0x38 | -| ERR_CODE_10 | 0x3c | -| ERR_CODE_11 | 0x40 | -| ERR_CODE_12 | 0x44 | - - -### Fields - -```wavejson -{"reg": [{"name": "ERR_CODE", "bits": 3, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 100}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:--------------------------------| -| 31:3 | | | Reserved | -| 2:0 | ro | 0x0 | [ERR_CODE](#err_code--err_code) | - -### ERR_CODE . ERR_CODE - -| Value | Name | Description | -|:--------|:------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 0x0 | NO_ERROR | No error condition has occurred. | -| 0x1 | MACRO_ERROR | Returned if the OTP macro command was invalid or did not complete successfully due to a macro malfunction. This error should never occur during normal operation and is not recoverable. This error triggers an fatal_macro_error alert. | -| 0x2 | MACRO_ECC_CORR_ERROR | A correctable ECC error has occured during an OTP read operation. The corresponding controller automatically recovers from this error when issuing a new command. | -| 0x3 | MACRO_ECC_UNCORR_ERROR | An uncorrectable ECC error has occurred during an OTP read operation. This error should never occur during normal operation and is not recoverable. If this error is present this may be a sign that the device is malfunctioning. This error triggers an fatal_macro_error alert. | -| 0x4 | MACRO_WRITE_BLANK_ERROR | This error is returned if a programming operation attempted to clear a bit that has previously been programmed to 1. The corresponding controller automatically recovers from this error when issuing a new command. Note however that the affected OTP word may be left in an inconsistent state if this error occurs. This can cause several issues when the word is accessed again (either as part of a regular read operation, as part of the readout at boot, or as part of a background check). It is important that SW ensures that each word is only written once, since this can render the device useless. | -| 0x5 | ACCESS_ERROR | This error indicates that a locked memory region has been accessed. The corresponding controller automatically recovers from this error when issuing a new command. | -| 0x6 | CHECK_FAIL_ERROR | An ECC, integrity or consistency mismatch has been detected in the buffer registers. This error should never occur during normal operation and is not recoverable. This error triggers an fatal_check_error alert. | -| 0x7 | FSM_STATE_ERROR | The FSM of the corresponding controller has reached an invalid state, or the FSM has been moved into a terminal error state due to an escalation action via lc_escalate_en_i. This error should never occur during normal operation and is not recoverable. If this error is present, this is a sign that the device has fallen victim to an invasive attack. This error triggers an fatal_check_error alert. | - - -## DIRECT_ACCESS_REGWEN -Register write enable for all direct access interface registers. -- Offset: `0x48` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "DIRECT_ACCESS_REGWEN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 220}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:--------------------------------------------------------------------| -| 31:1 | | | Reserved | -| 0 | rw0c | 0x1 | [DIRECT_ACCESS_REGWEN](#direct_access_regwen--direct_access_regwen) | - -### DIRECT_ACCESS_REGWEN . DIRECT_ACCESS_REGWEN -This bit controls whether the DAI registers can be written. -Write 0 to it in order to clear the bit. - -Note that the hardware also modulates this bit and sets it to 0 temporarily -during an OTP operation such that the corresponding address and data registers -cannot be modified while an operation is pending. The [`DAI_IDLE`](#dai_idle) status bit -will also be set to 0 in such a case. - -## DIRECT_ACCESS_CMD -Command register for direct accesses. -- Offset: `0x4c` -- Reset default: `0x0` -- Reset mask: `0x7` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "RD", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "WR", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "DIGEST", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:3 | | | | Reserved | -| 2 | r0w1c | 0x0 | DIGEST | Initiates the digest calculation and locking sequence for the partition specified by [`DIRECT_ACCESS_ADDRESS.`](#direct_access_address) | -| 1 | r0w1c | 0x0 | WR | Initiates a programming sequence that writes the data in [`DIRECT_ACCESS_WDATA_0`](#direct_access_wdata_0) and [`DIRECT_ACCESS_WDATA_1`](#direct_access_wdata_1) (for 64bit partitions) to the location specified by [`DIRECT_ACCESS_ADDRESS.`](#direct_access_address) | -| 0 | r0w1c | 0x0 | RD | Initiates a readout sequence that reads the location specified by [`DIRECT_ACCESS_ADDRESS.`](#direct_access_address) The command places the data read into [`DIRECT_ACCESS_RDATA_0`](#direct_access_rdata_0) and [`DIRECT_ACCESS_RDATA_1`](#direct_access_rdata_1) (for 64bit partitions). | - -## DIRECT_ACCESS_ADDRESS -Address register for direct accesses. -- Offset: `0x50` -- Reset default: `0x0` -- Reset mask: `0x7ff` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "DIRECT_ACCESS_ADDRESS", "bits": 11, "attr": ["rw"], "rotate": -90}, {"bits": 21}], "config": {"lanes": 1, "fontsize": 10, "vspace": 230}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-----------------------------------------------------------------------| -| 31:11 | | | Reserved | -| 10:0 | rw | 0x0 | [DIRECT_ACCESS_ADDRESS](#direct_access_address--direct_access_address) | - -### DIRECT_ACCESS_ADDRESS . DIRECT_ACCESS_ADDRESS -This is the address for the OTP word to be read or written through -the direct access interface. Note that the address is aligned to the access size -internally, hence bits 1:0 are ignored for 32bit accesses, and bits 2:0 are ignored -for 64bit accesses. - -For the digest calculation command, set this register to the partition base offset. - -## DIRECT_ACCESS_WDATA -Write data for direct accesses. -Hardware automatically determines the access granule (32bit or 64bit) based on which -partition is being written to. -- Reset default: `0x0` -- Reset mask: `0xffffffff` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Instances - -| Name | Offset | -|:----------------------|:---------| -| DIRECT_ACCESS_WDATA_0 | 0x54 | -| DIRECT_ACCESS_WDATA_1 | 0x58 | - - -### Fields - -```wavejson -{"reg": [{"name": "DIRECT_ACCESS_WDATA", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:--------------------|:--------------| -| 31:0 | rw | 0x0 | DIRECT_ACCESS_WDATA | | - -## DIRECT_ACCESS_RDATA -Read data for direct accesses. -Hardware automatically determines the access granule (32bit or 64bit) based on which -partition is read from. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:----------------------|:---------| -| DIRECT_ACCESS_RDATA_0 | 0x5c | -| DIRECT_ACCESS_RDATA_1 | 0x60 | - - -### Fields - -```wavejson -{"reg": [{"name": "DIRECT_ACCESS_RDATA", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:--------------------|:--------------| -| 31:0 | ro | 0x0 | DIRECT_ACCESS_RDATA | | - -## CHECK_TRIGGER_REGWEN -Register write enable for [`CHECK_TRIGGER.`](#check_trigger) -- Offset: `0x64` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "CHECK_TRIGGER_REGWEN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 220}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------------|:------------------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | CHECK_TRIGGER_REGWEN | When cleared to 0, the [`CHECK_TRIGGER`](#check_trigger) register cannot be written anymore. Write 0 to clear this bit. | - -## CHECK_TRIGGER -Command register for direct accesses. -- Offset: `0x68` -- Reset default: `0x0` -- Reset mask: `0x3` -- Register enable: [`CHECK_TRIGGER_REGWEN`](#check_trigger_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "INTEGRITY", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"name": "CONSISTENCY", "bits": 1, "attr": ["r0w1c"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-------------------------------------------| -| 31:2 | | | Reserved | -| 1 | r0w1c | 0x0 | [CONSISTENCY](#check_trigger--consistency) | -| 0 | r0w1c | 0x0 | [INTEGRITY](#check_trigger--integrity) | - -### CHECK_TRIGGER . CONSISTENCY -Writing 1 to this bit triggers a consistency check. SW should monitor [`STATUS.CHECK_PENDING`](#status) -and wait until the check has been completed. If there are any errors, those will be flagged -in the [`STATUS`](#status) and [`ERR_CODE`](#err_code) registers, and via interrupts and alerts. - -### CHECK_TRIGGER . INTEGRITY -Writing 1 to this bit triggers an integrity check. SW should monitor [`STATUS.CHECK_PENDING`](#status) -and wait until the check has been completed. If there are any errors, those will be flagged -in the [`STATUS`](#status) and [`ERR_CODE`](#err_code) registers, and via the interrupts and alerts. - -## CHECK_REGWEN -Register write enable for [`INTEGRITY_CHECK_PERIOD`](#integrity_check_period) and [`CONSISTENCY_CHECK_PERIOD.`](#consistency_check_period) -- Offset: `0x6c` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "CHECK_REGWEN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | CHECK_REGWEN | When cleared to 0, [`INTEGRITY_CHECK_PERIOD`](#integrity_check_period) and [`CONSISTENCY_CHECK_PERIOD`](#consistency_check_period) registers cannot be written anymore. Write 0 to clear this bit. | - -## CHECK_TIMEOUT -Timeout value for the integrity and consistency checks. -- Offset: `0x70` -- Reset default: `0x0` -- Reset mask: `0xffffffff` -- Register enable: [`CHECK_REGWEN`](#check_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "CHECK_TIMEOUT", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-----------------------------------------------| -| 31:0 | rw | 0x0 | [CHECK_TIMEOUT](#check_timeout--check_timeout) | - -### CHECK_TIMEOUT . CHECK_TIMEOUT -Timeout value in cycles for the for the integrity and consistency checks. If an integrity or consistency -check does not complete within the timeout window, an error will be flagged in the [`STATUS`](#status) register, -an otp_error interrupt will be raised, and an fatal_check_error alert will be sent out. The timeout should -be set to a large value to stay on the safe side. The maximum check time can be upper bounded by the -number of cycles it takes to readout, scramble and digest the entire OTP array. Since this amounts to -roughly 25k cycles, it is recommended to set this value to at least 100'000 cycles in order to stay on the -safe side. A value of zero disables the timeout mechanism (default). - -## INTEGRITY_CHECK_PERIOD -This value specifies the maximum period that can be generated pseudo-randomly. -Only applies to the HW_CFG* and SECRET* partitions once they are locked. -- Offset: `0x74` -- Reset default: `0x0` -- Reset mask: `0xffffffff` -- Register enable: [`CHECK_REGWEN`](#check_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "INTEGRITY_CHECK_PERIOD", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:--------------------------------------------------------------------------| -| 31:0 | rw | 0x0 | [INTEGRITY_CHECK_PERIOD](#integrity_check_period--integrity_check_period) | - -### INTEGRITY_CHECK_PERIOD . INTEGRITY_CHECK_PERIOD -The pseudo-random period is generated using a 40bit LFSR internally, and this register defines -the bit mask to be applied to the LFSR output in order to limit its range. The value of this -register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. -A recommended value is 0x3_FFFF, corresponding to a maximum period of ~2.8s at 24MHz. -A value of zero disables the timer (default). Note that a one-off check can always be triggered via -[`CHECK_TRIGGER.INTEGRITY.`](#check_trigger) - -## CONSISTENCY_CHECK_PERIOD -This value specifies the maximum period that can be generated pseudo-randomly. -This applies to the LIFE_CYCLE partition and the HW_CFG* and SECRET* partitions once they are locked. -- Offset: `0x78` -- Reset default: `0x0` -- Reset mask: `0xffffffff` -- Register enable: [`CHECK_REGWEN`](#check_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "CONSISTENCY_CHECK_PERIOD", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:--------------------------------------------------------------------------------| -| 31:0 | rw | 0x0 | [CONSISTENCY_CHECK_PERIOD](#consistency_check_period--consistency_check_period) | - -### CONSISTENCY_CHECK_PERIOD . CONSISTENCY_CHECK_PERIOD -The pseudo-random period is generated using a 40bit LFSR internally, and this register defines -the bit mask to be applied to the LFSR output in order to limit its range. The value of this -register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. -A recommended value is 0x3FF_FFFF, corresponding to a maximum period of ~716s at 24MHz. -A value of zero disables the timer (default). Note that a one-off check can always be triggered via -[`CHECK_TRIGGER.CONSISTENCY.`](#check_trigger) - -## VENDOR_TEST_READ_LOCK -Runtime read lock for the VENDOR_TEST partition. -- Offset: `0x7c` -- Reset default: `0x1` -- Reset mask: `0x1` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "VENDOR_TEST_READ_LOCK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 230}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:----------------------|:--------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | VENDOR_TEST_READ_LOCK | When cleared to 0, read access to the VENDOR_TEST partition is locked. Write 0 to clear this bit. | - -## CREATOR_SW_CFG_READ_LOCK -Runtime read lock for the CREATOR_SW_CFG partition. -- Offset: `0x80` -- Reset default: `0x1` -- Reset mask: `0x1` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "CREATOR_SW_CFG_READ_LOCK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 260}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------------------|:-----------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | CREATOR_SW_CFG_READ_LOCK | When cleared to 0, read access to the CREATOR_SW_CFG partition is locked. Write 0 to clear this bit. | - -## OWNER_SW_CFG_READ_LOCK -Runtime read lock for the OWNER_SW_CFG partition. -- Offset: `0x84` -- Reset default: `0x1` -- Reset mask: `0x1` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "OWNER_SW_CFG_READ_LOCK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 240}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-----------------------|:---------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | OWNER_SW_CFG_READ_LOCK | When cleared to 0, read access to the OWNER_SW_CFG partition is locked. Write 0 to clear this bit. | - -## ROT_CREATOR_AUTH_CODESIGN_READ_LOCK -Runtime read lock for the ROT_CREATOR_AUTH_CODESIGN partition. -- Offset: `0x88` -- Reset default: `0x1` -- Reset mask: `0x1` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "ROT_CREATOR_AUTH_CODESIGN_READ_LOCK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 370}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:------------------------------------|:----------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | ROT_CREATOR_AUTH_CODESIGN_READ_LOCK | When cleared to 0, read access to the ROT_CREATOR_AUTH_CODESIGN partition is locked. Write 0 to clear this bit. | - -## ROT_CREATOR_AUTH_STATE_READ_LOCK -Runtime read lock for the ROT_CREATOR_AUTH_STATE partition. -- Offset: `0x8c` -- Reset default: `0x1` -- Reset mask: `0x1` -- Register enable: [`DIRECT_ACCESS_REGWEN`](#direct_access_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "ROT_CREATOR_AUTH_STATE_READ_LOCK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 340}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------------------------|:-------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | ROT_CREATOR_AUTH_STATE_READ_LOCK | When cleared to 0, read access to the ROT_CREATOR_AUTH_STATE partition is locked. Write 0 to clear this bit. | - -## VENDOR_TEST_DIGEST -Integrity digest for the VENDOR_TEST partition. -The integrity digest is 0 by default. Software must write this -digest value via the direct access interface in order to lock the partition. -After a reset, write access to the VENDOR_TEST partition is locked and -the digest becomes visible in this CSR. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:---------------------|:---------| -| VENDOR_TEST_DIGEST_0 | 0x90 | -| VENDOR_TEST_DIGEST_1 | 0x94 | - - -### Fields - -```wavejson -{"reg": [{"name": "VENDOR_TEST_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------------------|:--------------| -| 31:0 | ro | 0x0 | VENDOR_TEST_DIGEST | | - -## CREATOR_SW_CFG_DIGEST -Integrity digest for the CREATOR_SW_CFG partition. -The integrity digest is 0 by default. Software must write this -digest value via the direct access interface in order to lock the partition. -After a reset, write access to the CREATOR_SW_CFG partition is locked and -the digest becomes visible in this CSR. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:------------------------|:---------| -| CREATOR_SW_CFG_DIGEST_0 | 0x98 | -| CREATOR_SW_CFG_DIGEST_1 | 0x9c | - - -### Fields - -```wavejson -{"reg": [{"name": "CREATOR_SW_CFG_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:----------------------|:--------------| -| 31:0 | ro | 0x0 | CREATOR_SW_CFG_DIGEST | | - -## OWNER_SW_CFG_DIGEST -Integrity digest for the OWNER_SW_CFG partition. -The integrity digest is 0 by default. Software must write this -digest value via the direct access interface in order to lock the partition. -After a reset, write access to the OWNER_SW_CFG partition is locked and -the digest becomes visible in this CSR. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:----------------------|:---------| -| OWNER_SW_CFG_DIGEST_0 | 0xa0 | -| OWNER_SW_CFG_DIGEST_1 | 0xa4 | - - -### Fields - -```wavejson -{"reg": [{"name": "OWNER_SW_CFG_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:--------------------|:--------------| -| 31:0 | ro | 0x0 | OWNER_SW_CFG_DIGEST | | - -## ROT_CREATOR_AUTH_CODESIGN_DIGEST -Integrity digest for the ROT_CREATOR_AUTH_CODESIGN partition. -The integrity digest is 0 by default. Software must write this -digest value via the direct access interface in order to lock the partition. -After a reset, write access to the ROT_CREATOR_AUTH_CODESIGN partition is locked and -the digest becomes visible in this CSR. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------------------------|:---------| -| ROT_CREATOR_AUTH_CODESIGN_DIGEST_0 | 0xa8 | -| ROT_CREATOR_AUTH_CODESIGN_DIGEST_1 | 0xac | - - -### Fields - -```wavejson -{"reg": [{"name": "ROT_CREATOR_AUTH_CODESIGN_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------------------------|:--------------| -| 31:0 | ro | 0x0 | ROT_CREATOR_AUTH_CODESIGN_DIGEST | | - -## ROT_CREATOR_AUTH_STATE_DIGEST -Integrity digest for the ROT_CREATOR_AUTH_STATE partition. -The integrity digest is 0 by default. Software must write this -digest value via the direct access interface in order to lock the partition. -After a reset, write access to the ROT_CREATOR_AUTH_STATE partition is locked and -the digest becomes visible in this CSR. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:--------------------------------|:---------| -| ROT_CREATOR_AUTH_STATE_DIGEST_0 | 0xb0 | -| ROT_CREATOR_AUTH_STATE_DIGEST_1 | 0xb4 | - - -### Fields - -```wavejson -{"reg": [{"name": "ROT_CREATOR_AUTH_STATE_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:------------------------------|:--------------| -| 31:0 | ro | 0x0 | ROT_CREATOR_AUTH_STATE_DIGEST | | - -## HW_CFG0_DIGEST -Integrity digest for the HW_CFG0 partition. -The integrity digest is 0 by default. The digest calculation can be triggered via the [`DIRECT_ACCESS_CMD.`](#direct_access_cmd) -After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------|:---------| -| HW_CFG0_DIGEST_0 | 0xb8 | -| HW_CFG0_DIGEST_1 | 0xbc | - - -### Fields - -```wavejson -{"reg": [{"name": "HW_CFG0_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:--------------| -| 31:0 | ro | 0x0 | HW_CFG0_DIGEST | | - -## HW_CFG1_DIGEST -Integrity digest for the HW_CFG1 partition. -The integrity digest is 0 by default. The digest calculation can be triggered via the [`DIRECT_ACCESS_CMD.`](#direct_access_cmd) -After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------|:---------| -| HW_CFG1_DIGEST_0 | 0xc0 | -| HW_CFG1_DIGEST_1 | 0xc4 | - - -### Fields - -```wavejson -{"reg": [{"name": "HW_CFG1_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:--------------| -| 31:0 | ro | 0x0 | HW_CFG1_DIGEST | | - -## SECRET0_DIGEST -Integrity digest for the SECRET0 partition. -The integrity digest is 0 by default. The digest calculation can be triggered via the [`DIRECT_ACCESS_CMD.`](#direct_access_cmd) -After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------|:---------| -| SECRET0_DIGEST_0 | 0xc8 | -| SECRET0_DIGEST_1 | 0xcc | - - -### Fields - -```wavejson -{"reg": [{"name": "SECRET0_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:--------------| -| 31:0 | ro | 0x0 | SECRET0_DIGEST | | - -## SECRET1_DIGEST -Integrity digest for the SECRET1 partition. -The integrity digest is 0 by default. The digest calculation can be triggered via the [`DIRECT_ACCESS_CMD.`](#direct_access_cmd) -After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------|:---------| -| SECRET1_DIGEST_0 | 0xd0 | -| SECRET1_DIGEST_1 | 0xd4 | - - -### Fields - -```wavejson -{"reg": [{"name": "SECRET1_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:--------------| -| 31:0 | ro | 0x0 | SECRET1_DIGEST | | - -## SECRET2_DIGEST -Integrity digest for the SECRET2 partition. -The integrity digest is 0 by default. The digest calculation can be triggered via the [`DIRECT_ACCESS_CMD.`](#direct_access_cmd) -After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Instances - -| Name | Offset | -|:-----------------|:---------| -| SECRET2_DIGEST_0 | 0xd8 | -| SECRET2_DIGEST_1 | 0xdc | - - -### Fields - -```wavejson -{"reg": [{"name": "SECRET2_DIGEST", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:--------------| -| 31:0 | ro | 0x0 | SECRET2_DIGEST | | - -## SW_CFG_WINDOW -Any read to this window directly maps to the corresponding offset in the creator and owner software -config partitions, and triggers an OTP readout of the bytes requested. Note that the transaction -will block until OTP readout has completed. - -- Word Aligned Offset Range: `0x800`to`0xffc` -- Size (words): `512` -- Access: `ro` -- Byte writes are *not* supported. - -## Summary of the **`prim`** interface's registers - -| Name | Offset | Length | Description | -|:-------------------------|:---------|---------:|:--------------| -| otp_ctrl.[`CSR0`](#csr0) | 0x0 | 4 | | -| otp_ctrl.[`CSR1`](#csr1) | 0x4 | 4 | | -| otp_ctrl.[`CSR2`](#csr2) | 0x8 | 4 | | -| otp_ctrl.[`CSR3`](#csr3) | 0xc | 4 | | -| otp_ctrl.[`CSR4`](#csr4) | 0x10 | 4 | | -| otp_ctrl.[`CSR5`](#csr5) | 0x14 | 4 | | -| otp_ctrl.[`CSR6`](#csr6) | 0x18 | 4 | | -| otp_ctrl.[`CSR7`](#csr7) | 0x1c | 4 | | - -## CSR0 - -- Offset: `0x0` -- Reset default: `0x0` -- Reset mask: `0x7ff3ff7` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 1}, {"name": "field3", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 2}, {"name": "field4", "bits": 11, "attr": ["rw"], "rotate": 0}, {"bits": 5}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:27 | | | | Reserved | -| 26:16 | rw | 0x0 | field4 | | -| 15:14 | | | | Reserved | -| 13:4 | rw | 0x0 | field3 | | -| 3 | | | | Reserved | -| 2 | rw | 0x0 | field2 | | -| 1 | rw | 0x0 | field1 | | -| 0 | rw | 0x0 | field0 | | - -## CSR1 - -- Offset: `0x4` -- Reset default: `0x0` -- Reset mask: `0xffffffff` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 7, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 7, "attr": ["rw"], "rotate": 0}, {"name": "field3", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field4", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:16 | rw | 0x0 | field4 | | -| 15 | rw | 0x0 | field3 | | -| 14:8 | rw | 0x0 | field2 | | -| 7 | rw | 0x0 | field1 | | -| 6:0 | rw | 0x0 | field0 | | - -## CSR2 - -- Offset: `0x8` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:1 | | | | Reserved | -| 0 | rw | 0x0 | field0 | | - -## CSR3 - -- Offset: `0xc` -- Reset default: `0x0` -- Reset mask: `0x7f3ff7` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 3, "attr": ["rw1c"], "rotate": -90}, {"bits": 1}, {"name": "field1", "bits": 10, "attr": ["rw1c"], "rotate": 0}, {"bits": 2}, {"name": "field2", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field3", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field4", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field5", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field6", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field7", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field8", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 9}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:23 | | | | Reserved | -| 22 | ro | 0x0 | field8 | | -| 21 | ro | 0x0 | field7 | | -| 20 | ro | 0x0 | field6 | | -| 19 | ro | 0x0 | field5 | | -| 18 | ro | 0x0 | field4 | | -| 17 | ro | 0x0 | field3 | | -| 16 | rw1c | 0x0 | field2 | | -| 15:14 | | | | Reserved | -| 13:4 | rw1c | 0x0 | field1 | | -| 3 | | | | Reserved | -| 2:0 | rw1c | 0x0 | field0 | | - -## CSR4 - -- Offset: `0x10` -- Reset default: `0x0` -- Reset mask: `0x73ff` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 2}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field3", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 17}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:15 | | | | Reserved | -| 14 | rw | 0x0 | field3 | | -| 13 | rw | 0x0 | field2 | | -| 12 | rw | 0x0 | field1 | | -| 11:10 | | | | Reserved | -| 9:0 | rw | 0x0 | field0 | | - -## CSR5 - -- Offset: `0x14` -- Reset default: `0x0` -- Reset mask: `0xffff3fff` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 6, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field3", "bits": 3, "attr": ["ro"], "rotate": -90}, {"name": "field4", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field5", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 2}, {"name": "field6", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:16 | rw | 0x0 | field6 | | -| 15:14 | | | | Reserved | -| 13 | ro | 0x0 | field5 | | -| 12 | ro | 0x0 | field4 | | -| 11:9 | ro | 0x0 | field3 | | -| 8 | ro | 0x0 | field2 | | -| 7:6 | rw | 0x0 | field1 | | -| 5:0 | rw | 0x0 | field0 | | - -## CSR6 - -- Offset: `0x18` -- Reset default: `0x0` -- Reset mask: `0xffff1bff` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 1}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "field3", "bits": 16, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:16 | rw | 0x0 | field3 | | -| 15:13 | | | | Reserved | -| 12 | rw | 0x0 | field2 | | -| 11 | rw | 0x0 | field1 | | -| 10 | | | | Reserved | -| 9:0 | rw | 0x0 | field0 | | - -## CSR7 - -- Offset: `0x1c` -- Reset default: `0x0` -- Reset mask: `0xc73f` - -### Fields - -```wavejson -{"reg": [{"name": "field0", "bits": 6, "attr": ["ro"], "rotate": 0}, {"bits": 2}, {"name": "field1", "bits": 3, "attr": ["ro"], "rotate": -90}, {"bits": 3}, {"name": "field2", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "field3", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------| -| 31:16 | | | | Reserved | -| 15 | ro | 0x0 | field3 | | -| 14 | ro | 0x0 | field2 | | -| 13:11 | | | | Reserved | -| 10:8 | ro | 0x0 | field1 | | -| 7:6 | | | | Reserved | -| 5:0 | ro | 0x0 | field0 | | - - - diff --git a/hw/ip/otp_ctrl/doc/theory_of_operation.md b/hw/ip/otp_ctrl/doc/theory_of_operation.md deleted file mode 100644 index 540b9e04bd486..0000000000000 --- a/hw/ip/otp_ctrl/doc/theory_of_operation.md +++ /dev/null @@ -1,514 +0,0 @@ -# Theory of Operation - -Conceptually speaking, the OTP functionality is at a high level split into "front-end" and "back-end". -The "front-end" contains the logical partitions that feed the hardware and software consumer interfaces of the system. -The "back-end" represents the programming interface used by hardware and software components to stage the upcoming values. -The diagram below illustrates this behavioral model. - -![OTP Controller Block Diagram](../doc/otp_ctrl_behavioral_model.svg) - -Note that the front-end contains both buffered and unbuffered partitions. -Buffered partitions are sensed once per power cycle and their contents are stored in registers, whereas unbuffered partitions are read on-demand. -The former are typically partitions that contain data like hardware configuration bits, key material and the life cycle state that need to be always available to the hardware, whereas the latter are large partitions that are accessed infrequently, such as the software configurations. -Values that are programmed into a buffered partition via the programming interface (coupled with read verification) are merely "staged", and do not take effect until the next power cycle. - -The sections below describe the operation of various pieces of the OTP controller and how it supports the described functionality. - -## Logical Partitions - -The OTP is logically separated into partitions that represent different functions. -This means the isolation is virtual and maintained by the OTP controller instead of the underlying OTP IP. - -Within each logical partition, there are specific enforceable properties - -- Confidentiality via secret partitions - - This controls whether a particular partition contains secret data. - - If secret, a partition is not readable by software once locked, and is scrambled in storage. -- Read lockability - - This controls whether a particular partition disables software readability for later stage software. - - Some partitions can be locked statically (by computing and storing an associated digest in OTP), others can be read locked at runtime via CSRs. -- Write lockability - - This controls whether a partition is locked and prevented from future updates. - - A locked partition is stored alongside a digest to be used later for integrity verification. -- Integrity Verification - - Once a partition is write-locked by calculating and writing a non-zero [digest](#locking-a-partition) to it, it can undergo periodic verification (time-scale configurable by software). -This verification takes two forms, partition integrity checks, and storage consistency checks. - -Since the OTP is memory-like in nature (it only outputs a certain number of bits per address location), some of the logical partitions are buffered in registers for instantaneous and parallel access by hardware. -This is a critical point, since after power-up, these particular OTP contents are stored in flip flops and sourced to the system. -I.e., buffered partitions are **NOT** directly sourced from the OTP macro itself. -Thus the security of both volatile (OTP controller) and non-volatile (OTP IP) storage becomes important. - -### Partition Listing and Description - -The OTP controller for OpenTitan contains the seven logical partitions shown below. - -{{#include otp_ctrl_partitions.md}} - -Generally speaking, the production life cycle of a device is split into 5 stages "Manufacturing" -> "Calibration and Testing" -> "Provisioning" -> "Mission" -> "RMA". -OTP values are usually programmed during "Calibration and Testing", "Provisioning" and "RMA" stages, as explained below. -A detailed listing of all the items and the corresponding memory map can be found in the [Programmer's Guide](programmers_guide.md)) further below. - -### Calibration and Test - -During this stage, the device is tested for functionality and calibrated to ensure uniformity. -The calibration can focus on a number of things, but usually is centered around adjusting clock, voltage and timing sources to remove process variation. -These calibration values are programmed into the CREATOR_SW_CFG partition, as they are non-secret values meant to be read out by software and programmed into respective peripherals. - -Early on during this stage, the various tokens are also programmed into the secret partitions and harvested by the silicon creator. - -### Provisioning - -During this stage, the device is provisioned with the final firmware and a "unique" seed or identity. -The secret partitions are populated with root secrets and keys that are critical to establishing the device identity. - -As part of injecting the final firmware, the stock-keeping-unit-specific hardware and software configurations are also programmed. - -### Life Cycle Partition - -The life cycle partition is active throughout all stages and hence it is the **ONLY** partition that cannot be locked. -After the device finishes provisioning and goes into production, it must retain the ability to transition back to RMA in case of unexpected failures. - -In order to support this transition, the [life cycle state](../../lc_ctrl/README.md) and counters must always be update-able. - -## Locking a Partition - -Write access to a partition can be permanently locked when software determines it will no longer make any updates to that partition. -To lock, an integrity constant is calculated and programmed alongside the other data of that partition. -The size of that integrity constant depends on the partition size granule, and is either 32bit or 64bit (see also [Direct Access Memory Map](#direct-access-memory-map)). - -Once the "integrity digest" is non-zero, no further updates are allowed. -If the partition is secret, software is in addition no longer able to read its contents (see [Secret Partition description](#secret-vs-nonsecret-partitions)). - -Note however, in all partitions, the digest itself is **ALWAYS** readable. -This gives software an opportunity to confirm that the locking operation has proceeded correctly, and if not, scrap the part immediately. - -Calculation of the integrity digest depends on whether the partition requires periodic background verification. - -### Vendor Test Partition - -The vendor test partition is intended to be used for OTP programming smoke checks during the manufacturing flow. -The silicon creator may implement these checks inside the proprietary version of the `prim_otp` wrapper. -This partition behaves like any other SW partition, with the exception that ECC uncorrectable errors will not lead to fatal errors / alerts as they do in all other partitions. -This is due to the nature of the OTP programming smoke checks, which may leave certain OTP words in a state inconsistent with the ECC polynomial employed upon OTP readout. - -### Software Configuration Partitions - -The software configuration partitions are used as non-volatile storage for flags, configuration and calibration data. -As such, the contents of this partition are usually consumed once as part of code execution, or moved to another storage compartment somewhere in the design. -For example, the clock calibration values and the LDO calibration values are programmed to the analog sensor top (AST) at startup. - -As such, it is not necessary to check periodically at the OTP source. -Instead, software can simply check as part of secure boot and take other measures when these values are programmed into peripherals. - -For this partition it is thus the responsibility of software to calculate the integrity digest and program it into the OTP. -It is also reasonable to shadow (parts of) this partition in main memory, and there is not an immediate impact from OTP contents to hardware. - -### Hardware Configuration and Secret Partitions - -The hardware and secret partitions directly affect downstream hardware. -The contents must go through periodic integrity checks and therefore the stored digest is calculated by hardware when software provides the intent to lock (as opposed to the software partitions where the digest has to be calculated by software). - -### Life Cycle Partition - -The life cycle partition cannot be locked and will therefore not contain a stored digest. -Note however that only the life cycle controller has access to this partition, i.e., the Direct Access Interface (DAI) cannot read nor write from/to the life cycle partition. - -## Secret vs Non-Secret Partitions - -Non-secret OTP partitions hold data that can be public; or data that has no impact on security. -For example, the current value of lock bits or clock calibration values. -These values are stored in OTP as plaintext. - -Secret partitions contain data that are critical to security, for example FLASH scrambling keys, device root secret and unlock tokens. -These values are stored scrambled in OTP, and are descrambled upon read. -The currently employed cipher is PRESENT, as it lends itself well to iterative decomposition, and it is a proven lightweight block cipher (see also [PRESENT Scrambling Primitive](../../prim/doc/prim_present.md). -The usage of a block cipher however implies that the secret partitions can only be written in 64bit chunks. - -Further, the contents of a particular secret partition are not readable by software once locked (other than the digest which must be always readable); while non-secret partitions are always readable unless read accessibility is explicitly removed by software. - -Unfortunately, secret partitions must utilize a global netlist key for the scrambling operation, as there is no other non-volatile storage to store a unique key. - - -## Partition Checks - -### Integrity - -Once the appropriate partitions have been locked, the hardware integrity checker employs two integrity checks to verify the content of the volatile buffer registers: - -1. All buffered partitions have additional ECC protection (8bit ECC for each 64bit block) that is concurrently monitored. -2. The digest of the partition is recomputed at semi-random intervals and compared to the digest stored alongside the partition. - -The purpose of this check is NOT to check between the storage flops and the OTP, but whether the buffer register contents remain consistent with the calculated digest. -This verification is primarily concerned with whether the storage flops have experienced fault attacks. -This check applies to only the HW_CFG* and SECRET* partitions. -If a failure is encountered, the OTP controller will send out a `fatal_check_error` alert and reset all of its hardware outputs to their defaults. - -### Storage Consistency - -This verification ensures the value stored in the buffer registers remain consistent with those in the OTP. -This process re-reads the OTP at semi-random intervals and confirms the value read is the same as the value stored. -Note, given there are integrity checks in parallel, it is not necessary for some partitions to check ALL read contents for consistency. -If there is an integrity digest, only the digest needs to be read; otherwise, all values must be read. - - -This check applies to LIFE_CYCLE, HW_CFG* and SECRET* partitions. -If a failure is encountered, the OTP controller will send out a `fatal_check_error` alert and reset all of its hardware outputs to their defaults. - -Note that checks applied to life cycle could cause a failure if life cycle is updated, because life cycle is the only partition that may contain live updates. -The controller hence detects this condition based on the `lc_check_byp_en_i` signal coming from the life cycle controller, and pauses background checks on this partition in order to prevent false positives. - -### Secret Partition Integrity Checks - -Since the secret partitions are stored scrambled, this also implies the integrity digest is calculated over the scrambled form. -In order to balance the amount of buffer registers needed, only the decrypted form of the secret partitions is held in buffer registers. -Hardware calculates the digest by re-scrambling the data before passing it through the digest. - - -## Power-up and Sense - -The OTP controller partition storage must output a specified safe default (it is not always 0 like a blank OTP) upon reset release. -This default output must remain until the OTP controller completes all checks. - -The OTP controller reads from the OTP IP. -If the reads pass OTP IP internal checks (for example ECC or redundancy), the partition storage is updated; however the output is still held at the default state via an output mux. -After all read is complete, the OTP controller performs integrity checks on the HW_CFG* and SECRET* partitions. -If a partition fails the integrity checks at this point it would signal an initialization error in the status CSR and abort further initialization. - -After all integrity checks are complete, the OTP controller releases the output gating and marks outputs as valid. -However, any partition marked with "error" continues to hold its output in the default state. - -Once the above steps are complete, the partition storage in buffered registers is not updated again (except for updates to the life cycle partition through the life cycle interface). -I.e., values programmed to OTP via the programming interface will not be visible in buffered registers until after the next power cycle. - -At this point, outputs of the partition storage are NOT expected to change unless a periodic check suddenly fails. -When this failure occurs, all outputs are reverted to their default state, and an alert is immediately triggered to the alert handler. -For timing purposes, OTP outputs can be treated as semi-static, as this error event should be rare and exceptional. - - -## Partition Defaults - -Partition defaults are context specific. -For example, a hardware configuration item that locks down specific access should default to "no access". -This ensures that a glitch attack on the OTP cannot easily revert the design to an insecure state. - -This hence suggests that when an OTP is all 0's and all 1's, it should, whenever possible, reflect an invalid or inert state in the encoding space of the affected item. -This also implies the reset state of consuming agents (for example key manager and life cycle), should default to invalid / inert state as well. - - -## Program and Read Ports - -As shown previously, the OTP is split into a front and back end. -The back-end interface is primarily used to update OTP contents, and read back for debug and verification purposes. -Despite being a separate functional access port from the logical partitions, the program and read ports are subjected to the same access controls. - -When a partition is write-locked, programming accesses are disallowed. -If the partition is secret, read accesses by the back-end interface are also disallowed (except for the digest which must always be readable). -Software can also disable any read accesses to the software configuration partitions via CSR settings to prevent later stage software from reading any content. - -The exception to the above is the life cycle partition. -The life cycle controller interface also acts as a "back-end" interface that always has programming access to ensure life cycle state can be advanced. - -Note, the program and read ports can conflict with ongoing background storage checks, and the OTP controller arbitrates between these two sides. -An in-progress operation will always be completed. -Afterwards, or when two requests arrive at the same time, the priority is life cycle > programming interface > on-demand read accesses via CSR windows > background checks. - - -## Programming the OTP - -The OTP controller has two programming paths: - -1. a functional programming path through software (the program port), -2. Life cycle programming path through hardware. - -The functional interface is used to update all partitions except for life cycle. -As mentioned previously, any updates made during the current power cycle are **NOT** reflected in the buffered partitions until the next reboot. - -The life cycle interface is used to update the life cycle state and transition counter only. -The commands are issued from the [life cycle controller](../../lc_ctrl/README.md), and similarly, successful or failed indications are also sent back to the life cycle controller. -Similar to the functional interface, the life cycle controller allows only one update per power cycle, and after a requested transition reverts to an inert state until reboot. - -For more details on how the software programs the OTP, please refer to the [Programmer's Guide](programmers_guide.md)) further below. - - -## Design Details - -### Block Diagram - -The following is a high-level block diagram that illustrates everything that has been discussed. - -![OTP Controller Block Diagram](../doc/otp_ctrl_blockdiag.svg) - -Each of the partitions P0-P7 has its [own controller FSM](#partition-implementations) that interacts with the OTP wrapper and the [scrambling datapath](#scrambling-datapath) to fulfill its tasks. -The partitions expose the address ranges and access control information to the Direct Access Interface (DAI) in order to block accesses that go to locked address ranges. -Further, the only two blocks that have (conditional) write access to the OTP are the DAI and the Life Cycle Interface (LCI) blocks. -The partitions can only issue read transactions to the OTP macro. -Note that the access ranges of the DAI and the LCI are mutually exclusive. -I.e., the DAI cannot read from nor write to the life cycle partition. -The LCI cannot read the OTP, but is allowed to write to the life cycle partition. - -The CSR node on the left side of this diagram connects to the DAI, the OTP partitions (P0-P7) and the OTP wrapper through a gated TL-UL interface. -All connections from the partitions to the CSR node are read-only, and typically only carry a subset of the information available. -E.g., the secret partitions only expose their digest value via the CSRs. - -The Key Derivation Interface (KDI) on the bottom right side interacts with the scrambling datapath, the EDN and the partition holding the scrambling root keys in order to derive static and ephemeral scrambling keys for FLASH and SRAM scrambling. - -The test access gate shown at the top of the block diagram is governed by the life cycle qualification signal `dft_en_i`, which is only enabled during the TEST_UNLOCKED* life cycle states. -Otherwise, test access via this TL-UL window is locked down. - -In addition to the blocks mentioned so far, the OTP controller also contains an LFSR timer that creates pseudo-randomly distributed partition check requests, and provides pseudo random data at high bandwidth in the event of a secure erase request due to chip-wide alert escalation. -For security reasons, the LFSR is periodically reseeded with entropy coming from EDN. - -### Data Allocation and Packing -#### Software View - -The effective word width of an OTP IP typically depends on a couple of factors, including the redundancy scheme employed. -For this the design at hand, it is assumed that this native OTP word-width is 16bit. -For software convenience, however, these details are abstracted and the open-source OTP controller exposes the OTP storage as a linear address space of 32bit words, which is aligned with the machine word size of the Ibex processor. -Since the OTP IP employs a redundancy mechanism similar to ECC, this implies however that write operations take place at a granularity of 32bit blocks for non-secret and 64bit blocks for secret partitions (due to the scrambling). -Hence, software is responsible to appropriately pack and program items, since each 32bit location can only be programmed once. - -#### Life Cycle View - -Since the life cycle partition is the only partition that needs live updates in-field, proper care must be taken to properly encode data in this partition such that incremental updates are possible. -The life cycle state is hence encoded such that incremental updates to the state are always carried out at the granularity of a 16bit word. -Further, the life cycle transition counter is encoded such that each stroke consumes a full 16bit word for the same reason. - -See [life cycle controller documentation](../../lc_ctrl/README.md) for more details on the life cycle encoding. - -### Partition Controllers - -In RTL, we distinguish between buffered and unbuffered partition modules. -These are parameterized, such that we can assemble the array of OTP partitions with these two modules only. -The corresponding controller FSMs are explained in more detail below. - -#### Unbuffered Partition - -![Unbuffered Partition FSM](../doc/otp_ctrl_unbuf_part_fsm.svg) - -As shown above, the unbuffered partition module has a relatively simple controller FSM that only reads out the digest value of the partition upon initialization, and then basically waits for TL-UL read transactions to its corresponding window in the CSR space. - -Write access through the DAI will be locked in case the digest is set to a non-zero value. -Also, read access through the DAI and the CSR window can be locked at runtime via a CSR. -Read transactions through the CSR window will error out if they are out of bounds, or if read access is locked. - -Note that unrecoverable [OTP errors](#generalized-open-source-interface), ECC failures in the digest register or external escalation via `lc_escalate_en` will move the partition controller into a terminal error state. - -#### Buffered Partition - -![Buffered Partition FSM](../doc/otp_ctrl_buf_part_fsm.svg) - -The controller FSM of the buffered partition module is more complex than the unbuffered counterpart, since it has to account for scrambling and digest calculation. - -Upon initialization, the controller reads out the whole partition and descrambles it on the fly if needed. - -Then, right after the initial readout, the partition controller jumps into the first integrity check, which behaves somewhat differently, depending on whether the partition is digest protected (or not) and/or scrambled (or not). -If the partition is not digest protected, or if the digest has not yet been computed, the check completes right away, and the buffered values are released for hardware broadcast. -Otherwise, the partition contents in the buffer registers are re-scrambled if needed, and a digest is computed on the fly. -If the computed digest matches with the one that has been read out before, the buffered registers are released for hardware broadcast. -Otherwise, the buffered values are gated to their default, and an alert is triggered through the error handling logic. - -After initialization, the integrity check (as described above) and the consistency check can be triggered by the LFSR timer mechanism on a periodic basis. - -The consistency check behaves differently, depending on whether the partition is digest protected or not. -If it is, the consistency check will read out the digest stored in OTP and compare it with the value stored in the buffer register. -Otherwise, if no digest is available, the controller will read out the whole partition from OTP, and compare it to the contents stored in the buffer registers. -In case of a mismatch, the buffered values are gated to their default, and an alert is triggered through the error handling logic. - -Note that in case of unrecoverable OTP errors or ECC failures in the buffer registers, the partition controller FSM is moved into a terminal error state, which locks down all access through DAI and clamps the values that are broadcast in hardware to their defaults. - -External escalation via the `lc_escalate_en` signal will move the partition controller FSM into the terminal error state as well. -See [life cycle controller documentation](../../lc_ctrl/README.md) for more details. - -### Direct Access Interface Control - -![Direct Access Interface FSM](../doc/otp_ctrl_dai_fsm.svg) - -Upon reset release, the DAI controller first sends an initialization command to the OTP macro. -Once the OTP macro becomes operational, an initialization request is sent to all partition controllers, which will read out and initialize the corresponding buffer registers. -The DAI then becomes operational once all partitions have initialized, and supports read, write and digest calculation commands (see [here](#direct-access-interface) for more information about how to interact with the DAI through the CSRs). - -Read and write commands transfer either 32bit or 64bit of data from the OTP to the corresponding CSR and vice versa. The access size is determined automatically, depending on whether the partition is scrambled or not. Also, (de)scrambling is performed transparently, depending on whether the partition is scrambled or not. - -Digest calculation commands read out the complete contents of a particular partition, compute a digest and write that digest value to the predefined location at the end of the partition. - -Note that any unrecoverable OTP error will move the DAI into a terminal error state, where all access through the DAI will be locked. -Also, the DAI consumes the read and write access information provided by the partition controller, and if a certain read or write access is not permitted, a recoverable error will be flagged in the status / error CSRs. - -### Life Cycle Interface Control - -![Life Cycle Interface FSM](../doc/otp_ctrl_lci_fsm.svg) - -Upon reset release the LCI FSM waits until the OTP controller has initialized and the LCI gets enabled. -Once it is in the idle state, life cycle state updates can be initiated via the life cycle interface as [described here](#state-transitions). -The LCI controller takes the life cycle state to be programmed and writes all 16bit words to OTP. -In case of unrecoverable OTP errors, the FSM signals an error to the life cycle controller and moves into a terminal error state. - -### Key Derivation Interface - -![Key Derivation Interface FSM](../doc/otp_ctrl_kdi_fsm.svg) - -Upon reset release the KDI FSM waits until the OTP controller has initialized and the KDI gets enabled. -Once it is in the idle state, key derivation can be requested via the [flash](#interface-to-flash-scrambler) and [sram](#interface-to-sram-and-otbn-scramblers) interfaces. -Based on which interface makes the request, the KDI controller will evaluate a variant of the PRESENT digest mechanism as described in more detail below. - -### Scrambling Datapath - -![OTP Digest Mechanism](../doc/otp_ctrl_digest_mechanism.svg) - -The scrambling datapath is built around an iterative implementation of the [PRESENT lightweight cipher](../../prim/doc/prim_present.md) that performs one round per cycle. -The datapath contains some additional multiplexing circuitry to enable the DAI, KDI and partition controllers to evaluate different functions with the same datapath. -The algorithmic steps of these functions are explained in more detail below. - -#### Scrambling - -As illustrated in subfigure a) in the diagram above, the standard 128bit-key PRESENT configuration with 31 rounds is used for scrambling operations. -The key used for scrambling is a global netlist constant chosen by the silicon creator, and all secret partitions are encrypted using the their own distinct netlist constant. -Note that the amount of data that is being scrambled is small (160byte = 20 x 64bit blocks) and the scrambled data remains constant. -Hence, no additional masking or diversification scheme is applied since only a very limited amount of information can be gathered by observing the scrambling operation via side-channels. - -#### Digest Calculation - -The integrity digests used in the [partition checks](#partition-checks) are computed using a custom [Merkle-Damgard](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction) scheme, where the employed one-way compression function F is constructed by using PRESENT in a [Davies-Meyer arrangement](https://en.wikipedia.org/wiki/One-way_compression_function#Davies%E2%80%93Meyer). -This is illustrated in subfigure b). - -At the beginning of the digest calculation the 64bit state is initialized with an initialization vector (IV). -Then, the data to be digested is split into 128bit chunks, each of which is used as a 128bit key input for updating the 64bit state with the compression function F. -Chunks that are not aligned with 128bit are padded with zero, and the finalization operation consists of another 31-round encryption pass with a finalization constant. -Note that both the IV as well as the finalization constant are global netlist constants chosen by the silicon creator. - -#### Scrambling Key Derivation - -The key derivation functions for ephemeral SRAM and static FLASH scrambling keys employ a similar construction as the digest calculation function. -In particular, the keys are derived by repeatedly reducing a (partially random) block of data into a 64bit block, as illustrated in subfigures c) and d). - -For ephemeral SRAM scrambling keys, the data block is composed of the 128bit SRAM_DATA_KEY_SEED stored in OTP, as well as 128bit of fresh entropy fetched from the EDN. -This process is repeated twice in order to produce a 128bit key. - -For static FLASH scrambling keys, the data block is composed of a 128bit part of either the FLASH_DATA_KEY_SEED or the FLASH_ADDR_KEY_SEED stored in OTP. -These key seeds are 256bit in size, allowing to use a unique chunk of 128bit of key seed data to derive a 64bit halve of a particular scrambling key. - -Note that the IV and finalization constants are distinct for SRAM and FLASH data and FLASH address scrambling keys. -These constants are chosen by the silicon creator prior to the tapeout. - -### Access Arbitration - -Access to the OTP wrapper and the scrambling datapath are both round-robin arbitrated, where the former arbitration occurs at cycle level (i.e., individual OTP memory accesses), and the latter occurs at the level of complete transactions (i.e., full digest or encryption). -Arbitration at transaction level is implemented similarly to cycle-based arbitration, with the difference that the grant signals remain asserted until the requestor deasserts the request (thereby releasing the arbiter, which acts as a mutex in this case). -This is behavior illustrated in the example below. - -```wavejson -{signal: [ - {name: 'clk_i', wave: 'p............'}, - {name: 'part_scrmbl_mtx_req[0]', wave: '01....0.1....'}, - {name: 'part_scrmbl_mtx_req[1]', wave: '0.1......0...'}, - {name: 'part_scrmbl_mtx_req[2]', wave: '0.1........0.'}, - {}, - {name: 'part_scrmbl_mtx_gnt[0]', wave: '01....0....1.'}, - {name: 'part_scrmbl_mtx_gnt[1]', wave: '0.....1..0...'}, - {name: 'part_scrmbl_mtx_gnt[2]', wave: '0........1.0.'}, -]} -``` - -### Primitive Wrapper and FPGA Emulation - -![OTP Wrapper Block Diagram](../doc/otp_ctrl_prim_otp.svg) - -The OTP IP is wrapped up in a primitive wrapper that exposes a TL-UL interface for testing purposes, and a generalized open-source interface for functional operation (described below). -Any OTP redundancy mechanism like per-word ECC is assumed to be handled inside the wrapper, which means that the word width exposed as part of the generalized interface is the effective word width. - -Note that the register space exposed via the TL-UL test interface, as well as DFT and power-related signals are dependent on the underlying proprietary OTP IP. -They are therefore not further described in this document. - -#### Generalized Open-source Interface - -The generalized open-source interface uses a couple of parameters (defaults set for Earlgrey configuration). - -Parameter | Default | Top Earlgrey | Description ----------------|---------|---------------|--------------- -`Width` | 16 | 16 | Native OTP word width. -`Depth` | 1024 | 1024 | Depth of OTP macro. -`CmdWidth` | 7 | 7 | Width of the OTP command. -`ErrWidth` | 3 | 3 | Width of error code output signal. -`PwrSeqWidth` | 2 | 2 | Width of power sequencing signals to/from AST. -`SizeWidth` | 2 | 2 | Width of the size field. -`IfWidth` | 2^`SizeWidth` * `Width` | 2^`SizeWidth` * `Width` | Data interface width. - -The generalized open-source interface is a simple command interface with a ready / valid handshake that makes it possible to introduce back pressure if the OTP macro is not able to accept a command due to an ongoing operation. - -In order to facilitate the scrambling and digest operations, the data width has been sized such that data blocks up to the PRESENT block size (64bit) can be transferred across the generalized interface. The actual size of a transfer is determined via the size_i field. Transfer sizes are specified in multiples of the native OTP block size, as listed below. - -Value of `size_i` | #Native OTP Words | Bit Slice -------------------|-------------------|------------ -2'b00 | 1 | `{word0} = data[15:0]` -2'b01 | 2 | `{word1, word0} = data[31:0]` -2'b10 | 3 | `{word2, word1, word0} = data[47:0]` -2'b11 | 4 | `{word3, word2, word1, word0} = data[63:0]` - -Responses are returned in-order via an unidirectional response interface (i.e., without back pressure capability). -Downstream logic must be able to sink the response in any case. -The response optionally carries read data, depending on whether the operation that took place was a read or not. -Also, an error signal returns a non-zero error code in case an error occurred while carrying out the OTP command. - -The signals pertaining to the generalized open-source interface are listed below. - -Signal | Direction | Type | Description -------------------------|------------------|-----------------------------|--------------- -`fatal_alert_o` | `output` | `logic` | Fatal alert output from the primitive. This is connected to a separate alert channel in the instantiating IP. The instantiating IP latches the alert indication and continuously outputs alert events until reset. -`recov_alert_o` | `output` | `logic` | Recoverable alert output from the primitive. This is connected to a separate alert channel in the instantiating IP. Should only be pulsed high for each alert occurrence. The instantiating IP then sends out a single alert event for each pulse. -`ready_o` | `output` | `logic` | Ready signal for the command handshake. -`valid_i` | `input` | `logic` | Valid signal for the command handshake. -`size_i` | `input` | `logic [SizeWidth-1:0]` | Number of native OTP words to transfer, minus one: `2'b00 = 1 native word` ... `2'b11 = 4 native words`. -`cmd_i` | `input` | `logic [CmdWidth-1:0]` | OTP command: `7'b1000101 = read`, `7'b0110111 = write`, `7'b1111001 = read raw`, `7'b1100010 = write raw`, `7'b0101100 = initialize` -`addr_i` | `input` | `logic [$clog2(Depth)-1:0]` | OTP word address. -`wdata_i` | `input` | `logic [IfWidth-1:0]` | Write data for write commands. -`valid_o` | `output` | `logic` | Valid signal for command response. -`rdata_o` | `output` | `logic [IfWidth-1:0]` | Read data from read commands. -`err_o` | `output` | `logic [ErrWidth-1:0]` | Error code. - -The `write raw` and `read raw` command instructs the `prim_otp` wrapper to store / read the data in raw format without generating nor checking integrity information. -That means that the wrapper must return the raw, uncorrected data and no integrity errors. - -The `prim_otp` wrapper implements the `Macro*` error codes (0x0 - 0x4) defined in [OTP error handling](#error-handling). - -The timing diagram below illustrates the timing of a command. -Note that both read and write commands return a response, and each command is independent of the previously issued commands. -The latency from accepting a command to returning a response depends on the underlying OTP IP and is typically larger than 10 cycles. -The returned values depend on the command type and whether an error occurred or not. - -```wavejson -{ - signal: [ - { name: 'clk_i', wave: 'p.............' }, - { name: 'ready_o', wave: '0..10|.10.|...' , node: '...a...c'}, - { name: 'valid_i', wave: '01..0|1.0.|...' }, - { name: 'size_i', wave: '03..0|3.0.|...' }, - { name: 'cmd_i', wave: '04..0|4.0.|...' }, - { name: 'wdata_i', wave: '05..0|5.0.|...' }, - { name: 'valid_o', wave: '0....|..10|.10' , node: '........b...d'}, - { name: 'rdata_o', wave: '0....|..50|.50' }, - { name: 'err_o', wave: '0....|..40|.40' }, - ], - edge: [ - 'a~>b', - 'c~>d', - ], - head: { - text: 'Timing of an OTP command.', - }, - foot: { - text: "Cmd's are accepted in cycles 3/7, and the corresponding responses return in cycles 8/12.", - tick: 0, - } -} -``` - -Note that the open source OTP controller allows up to two outstanding OTP commands, meaning that it is permissible to acknowledge an incoming command and start working on it while the results of the last command are still in the process of being output (e.g., due to an output register stage). - -#### Generic Simulation and FPGA Emulation Model - -For open-source simulation and FPGA emulation, a synthesizable and generic OTP wrapper module is provided (`prim_generic_otp`). -This is automatically selected in the OpenTitan build flow via the technology primitive mechanism if no proprietary OTP IP is available for a specific technology. -The OTP storage in `prim_generic_otp` is emulated using a standard RAM primitive `prim_generic_ram_1p`. -While this storage element is volatile, the primitive is constructed such that the contents are not wiped upon a system-wide reset. -I.e., only a power-cycle wipes the RAM primitive, thereby enabling limited emulation of the OTP function and life cycle transitions also on an FPGA device. diff --git a/hw/ip/otp_ctrl/dv/README.md b/hw/ip/otp_ctrl/dv/README.md deleted file mode 100644 index 23b6ec64751df..0000000000000 --- a/hw/ip/otp_ctrl/dv/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# OTP_CTRL DV document - -## Goals -* **DV** - * Verify all OTP_CTRL IP features by running dynamic simulations with a SV/UVM based testbench - * Develop and run all tests based on the [testplan](#testplan) below towards closing code and functional coverage on the IP and all of its sub-modules -* **FPV** - * Verify TileLink device protocol compliance with an SVA based testbench - -## Current status -* [Design & verification stage](../../../README.md) - * [HW development stages](../../../../doc/project_governance/development_stages.md) -* [Simulation results](https://reports.opentitan.org/hw/ip/otp_ctrl/dv/latest/report.html) - -## Design features -For detailed information on OTP_CTRL design features, please see the [OTP_CTRL HW IP technical specification](../README.md). - -## Testbench architecture -OTP_CTRL testbench has been constructed based on the [CIP testbench architecture](../../../dv/sv/cip_lib/README.md). - -### Block diagram -![Block diagram](./doc/tb.svg) - -### Top level testbench -Top level testbench is located at `hw/ip/otp_ctrl/dv/tb.sv`. It instantiates the OTP_CTRL DUT module `hw/ip/otp_ctrl/rtl/otp_ctrl.sv`. -In addition, it instantiates the following interfaces, connects them to the DUT and sets their handle into `uvm_config_db`: -* [Clock and reset interface](../../../dv/sv/common_ifs/README.md) -* [TileLink host interface](../../../dv/sv/tl_agent/README.md) -* OTP_CTRL IOs -* Interrupts ([`pins_if`](../../../dv/sv/common_ifs/README.md)) -* Alerts ([`alert_esc_if`](../../../dv/sv/alert_esc_agent/README.md)) - -### Common DV utility components -The following utilities provide generic helper tasks and functions to perform activities that are common across the project: -* [dv_utils_pkg](../../../dv/sv/dv_utils/README.md) -* [csr_utils_pkg](../../../dv/sv/csr_utils/README.md) - -### Global types & methods -All common types and methods defined at the package level can be found in -`otp_ctrl_env_pkg`. Some of them in use are: -```systemverilog - parameter uint SCRAMBLE_DATA_SIZE = 64; - parameter uint SCRAMBLE_KEY_SIZE = 128; - parameter uint NUM_ROUND = 31; - - typedef enum bit [2:0] { - OtpNoError, - OtpMacroError, - OtpMacroEccCorrError, - OtpMacroEccUncorrError, - OtpMacroWriteBlankError, - OtpAccessError, - OtpCheckFailError, - OtpFsmStateError - } otp_err_code_e; -``` - -### TL_agent -OTP_CTRL testbench instantiates (already handled in CIP base env) [tl_agent](../../../dv/sv/tl_agent/README.md), which provides the ability to drive and independently monitor random traffic via TL host interface into OTP_CTRL device. - -### Alert_agents -OTP_CTRL testbench instantiates (already handled in CIP base env) two [alert_agents](../../../dv/sv/alert_esc_agent/README.md): -fatal_check_alert and fatal_macro_alert. -The alert_agents provide the ability to drive and independently monitor alert handshakes via alert interfaces in OTP_CTRL device. - -### OTP_CTRL interface -OTP_CTRL design has specific inputs and outputs to communicate with other IPs including LC_CTRL, OTBN, SRAM, FLASH etc. -This interface is created to initialize, use simple task to drive, and use assertions to monitor these signals. - -### Memory backdoor interface -OTP_CTRL testbench binds design's non-volatile OTP memory with a [`mem_bkdr_util`](../../../dv/sv/mem_bkdr_util/README.md), which supports read, write, and injection of ECC errors to design's OTP memory. - -### UVM RAL model -The OTP_CTRL RAL model is created with the [`ralgen`](../../../dv/tools/ralgen/README.md) FuseSoC generator script automatically when the simulation is at the build stage. - -It can be created manually by invoking [`regtool`](../../../../util/reggen/doc/setup_and_use.md). - -### Reference models -The OTP_CTRL's utilizes [PRESENT](../../prim/doc/prim_present.md as the cipher to scramble and protect secrets. -Thus OTP_CTRL's scoreboard adopted PRESENT's C reference model, located under `hw/ip/prim/dv/prim_present/` folder, for encryption and decryption purpose. - -### Stimulus strategy -#### Test sequences -All test sequences reside in `hw/ip/otp_ctrl/dv/env/seq_lib`. -The `otp_ctrl_base_vseq` virtual sequence is extended from `cip_base_vseq` and serves as a starting point. -All test sequences are extended from `otp_ctrl_base_vseq`. -It provides commonly used handles, variables, functions and tasks that the test sequences can simple use / call. -Some of the most commonly used tasks / functions are as follows: -* dai_wr: This task triggers an OTP write sequence via the DAI interface. -* dai_rd: This task triggers an OTP read sequence via the DAI interface. -* trigger_checks: This task triggers a one-time OTP check and user can choose to trigger consistency check or integrity check. -* randomize_dai_addr: This task takes a DAI address as input and randomize its last two bits, because the last two bits should be ignored in design. - -#### Functional coverage -To ensure high quality constrained random stimulus, it is necessary to develop a functional coverage model. -The following two files declared OTP_CTRL's covergroups: -- `dv/env/otp_ctrl_env_cov.sv` declares functional or CSR related covergroups. -The functional coverage is collected manually inside OTP_CTRL's scoreboard by invoking the `sample` function. -- `dv/cov/otp_ctrl_cov_if.sv` declares interface signal related covergroups. -The functional coverage is collected automatically when the sampled signal is active. - -### Self-checking strategy -#### Scoreboard -The `otp_ctrl_scoreboard` is primarily used for end to end checking. -It creates the following analysis ports to retrieve the data monitored by corresponding interface agents: -* tl_a_chan_fifo: tl address channel -* tl_d_chan_fifo: tl data channel -* alert_fifos: alert handshakes -* sram_fifos: sram requests -* otbn_fifo: otbn request -* lc_prog_fifo: life cycle programming request -* lc_token_fifo: life cycle token request -* flash_addr_fifo: flash address request -* flash_data_fifo: flash data request -* edn_fifo: edn response to OTP_CTRL - -For all requests to OTP_CTRL as listed above, scoreboard has a corresponding task to process request, check OTP_CTRL's response value against encryption, and collect coverage. - -OTP_CTRL's scoreboard has an internal array `otp_a` that tracks OTP memory data. -Every successful OTP write operation will update this internal array, and every successful OTP read operation will check the readout value against this internal array. -Note that in design, secret partitions will go through a encryption before writing to the actually OTP memory, and will be decrypted upon a read request. -For the simplicity of this internal array, we will skip this procedure. -However, if scoreboard backdoor read any secret partitions, we will decrypt the data then write the decrypted data to the internal array. -For any operation that fails, the scoreboard will predict the status and err_code according to the failure type. -If the error can trigger alert, scoreboard will use `set_exp_alert` task to check if the alert is firing correctly. -If a HW digest operation is triggered by sequence, scoreboard will calculate digest value with partition data from its internal array and update the digest value. -According to design spec, scoreboard won't lock the partition and predict the digest value to digest registers until next power cycle. - -If a reset or lc_escalation_en is issued during an OTP_CTRL write operation, scoreboard cannot accurately predict how many bits have been programmed into OTP memory. -To avoid mismatches, scoreboard utilizes flags `dai_wr_ip` and `dai_digest_ip` to track otp write operations, and issue a backdoor read if the write operation is interrupted. - -#### Assertions -* TLUL assertions: The `tb/otp_ctrl_bind.sv` binds the `tlul_assert` [assertions](../../tlul/doc/TlulProtocolChecker.md) to the IP to ensure TileLink interface protocol compliance. -* Unknown checks on DUT outputs: The RTL has assertions to ensure all outputs are initialized to known values after coming out of reset. -* OTP_CTRL_IF assertions: This interface has assertions to ensure certain OTP_CTRL's outputs (such as: otp_broadcast_o, keymgr_key_o) are stable after OTP initialization. - -## Building and running tests -We are using our in-house developed [regression tool](../../../../util/dvsim/README.md) for building and running our tests and regressions. -Please take a look at the link for detailed information on the usage, capabilities, features and known issues. -Here's how to run a smoke test: -```console -$ $REPO_TOP/util/dvsim/dvsim.py $REPO_TOP/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson -i otp_ctrl_smoke -``` - -## Testplan -[Testplan](../data/otp_ctrl_testplan.hjson) diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov.core b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov.core deleted file mode 100644 index 361da46371a06..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov.core +++ /dev/null @@ -1,24 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:otp_ctrl_cov" -description: "OTP_CTRL functional coverage and bind files" -filesets: - files_rtl: - depend: - - lowrisc:ip:otp_ctrl - - files_dv: - depend: - - lowrisc:dv:dv_utils - files: - - otp_ctrl_cov_if.sv - - otp_ctrl_cov_bind.sv - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_rtl - - files_dv diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_bind.sv b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_bind.sv deleted file mode 100644 index 308ee9822e3fd..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_bind.sv +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Binds OTP_CTRL functional coverage interaface to the top level OTP_CTRL module. -// -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -`define PART_MUBI_COV(__part_name, __index) \ - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) ``__part_name``_read_lock_mubi_cov_if ( \ - .rst_ni (rst_ni), \ - .mubi (part_access[``__index``].read_lock) \ - ); \ - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) ``__part_name``_write_lock_mubi_cov_if ( \ - .rst_ni (rst_ni), \ - .mubi (part_access[``__index``].write_lock) \ - ); - -`define DAI_MUBI_COV(__part_name, __index) \ - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) dai_``__part_name``_read_lock_mubi_cov_if ( \ - .rst_ni (rst_ni), \ - .mubi (part_access_dai[``__index``].read_lock) \ - ); \ - bind otp_ctrl cip_mubi_cov_if #(.Width(8)) dai_``__part_name``_write_lock_mubi_cov_if ( \ - .rst_ni (rst_ni), \ - .mubi (part_access_dai[``__index``].write_lock) \ - ); - -module otp_ctrl_cov_bind; - import otp_ctrl_part_pkg::*; - - bind otp_ctrl otp_ctrl_cov_if u_otp_ctrl_cov_if ( - .pwr_otp_o (pwr_otp_o), - .lc_otp_program_i (lc_otp_program_i), - .lc_escalate_en_i (lc_escalate_en_i), - .flash_otp_key_i (flash_otp_key_i), - .sram_otp_key_i (sram_otp_key_i), - .otbn_otp_key_i (otbn_otp_key_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_creator_seed_sw_rw_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_creator_seed_sw_rw_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_seed_hw_rd_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_seed_hw_rd_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_dft_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_dft_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_escalate_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_escalate_en_i) - ); - - bind otp_ctrl cip_lc_tx_cov_if u_lc_check_byp_en_cov_if ( - .rst_ni (rst_ni), - .val (lc_check_byp_en_i) - ); - - // Mubi internal coverage for buffered and unbuffered partitions. - `PART_MUBI_COV(vendor_test, otp_ctrl_part_pkg::VendorTestIdx) - `PART_MUBI_COV(creator_sw_cfg, otp_ctrl_part_pkg::CreatorSwCfgIdx) - `PART_MUBI_COV(owner_sw_cfg, otp_ctrl_part_pkg::OwnerSwCfgIdx) - `PART_MUBI_COV(rot_creator_auth_codesign, otp_ctrl_part_pkg::RotCreatorAuthCodesignIdx) - `PART_MUBI_COV(rot_creator_auth_state, otp_ctrl_part_pkg::RotCreatorAuthStateIdx) - `PART_MUBI_COV(hw_cfg0, otp_ctrl_part_pkg::HwCfg0Idx) - `PART_MUBI_COV(hw_cfg1, otp_ctrl_part_pkg::HwCfg1Idx) - `PART_MUBI_COV(secret0, otp_ctrl_part_pkg::Secret0Idx) - `PART_MUBI_COV(secret1, otp_ctrl_part_pkg::Secret1Idx) - `PART_MUBI_COV(secret2, otp_ctrl_part_pkg::Secret2Idx) - - // Mubi internal coverage for DAI interface access - `DAI_MUBI_COV(vendor_test, otp_ctrl_part_pkg::VendorTestIdx) - `DAI_MUBI_COV(creator_sw_cfg, otp_ctrl_part_pkg::CreatorSwCfgIdx) - `DAI_MUBI_COV(owner_sw_cfg, otp_ctrl_part_pkg::OwnerSwCfgIdx) - `DAI_MUBI_COV(rot_creator_auth_codesign, otp_ctrl_part_pkg::RotCreatorAuthCodesignIdx) - `DAI_MUBI_COV(rot_creator_auth_state, otp_ctrl_part_pkg::RotCreatorAuthStateIdx) - `DAI_MUBI_COV(hw_cfg0, otp_ctrl_part_pkg::HwCfg0Idx) - `DAI_MUBI_COV(hw_cfg1, otp_ctrl_part_pkg::HwCfg1Idx) - `DAI_MUBI_COV(secret0, otp_ctrl_part_pkg::Secret0Idx) - `DAI_MUBI_COV(secret1, otp_ctrl_part_pkg::Secret1Idx) - `DAI_MUBI_COV(secret2, otp_ctrl_part_pkg::Secret2Idx) - -`undef PART_MUBI_COV -`undef DAI_MUBI_COV -endmodule diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_fsm_unr_excl.el b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_fsm_unr_excl.el deleted file mode 100644 index 1c3412b695418..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_fsm_unr_excl.el +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// The current UNR flow marks some transition to reset states as unreachable. -// This file manually removed the reset transition states. -//================================================== -// This file contains the Excluded objects -// Generated By User: chencindy -// Format Version: 2 -// Date: Fri Jan 6 11:14:02 2023 -// ExclMode: default -//================================================== -CHECKSUM: "2063559012 2582220255" -INSTANCE: tb.dut.gen_partitions[3].gen_buffered.u_part_buf -Fsm state_q "441128463" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -Transition IntegDigSt->IntegDigFinSt "1890->1765" -Fsm state_q "441128463" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -State InitDescrWaitSt "2472" -Fsm state_q "441128463" -State IntegScrSt "3418" -Fsm state_q "441128463" -State IntegScrWaitSt "2207" -Fsm state_q "441128463" -State InitDescrSt "3204" -Fsm error_q "2410907799" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2410907799" -Transition CheckFailError->FsmStateError "6->7" -CHECKSUM: "2063559012 2582220255" -INSTANCE: tb.dut.gen_partitions[4].gen_buffered.u_part_buf -Fsm state_q "441128463" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm state_q "441128463" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -State IntegDigPadSt "855" -Fsm error_q "2410907799" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2410907799" -Transition CheckFailError->FsmStateError "6->7" -CHECKSUM: "2063559012 2582220255" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf -Fsm state_q "441128463" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm state_q "441128463" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -State IntegDigPadSt "855" -Fsm error_q "2410907799" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2410907799" -Transition CheckFailError->FsmStateError "6->7" -CHECKSUM: "2063559012 2582220255" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf -Fsm state_q "441128463" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm state_q "441128463" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -State IntegDigPadSt "855" -Fsm error_q "2410907799" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2410907799" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -Transition CheckFailError->FsmStateError "6->7" -CHECKSUM: "2063559012 2582220255" -INSTANCE: tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf -Fsm state_q "441128463" -Transition IdleSt->IntegDigClrSt "1357->2625" -Fsm state_q "441128463" -State InitDescrWaitSt "2472" -Fsm state_q "441128463" -State IntegDigFinSt "1765" -Fsm state_q "441128463" -State IntegDigPadSt "855" -Fsm state_q "441128463" -State IntegDigSt "1890" -Fsm state_q "441128463" -State IntegDigWaitSt "2290" -Fsm state_q "441128463" -State IntegScrSt "3418" -Fsm state_q "441128463" -State IntegScrWaitSt "2207" -Fsm state_q "441128463" -State InitDescrSt "3204" -Fsm error_q "2410907799" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2410907799" -Transition CheckFailError->FsmStateError "6->7" -CHECKSUM: "2940612991 27342893" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf -Fsm error_q "2210720134" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -Transition MacroEccCorrError->AccessError "2->5" -Fsm error_q "2210720134" -Transition AccessError->CheckFailError "5->6" -CHECKSUM: "2940612991 27342893" -INSTANCE: tb.dut.gen_partitions[1].gen_unbuffered.u_part_unbuf -Fsm error_q "2210720134" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -Transition MacroEccCorrError->AccessError "2->5" -Fsm error_q "2210720134" -Transition AccessError->CheckFailError "5->6" -CHECKSUM: "2940612991 27342893" -INSTANCE: tb.dut.gen_partitions[2].gen_unbuffered.u_part_unbuf -Fsm error_q "2210720134" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -Transition MacroEccCorrError->AccessError "2->5" -Fsm error_q "2210720134" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -Transition AccessError->CheckFailError "5->6" -CHECKSUM: "4205406832 4258846959" -INSTANCE: tb.dut.u_otp_ctrl_dai -Fsm error_q "1085514286" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "1085514286" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "1085514286" -Transition AccessError->MacroEccCorrError "5->2" -CHECKSUM: "761735614 2379312231" -INSTANCE: tb.dut.u_otp_ctrl_kdi -Fsm state_q "2979668442" -Transition DigWaitSt->FinishSt "913->760" -Fsm state_q "2979668442" -Transition DigWaitSt->DigLoadSt "913->183" diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_if.sv b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_if.sv deleted file mode 100644 index 106178b88066d..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_if.sv +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Implements functional coverage for OTP_CTRL - -interface otp_ctrl_cov_if - import otp_ctrl_reg_pkg::*; - ( - input pwrmgr_pkg::pwr_otp_rsp_t pwr_otp_o, - input otp_ctrl_pkg::lc_otp_program_req_t lc_otp_program_i, - input bit [3:0] lc_escalate_en_i, - input otp_ctrl_pkg::flash_otp_key_req_t flash_otp_key_i, - input otp_ctrl_pkg::sram_otp_key_req_t [NumSramKeyReqSlots-1:0] sram_otp_key_i, - input otp_ctrl_pkg::otbn_otp_key_req_t otbn_otp_key_i - ); - - import uvm_pkg::*; - import dv_utils_pkg::*; - `include "dv_fcov_macros.svh" - - covergroup lc_esc_en_condition_cg @(lc_escalate_en_i == lc_ctrl_pkg::On); - lc_esc_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - lc_esc_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - lc_esc_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - lc_esc_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - lc_esc_during_otbn_req: coverpoint otbn_otp_key_i.req; - lc_esc_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - lc_esc_during_lc_otp_prog_req: coverpoint lc_otp_program_i.req; - endgroup - - covergroup flash_data_req_condition_cg @(flash_otp_key_i.data_req); - flash_data_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - flash_data_req_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - flash_data_req_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - flash_data_req_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - flash_data_req_during_otbn_req: coverpoint otbn_otp_key_i.req; - flash_data_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - covergroup flash_addr_req_condition_cg @(flash_otp_key_i.addr_req); - flash_addr_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - flash_addr_req_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - flash_addr_req_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - flash_addr_req_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - flash_addr_req_during_otbn_req: coverpoint otbn_otp_key_i.req; - flash_addr_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - covergroup sram_0_req_condition_cg @(sram_otp_key_i[0].req); - sram_0_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - sram_0_req_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - sram_0_req_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - sram_0_req_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - sram_0_req_during_otbn_req: coverpoint otbn_otp_key_i.req; - sram_0_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - covergroup sram_1_req_condition_cg @(sram_otp_key_i[1].req); - sram_1_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - sram_1_req_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - sram_1_req_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - sram_1_req_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - sram_1_req_during_otbn_req: coverpoint otbn_otp_key_i.req; - sram_1_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - covergroup otbn_req_condition_cg @(otbn_otp_key_i.req); - otbn_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - otbn_req_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - otbn_req_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - otbn_req_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - otbn_req_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - otbn_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - covergroup lc_prog_req_condition_cg @(lc_otp_program_i.req); - lc_prog_req_during_lc_esc: coverpoint lc_escalate_en_i { - bins lc_esc_on = {lc_ctrl_pkg::On}; - bins lc_esc_off = {[0 : lc_ctrl_pkg::On-1], [lc_ctrl_pkg::On+1 : '1]}; - } - lc_prog_req_during_flash_addr_req: coverpoint flash_otp_key_i.addr_req; - lc_prog_req_during_flash_data_req: coverpoint flash_otp_key_i.data_req; - lc_prog_req_during_sram_0_req: coverpoint sram_otp_key_i[0].req; - lc_prog_req_during_sram_1_req: coverpoint sram_otp_key_i[1].req; - lc_prog_req_during_otbn_req: coverpoint otbn_otp_key_i.req; - lc_prog_req_during_otp_idle: coverpoint pwr_otp_o.otp_idle; - endgroup - - `DV_FCOV_INSTANTIATE_CG(lc_esc_en_condition_cg) - `DV_FCOV_INSTANTIATE_CG(flash_data_req_condition_cg) - `DV_FCOV_INSTANTIATE_CG(flash_addr_req_condition_cg) - `DV_FCOV_INSTANTIATE_CG(sram_0_req_condition_cg) - `DV_FCOV_INSTANTIATE_CG(sram_1_req_condition_cg) - `DV_FCOV_INSTANTIATE_CG(otbn_req_condition_cg) - `DV_FCOV_INSTANTIATE_CG(lc_prog_req_condition_cg) - -endinterface diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el deleted file mode 100644 index 99dfe4f72ff2c..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el +++ /dev/null @@ -1,6133 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Generated UNR file from Synopsys UNR tool with security modules being black-boxed. -//================================================== -// This file contains the Excluded objects -// Generated By User: miguelosorio -// Format Version: 2 -// Date: Fri Aug 30 23:42:43 2024 -// ExclMode: default -//================================================== -CHECKSUM: "2868806991 3096942133" -INSTANCE: tb.dut.gen_alert_tx[4].u_prim_alert_sender -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 alert_ack_o "logic alert_ack_o" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 alert_ack_o "logic alert_ack_o" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 alert_state_o "logic alert_state_o" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 alert_state_o "logic alert_state_o" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf.gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[1].gen_unbuffered.u_part_unbuf.gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[2].gen_unbuffered.u_part_unbuf.gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[3].gen_unbuffered.u_part_unbuf.gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[4].gen_unbuffered.u_part_unbuf.gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[4].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[2].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[3].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[5].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[6].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[7].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[8].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[2].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[3].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[4].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[2].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[3].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[4].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[5].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[6].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[7].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[8].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[9].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[10].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[2].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[3].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[4].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[5].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[6].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[7].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[8].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[9].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[10].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[1].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[2].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[3].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[4].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[5].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[6].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[7].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[8].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[9].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "1436819047 249500095" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf.u_otp_ctrl_ecc_reg.gen_ecc_dec[10].u_prim_secded_inv_72_64_dec -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [0] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [1] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [2] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [3] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [4] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [5] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [6] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 syndrome_o [7] "logic syndrome_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [0] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 err_o [1] "logic err_o[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 err_o [1] "logic err_o[1:0]" -CHECKSUM: "3215070453 3446030929" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_reqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Block 19 "4019242409" "wptr_wrap_cnt_q <= (wptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -ANNOTATION: "VC_COV_UNR" -Block 28 "1113085816" "rptr_wrap_cnt_q <= (rptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -CHECKSUM: "3215070453 3446030929" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_sramreqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Block 19 "4019242409" "wptr_wrap_cnt_q <= (wptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -ANNOTATION: "VC_COV_UNR" -Block 28 "1113085816" "rptr_wrap_cnt_q <= (rptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -CHECKSUM: "3215070453 3446030929" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_rspfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Block 19 "4019242409" "wptr_wrap_cnt_q <= (wptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -ANNOTATION: "VC_COV_UNR" -Block 28 "1113085816" "rptr_wrap_cnt_q <= (rptr_wrap_cnt_q + {{(WrapPtrW - 1) {1'b0}}, 1'b1});" -CHECKSUM: "3171246264 1537087436" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic -ANNOTATION: "VC_COV_UNR" -Block 24 "3494210324" ";" -CHECKSUM: "3665351474 3190968676" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 22 "662519215" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 23 "617613755" "state_d = InitDescrWaitSt;" -ANNOTATION: "VC_COV_UNR" -Block 25 "2942482414" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 26 "3475289755" "state_d = InitSt;" -ANNOTATION: "VC_COV_UNR" -Block 68 "746922678" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 69 "369318088" "state_d = IntegScrWaitSt;" -ANNOTATION: "VC_COV_UNR" -Block 71 "1545788457" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 72 "2540127236" "state_d = IntegDigSt;" -ANNOTATION: "VC_COV_UNR" -Block 78 "4176855572" "state_d = IntegDigPadSt;" -ANNOTATION: "VC_COV_UNR" -Block 86 "1288945484" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 87 "984470440" "state_d = IntegDigFinSt;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3665351474 328877407" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 22 "662519215" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 23 "617613755" "state_d = InitDescrWaitSt;" -ANNOTATION: "VC_COV_UNR" -Block 25 "2942482414" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 26 "3475289755" "state_d = InitSt;" -ANNOTATION: "VC_COV_UNR" -Block 68 "746922678" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 69 "369318088" "state_d = IntegScrWaitSt;" -ANNOTATION: "VC_COV_UNR" -Block 71 "1545788457" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 72 "2540127236" "state_d = IntegDigSt;" -ANNOTATION: "VC_COV_UNR" -Block 77 "3141955456" "scrmbl_cmd_o = Digest;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3665351474 4034042967" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 78 "4176855572" "state_d = IntegDigPadSt;" -ANNOTATION: "VC_COV_UNR" -Block 86 "1288945484" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 87 "984470440" "state_d = IntegDigFinSt;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3665351474 2385925532" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 78 "4176855572" "state_d = IntegDigPadSt;" -ANNOTATION: "VC_COV_UNR" -Block 86 "1288945484" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 87 "984470440" "state_d = IntegDigFinSt;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3665351474 2380508828" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 78 "4176855572" "state_d = IntegDigPadSt;" -ANNOTATION: "VC_COV_UNR" -Block 86 "1288945484" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 87 "984470440" "state_d = IntegDigFinSt;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3665351474 3973220603" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf -ANNOTATION: "VC_COV_UNR" -Block 22 "662519215" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 25 "2942482414" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 68 "746922678" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 71 "1545788457" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 74 "736744825" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 86 "1288945484" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 89 "967932616" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 92 "3253244488" "scrmbl_mtx_req_o = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 105 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 106 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "3882079776 1965827338" -INSTANCE: tb.dut.u_otp_ctrl_scrmbl -ANNOTATION: "VC_COV_UNR" -Block 28 "3494210324" ";" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field3 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field4 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field5 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field6 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field7 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field8 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field2 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field3 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field4 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field5 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field0 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field1 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field2 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "4255502330 223073768" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field3 -ANNOTATION: "VC_COV_UNR" -Block 4 "1824183207" "q <= wr_data;" -CHECKSUM: "3162909804 919553166" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Block 17 "814628507" "error_d = MacroEccCorrError;" -ANNOTATION: "VC_COV_UNR" -Block 32 "3415759745" "error_d = MacroEccCorrError;" -CHECKSUM: "3162909804 2229302740" -INSTANCE: tb.dut.gen_partitions[4].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Block 44 "1192338528" "state_d = ErrorSt;" -ANNOTATION: "VC_COV_UNR" -Block 45 "2515805717" "error_d = CheckFailError;" -CHECKSUM: "662936270 450589591" -INSTANCE: tb.dut.u_tlul_adapter_sram -ANNOTATION: "VC_COV_UNR" -Block 22 "3478134645" "d_valid = 1'b1;" -CHECKSUM: "3436844037 1915699783" -INSTANCE: tb.dut -ANNOTATION: "VC_COV_UNR" -Block 15 "1636116421" "tlul_oob_err_d = 1'b1;" -ANNOTATION: "VC_COV_UNR" -Block 32 "3434355351" "part_access_pre[k] = {2 {MuBi8True}};" -CHECKSUM: "1158524476 3747170265" -INSTANCE: tb.dut.u_otp_ctrl_kdi -ANNOTATION: "VC_COV_UNR" -Block 88 "3038555774" "state_d = DigLoadSt;" -CHECKSUM: "1611327958 113940473" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top -ANNOTATION: "VC_COV_UNR" -Condition 20 "3585319611" "(reg_we && ((!addrmiss))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 22 "1026062099" "(addrmiss | wr_err | intg_err) 1 -1" (4 "100") -CHECKSUM: "3171246264 2882888745" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic -ANNOTATION: "VC_COV_UNR" -Condition 1 "2104830463" "(cmd_i == Init) 1 -1" (1 "0") -CHECKSUM: "3162909804 3458814989" -INSTANCE: tb.dut.gen_partitions[1].gen_unbuffered.u_part_unbuf -Fsm state_q "4141872371" -ANNOTATION: "VC_COV_UNR" -Transition ResetSt->IdleSt "694->745" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->CheckFailError "5->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition MacroEccCorrError->AccessError "2->5" -CHECKSUM: "3162909804 3458814989" -INSTANCE: tb.dut.gen_partitions[2].gen_unbuffered.u_part_unbuf -Fsm state_q "4141872371" -ANNOTATION: "VC_COV_UNR" -Transition ResetSt->IdleSt "694->745" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->CheckFailError "5->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition MacroEccCorrError->AccessError "2->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition MacroEccCorrError->CheckFailError "2->6" -CHECKSUM: "3162909804 3458814989" -INSTANCE: tb.dut.gen_partitions[3].gen_unbuffered.u_part_unbuf -Fsm state_q "4141872371" -ANNOTATION: "VC_COV_UNR" -Transition ResetSt->IdleSt "694->745" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->CheckFailError "5->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition MacroEccCorrError->AccessError "2->5" -CHECKSUM: "3162909804 3458814989" -INSTANCE: tb.dut.gen_partitions[4].gen_unbuffered.u_part_unbuf -Fsm state_q "4141872371" -ANNOTATION: "VC_COV_UNR" -Transition ResetSt->IdleSt "694->745" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -State CheckFailError "6" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition MacroEccCorrError->AccessError "2->5" -CHECKSUM: "3436844037 2267239089" -INSTANCE: tb.dut -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_ast_pwr_seq_o.pwr_seq [0] "logic otp_ast_pwr_seq_o.pwr_seq[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_ast_pwr_seq_o.pwr_seq [0] "logic otp_ast_pwr_seq_o.pwr_seq[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_ast_pwr_seq_o.pwr_seq [1] "logic otp_ast_pwr_seq_o.pwr_seq[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_ast_pwr_seq_o.pwr_seq [1] "logic otp_ast_pwr_seq_o.pwr_seq[1:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [0] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [0] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [1] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [1] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [2] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [2] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [3] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [3] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [4] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [4] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [5] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [5] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [6] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [6] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [7] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [7] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [8] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [8] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [9] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [9] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [10] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [10] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [11] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [11] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [12] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [12] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [13] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [13] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [14] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [14] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [15] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [15] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [16] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [16] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [17] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [17] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [18] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [18] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [19] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [19] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [20] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [20] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [21] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [21] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [22] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [22] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [23] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [23] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [24] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [24] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [25] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [25] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [26] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [26] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [27] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [27] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [28] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [28] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [29] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [29] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [30] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [30] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 lc_otp_vendor_test_o.status [31] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 lc_otp_vendor_test_o.status [31] "logic lc_otp_vendor_test_o.status[31:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed_valid "logic otp_keymgr_key_o.owner_seed_valid" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed_valid "logic otp_keymgr_key_o.owner_seed_valid" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [0] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [0] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [1] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [1] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [2] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [2] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [3] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [3] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [4] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [4] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [5] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [5] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [6] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [6] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [7] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [7] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [8] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [8] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [9] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [9] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [10] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [10] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [11] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [11] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [12] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [12] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [13] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [13] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [14] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [14] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [15] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [15] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [16] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [16] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [17] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [17] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [18] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [18] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [19] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [19] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [20] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [20] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [21] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [21] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [22] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [22] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [23] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [23] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [24] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [24] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [25] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [25] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [26] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [26] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [27] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [27] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [28] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [28] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [29] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [29] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [30] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [30] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [31] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [31] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [32] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [32] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [33] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [33] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [34] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [34] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [35] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [35] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [36] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [36] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [37] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [37] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [38] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [38] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [39] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [39] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [40] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [40] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [41] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [41] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [42] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [42] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [43] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [43] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [44] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [44] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [45] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [45] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [46] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [46] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [47] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [47] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [48] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [48] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [49] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [49] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [50] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [50] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [51] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [51] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [52] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [52] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [53] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [53] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [54] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [54] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [55] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [55] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [56] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [56] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [57] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [57] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [58] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [58] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [59] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [59] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [60] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [60] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [61] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [61] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [62] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [62] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [63] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [63] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [64] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [64] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [65] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [65] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [66] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [66] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [67] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [67] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [68] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [68] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [69] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [69] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [70] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [70] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [71] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [71] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [72] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [72] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [73] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [73] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [74] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [74] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [75] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [75] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [76] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [76] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [77] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [77] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [78] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [78] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [79] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [79] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [80] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [80] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [81] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [81] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [82] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [82] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [83] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [83] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [84] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [84] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [85] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [85] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [86] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [86] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [87] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [87] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [88] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [88] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [89] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [89] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [90] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [90] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [91] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [91] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [92] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [92] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [93] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [93] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [94] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [94] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [95] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [95] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [96] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [96] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [97] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [97] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [98] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [98] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [99] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [99] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [100] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [100] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [101] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [101] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [102] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [102] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [103] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [103] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [104] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [104] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [105] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [105] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [106] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [106] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [107] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [107] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [108] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [108] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [109] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [109] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [110] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [110] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [111] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [111] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [112] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [112] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [113] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [113] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [114] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [114] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [115] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [115] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [116] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [116] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [117] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [117] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [118] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [118] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [119] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [119] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [120] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [120] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [121] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [121] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [122] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [122] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [123] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [123] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [124] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [124] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [125] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [125] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [126] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [126] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [127] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [127] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [128] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [128] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [129] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [129] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [130] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [130] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [131] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [131] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [132] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [132] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [133] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [133] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [134] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [134] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [135] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [135] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [136] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [136] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [137] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [137] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [138] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [138] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [139] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [139] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [140] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [140] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [141] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [141] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [142] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [142] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [143] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [143] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [144] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [144] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [145] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [145] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [146] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [146] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [147] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [147] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [148] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [148] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [149] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [149] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [150] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [150] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [151] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [151] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [152] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [152] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [153] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [153] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [154] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [154] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [155] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [155] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [156] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [156] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [157] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [157] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [158] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [158] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [159] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [159] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [160] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [160] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [161] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [161] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [162] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [162] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [163] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [163] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [164] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [164] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [165] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [165] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [166] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [166] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [167] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [167] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [168] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [168] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [169] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [169] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [170] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [170] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [171] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [171] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [172] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [172] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [173] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [173] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [174] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [174] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [175] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [175] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [176] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [176] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [177] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [177] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [178] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [178] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [179] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [179] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [180] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [180] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [181] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [181] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [182] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [182] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [183] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [183] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [184] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [184] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [185] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [185] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [186] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [186] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [187] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [187] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [188] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [188] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [189] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [189] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [190] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [190] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [191] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [191] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [192] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [192] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [193] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [193] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [194] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [194] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [195] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [195] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [196] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [196] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [197] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [197] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [198] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [198] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [199] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [199] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [200] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [200] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [201] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [201] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [202] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [202] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [203] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [203] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [204] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [204] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [205] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [205] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [206] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [206] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [207] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [207] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [208] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [208] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [209] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [209] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [210] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [210] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [211] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [211] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [212] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [212] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [213] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [213] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [214] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [214] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [215] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [215] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [216] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [216] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [217] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [217] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [218] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [218] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [219] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [219] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [220] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [220] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [221] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [221] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [222] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [222] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [223] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [223] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [224] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [224] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [225] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [225] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [226] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [226] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [227] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [227] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [228] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [228] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [229] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [229] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [230] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [230] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [231] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [231] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [232] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [232] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [233] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [233] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [234] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [234] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [235] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [235] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [236] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [236] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [237] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [237] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [238] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [238] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [239] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [239] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [240] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [240] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [241] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [241] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [242] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [242] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [243] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [243] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [244] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [244] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [245] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [245] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [246] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [246] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [247] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [247] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [248] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [248] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [249] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [249] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [250] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [250] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [251] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [251] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [252] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [252] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [253] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [253] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [254] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [254] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.owner_seed [255] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.owner_seed [255] "logic otp_keymgr_key_o.owner_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed_valid "logic otp_keymgr_key_o.creator_seed_valid" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed_valid "logic otp_keymgr_key_o.creator_seed_valid" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [0] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [0] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [1] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [1] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [2] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [2] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [3] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [3] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [4] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [4] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [5] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [5] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [6] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [6] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [7] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [7] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [8] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [8] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [9] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [9] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [10] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [10] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [11] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [11] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [12] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [12] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [13] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [13] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [14] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [14] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [15] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [15] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [16] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [16] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [17] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [17] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [18] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [18] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [19] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [19] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [20] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [20] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [21] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [21] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [22] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [22] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [23] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [23] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [24] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [24] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [25] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [25] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [26] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [26] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [27] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [27] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [28] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [28] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [29] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [29] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [30] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [30] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [31] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [31] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [32] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [32] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [33] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [33] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [34] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [34] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [35] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [35] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [36] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [36] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [37] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [37] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [38] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [38] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [39] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [39] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [40] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [40] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [41] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [41] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [42] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [42] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [43] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [43] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [44] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [44] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [45] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [45] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [46] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [46] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [47] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [47] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [48] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [48] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [49] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [49] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [50] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [50] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [51] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [51] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [52] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [52] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [53] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [53] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [54] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [54] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [55] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [55] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [56] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [56] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [57] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [57] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [58] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [58] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [59] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [59] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [60] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [60] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [61] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [61] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [62] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [62] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [63] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [63] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [64] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [64] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [65] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [65] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [66] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [66] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [67] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [67] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [68] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [68] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [69] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [69] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [70] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [70] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [71] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [71] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [72] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [72] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [73] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [73] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [74] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [74] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [75] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [75] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [76] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [76] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [77] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [77] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [78] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [78] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [79] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [79] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [80] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [80] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [81] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [81] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [82] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [82] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [83] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [83] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [84] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [84] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [85] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [85] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [86] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [86] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [87] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [87] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [88] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [88] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [89] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [89] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [90] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [90] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [91] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [91] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [92] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [92] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [93] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [93] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [94] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [94] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [95] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [95] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [96] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [96] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [97] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [97] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [98] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [98] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [99] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [99] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [100] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [100] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [101] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [101] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [102] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [102] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [103] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [103] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [104] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [104] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [105] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [105] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [106] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [106] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [107] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [107] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [108] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [108] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [109] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [109] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [110] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [110] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [111] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [111] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [112] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [112] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [113] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [113] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [114] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [114] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [115] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [115] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [116] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [116] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [117] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [117] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [118] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [118] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [119] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [119] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [120] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [120] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [121] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [121] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [122] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [122] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [123] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [123] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [124] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [124] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [125] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [125] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [126] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [126] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [127] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [127] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [128] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [128] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [129] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [129] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [130] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [130] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [131] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [131] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [132] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [132] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [133] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [133] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [134] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [134] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [135] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [135] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [136] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [136] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [137] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [137] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [138] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [138] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [139] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [139] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [140] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [140] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [141] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [141] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [142] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [142] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [143] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [143] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [144] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [144] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [145] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [145] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [146] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [146] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [147] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [147] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [148] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [148] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [149] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [149] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [150] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [150] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [151] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [151] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [152] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [152] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [153] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [153] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [154] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [154] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [155] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [155] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [156] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [156] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [157] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [157] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [158] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [158] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [159] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [159] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [160] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [160] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [161] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [161] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [162] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [162] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [163] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [163] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [164] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [164] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [165] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [165] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [166] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [166] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [167] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [167] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [168] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [168] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [169] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [169] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [170] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [170] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [171] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [171] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [172] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [172] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [173] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [173] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [174] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [174] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [175] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [175] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [176] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [176] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [177] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [177] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [178] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [178] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [179] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [179] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [180] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [180] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [181] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [181] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [182] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [182] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [183] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [183] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [184] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [184] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [185] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [185] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [186] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [186] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [187] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [187] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [188] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [188] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [189] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [189] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [190] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [190] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [191] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [191] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [192] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [192] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [193] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [193] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [194] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [194] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [195] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [195] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [196] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [196] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [197] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [197] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [198] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [198] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [199] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [199] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [200] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [200] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [201] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [201] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [202] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [202] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [203] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [203] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [204] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [204] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [205] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [205] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [206] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [206] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [207] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [207] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [208] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [208] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [209] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [209] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [210] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [210] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [211] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [211] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [212] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [212] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [213] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [213] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [214] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [214] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [215] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [215] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [216] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [216] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [217] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [217] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [218] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [218] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [219] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [219] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [220] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [220] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [221] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [221] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [222] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [222] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [223] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [223] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [224] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [224] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [225] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [225] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [226] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [226] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [227] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [227] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [228] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [228] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [229] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [229] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [230] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [230] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [231] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [231] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [232] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [232] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [233] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [233] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [234] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [234] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [235] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [235] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [236] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [236] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [237] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [237] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [238] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [238] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [239] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [239] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [240] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [240] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [241] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [241] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [242] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [242] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [243] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [243] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [244] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [244] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [245] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [245] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [246] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [246] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [247] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [247] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [248] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [248] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [249] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [249] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [250] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [250] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [251] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [251] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [252] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [252] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [253] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [253] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [254] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [254] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 otp_keymgr_key_o.creator_seed [255] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 otp_keymgr_key_o.creator_seed [255] "logic otp_keymgr_key_o.creator_seed[255:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [0] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [0] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [1] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [1] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [2] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [2] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [3] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [3] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [4] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [4] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [5] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [5] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [6] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [6] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 0to1 cio_test_o [7] "logic cio_test_o[7:0]" -ANNOTATION: "VC_COV_UNR" -Toggle 1to0 cio_test_o [7] "logic cio_test_o[7:0]" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrSt "3204" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrWaitSt "2472" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigPadSt "855" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrSt "3418" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrWaitSt "2207" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrSt "3204" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrWaitSt "2472" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrSt "3418" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrWaitSt "2207" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigSt->IntegDigFinSt "1890->1765" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigPadSt "855" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigPadSt "855" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigPadSt "855" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition CnstyReadWaitSt->CnstyReadSt "2684->107" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition InitWaitSt->InitSt "945->3367" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IdleSt "2625->1357" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IntegDigClrSt->IntegDigSt "2625->1890" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3665351474 2582220255" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrSt "3204" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State InitDescrWaitSt "2472" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigFinSt "1765" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigPadSt "855" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigSt "1890" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegDigWaitSt "2290" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrSt "3418" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -State IntegScrWaitSt "2207" -Fsm state_q "441128463" -ANNOTATION: "VC_COV_UNR" -Transition IdleSt->IntegDigClrSt "1357->2625" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->MacroEccCorrError "6->2" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -Fsm error_q "2410907799" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "3162909804 3458814989" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf -Fsm state_q "4141872371" -ANNOTATION: "VC_COV_UNR" -Transition ResetSt->IdleSt "694->745" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -State MacroEccCorrError "2" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->AccessError "6->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition CheckFailError->FsmStateError "6->7" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "2210720134" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->CheckFailError "7->6" -CHECKSUM: "903559179 4258846959" -INSTANCE: tb.dut.u_otp_ctrl_dai -Fsm error_q "1085514286" -ANNOTATION: "VC_COV_UNR" -Transition AccessError->MacroEccCorrError "5->2" -Fsm error_q "1085514286" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->AccessError "7->5" -Fsm error_q "1085514286" -ANNOTATION: "VC_COV_UNR" -Transition FsmStateError->MacroEccCorrError "7->2" -CHECKSUM: "1158524476 2379312231" -INSTANCE: tb.dut.u_otp_ctrl_kdi -Fsm state_q "2979668442" -ANNOTATION: "VC_COV_UNR" -Transition DigWaitSt->DigLoadSt "913->183" -CHECKSUM: "165375753 2072593586" -INSTANCE: tb.dut.u_otp_ctrl_lfsr_timer -ANNOTATION: "VC_COV_UNR" -Condition 15 "1557524712" "(edn_req_o & edn_ack_i) 1 -1" (1 "01") -CHECKSUM: "3436844037 2360113432" -INSTANCE: tb.dut -ANNOTATION: "VC_COV_UNR" -Condition 1 "83486244" "(tlul_part_sel_oh != '0) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 2 "1218027842" "(((|part_tlul_gnt)) | tlul_oob_err_q) 1 -1" (2 "01") -ANNOTATION: "VC_COV_UNR" -Condition 3 "3291433605" "(((|part_tlul_rvalid)) | tlul_oob_err_q) 1 -1" (2 "01") -ANNOTATION: "VC_COV_UNR" -Condition 4 "3779635843" "(fatal_bus_integ_error_q | ((|intg_error))) 1 -1" (3 "10") -ANNOTATION: "VC_COV_UNR" -Condition 5 "1876397257" "(part_error[k] == MacroError) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 10 "2334459673" "(otp_rvalid & otp_fifo_valid) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 13 "1319238213" "(reg2hw.direct_access_cmd.digest.qe | reg2hw.direct_access_cmd.wr.qe | reg2hw.direct_access_cmd.rd.qe) 1 -1" (2 "001") -ANNOTATION: "VC_COV_UNR" -Condition 13 "1319238213" "(reg2hw.direct_access_cmd.digest.qe | reg2hw.direct_access_cmd.wr.qe | reg2hw.direct_access_cmd.rd.qe) 1 -1" (3 "010") -ANNOTATION: "VC_COV_UNR" -Condition 13 "1319238213" "(reg2hw.direct_access_cmd.digest.qe | reg2hw.direct_access_cmd.wr.qe | reg2hw.direct_access_cmd.rd.qe) 1 -1" (4 "100") -ANNOTATION: "vcs_gen_start:k=10:vcs_gen_end:VC_COV_UNR" -Condition 42 "1479216946" "(({tlul_addr, 2'b0} >= 11'b11110101000) & ({1'b0, {tlul_addr, 2'b0}} < gen_part_sel[10].PartEnd)) 1 -1" (2 "10") -CHECKSUM: "1746381268 1271541636" -INSTANCE: tb.dut.u_reg_core.u_socket -ANNOTATION: "VC_COV_UNR" -Condition 3 "118253128" "(tl_t_o.a_valid & tl_t_i.a_ready) 1 -1" (1 "01") -CHECKSUM: "74367784 3785313510" -INSTANCE: tb.dut.u_reg_core.u_reg_if -ANNOTATION: "VC_COV_UNR" -Condition 18 "3340270436" "(addr_align_err | malformed_meta_err | tl_err | instr_error | intg_error) 1 -1" (5 "01000") -CHECKSUM: "74367784 3785313510" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_reg_if -ANNOTATION: "VC_COV_UNR" -Condition 18 "3340270436" "(addr_align_err | malformed_meta_err | tl_err | instr_error | intg_error) 1 -1" (5 "01000") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field3 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field4 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field5 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field6 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field7 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field8 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field2 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field4 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field5 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field2 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3274445021" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field3 -ANNOTATION: "VC_COV_UNR" -Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3858770513" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field3 -ANNOTATION: "VC_COV_UNR" -Condition 1 "1301967206" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3858770513" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field1 -ANNOTATION: "VC_COV_UNR" -Condition 1 "1301967206" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "4255502330 3201188367" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field0 -ANNOTATION: "VC_COV_UNR" -Condition 1 "1807203824" "(wr_en ? wr_data : qs) 1 -1" (2 "1") -CHECKSUM: "2099741489 1445279304" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field0.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -CHECKSUM: "2099741489 1445279304" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field1.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -CHECKSUM: "2099741489 3636044484" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field2.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -ANNOTATION: "VC_COV_UNR" -Condition 2 "2306794614" "((de ? d : q) & (we ? ((~wd)) : '1)) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 2 "2306794614" "((de ? d : q) & (we ? ((~wd)) : '1)) 1 -1" (3 "11") -ANNOTATION: "VC_COV_UNR" -Condition 3 "2289961458" "(de ? d : q) 1 -1" (2 "1") -CHECKSUM: "2099741489 1283100255" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field6.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -CHECKSUM: "2099741489 1077956591" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field0.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -CHECKSUM: "2099741489 4164822555" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field1.wr_en_data_arb -ANNOTATION: "VC_COV_UNR" -Condition 1 "505266581" "(we | de) 1 -1" (2 "01") -CHECKSUM: "662936270 2081652359" -INSTANCE: tb.dut.u_tlul_adapter_sram -ANNOTATION: "VC_COV_UNR" -Condition 2 "3455933711" "(reqfifo_rdata.op == OpRead) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 8 "3066913128" "(intg_error | rsp_fifo_error | sramreqfifo_error | reqfifo_error | intg_error_q) 1 -1" (2 "00001") -ANNOTATION: "VC_COV_UNR" -Condition 17 "3469950311" "(wr_attr_error | wr_vld_error | rd_vld_error | instr_error | tlul_error | intg_error) 1 -1" (7 "100000") -ANNOTATION: "VC_COV_UNR" -Condition 20 "709191362" "(req_o & gnt_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 21 "3623514242" "(d_valid & reqfifo_rvalid & rspfifo_rvalid & (reqfifo_rdata.op == OpRead)) 1 -1" (1 "0111") -ANNOTATION: "VC_COV_UNR" -Condition 21 "3623514242" "(d_valid & reqfifo_rvalid & rspfifo_rvalid & (reqfifo_rdata.op == OpRead)) 1 -1" (2 "1011") -ANNOTATION: "VC_COV_UNR" -Condition 21 "3623514242" "(d_valid & reqfifo_rvalid & rspfifo_rvalid & (reqfifo_rdata.op == OpRead)) 1 -1" (4 "1110") -ANNOTATION: "VC_COV_UNR" -Condition 25 "2807788926" "((vld_rd_rsp && reqfifo_rdata.error) ? error_blanking_integ : (vld_rd_rsp ? rspfifo_rdata.data_intg : prim_secded_pkg::SecdedInv3932ZeroEcc)) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 26 "561780173" "(vld_rd_rsp && reqfifo_rdata.error) 1 -1" (3 "11") -ANNOTATION: "VC_COV_UNR" -Condition 34 "201396280" "(d_valid && d_error) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 35 "3680494467" "((gnt_i | missed_err_gnt_q) & reqfifo_wready & sramreqfifo_wready & sramreqaddrfifo_wready) 1 -1" (3 "1101") -ANNOTATION: "VC_COV_UNR" -Condition 37 "2164803938" "(tl_i_int.a_valid & reqfifo_wready & ((~error_internal))) 1 -1" (1 "011") -ANNOTATION: "VC_COV_UNR" -Condition 42 "2041272341" "(sram_ack & ((~we_o))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 43 "721931741" "(rvalid_i & reqfifo_rvalid) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:i=0:vcs_gen_end:VC_COV_UNR" -Condition 48 "3548937587" "(((|wmask_intg)) & ((|wdata_intg))) 1 -1" (1 "01") -CHECKSUM: "2974379282 2951929728" -INSTANCE: tb.dut.u_part_sel_idx -ANNOTATION: "vcs_gen_start:level=0,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 1 "2750612666" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[0].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[0].gen_level[0].C1]) 1 -1" (1 "00") -CHECKSUM: "2974379282 2951929728" -INSTANCE: tb.dut.u_otp_ctrl_dai.u_part_sel_idx -ANNOTATION: "vcs_gen_start:level=0,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 1 "2750612666" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[0].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[0].gen_level[0].C1]) 1 -1" (1 "00") -CHECKSUM: "2032872600 2493710885" -INSTANCE: tb.dut.u_edn_arb -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 10 "635964333" "(req_i[0] & gen_normal_case.prio_mask_q[0]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 11 "2124571033" "(req_i[0] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[1].gen_level[0].Pa] & ready_i) 1 -1" (1 "011") -CHECKSUM: "2032872600 3068670743" -INSTANCE: tb.dut.u_otp_arb -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 118 "3667925887" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 119 "2125455247" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 119 "2125455247" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 120 "2371949082" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C1]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 121 "4111290463" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 124 "2230658126" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel))) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 125 "1884579875" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 137 "1731868698" "(req_i[0] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[0].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 142 "1060032545" "(req_i[1] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 147 "1299459822" "(req_i[2] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 152 "358663893" "(req_i[3] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 157 "2252512415" "(req_i[4] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 162 "3730207908" "(req_i[5] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[5].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 167 "2886503019" "(req_i[6] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[6].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=7:vcs_gen_end:VC_COV_UNR" -Condition 172 "4095238736" "(req_i[7] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[7].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=8:vcs_gen_end:VC_COV_UNR" -Condition 177 "296455364" "(req_i[8] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[8].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=9:vcs_gen_end:VC_COV_UNR" -Condition 182 "1237279999" "(req_i[9] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[9].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 187 "565898016" "(req_i[10] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[10].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=11:vcs_gen_end:VC_COV_UNR" -Condition 192 "2218826282" "(req_i[11] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[11].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 197 "4217824807" "(req_i[12] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[12].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 201 "1343278836" "(req_i[13] & gen_normal_case.prio_mask_q[13]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 201 "1343278836" "(req_i[13] & gen_normal_case.prio_mask_q[13]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 202 "1587320621" "(req_i[13] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 202 "1587320621" "(req_i[13] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ready_i) 1 -1" (2 "101") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 202 "1587320621" "(req_i[13] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 202 "1587320621" "(req_i[13] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ready_i) 1 -1" (4 "111") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 204 "3359315662" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ((~ready_i)))) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 204 "3359315662" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 205 "87484194" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ((~ready_i))) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 205 "87484194" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ((~ready_i))) 1 -1" (3 "11") -CHECKSUM: "2032872600 835765284" -INSTANCE: tb.dut.u_scrmbl_mtx -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 10 "1993460578" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[1].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 10 "1993460578" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[1].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 11 "1567077924" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 12 "3158492049" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[1].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[1].gen_level[0].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 13 "96040801" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[1].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 14 "1193252123" "(gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[1].gen_level[0].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[1].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 15 "445016888" "(gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[1].gen_level[0].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[1].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 16 "1314162940" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[1].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 16 "1314162940" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[1].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 17 "2175331913" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[1].gen_level[0].Pa] & gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 18 "2134997267" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[1].gen_level[0].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[1].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 28 "2070917326" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 28 "2070917326" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 29 "3264610632" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 29 "3264610632" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 30 "1496330476" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C1]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 30 "1496330476" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[2].gen_level[0].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 31 "475390859" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 31 "475390859" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[2].gen_level[0].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 32 "3851361741" "(gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[2].gen_level[0].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[2].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 33 "834897871" "(gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[2].gen_level[0].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[2].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 34 "827710109" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 34 "827710109" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel))) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 34 "827710109" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 35 "1296065718" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] & gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 35 "1296065718" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] & gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 36 "2587069038" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[2].gen_level[0].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=2,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 45 "1389557192" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[2].gen_level[1].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[2].gen_level[1].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 64 "210767427" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 64 "210767427" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 65 "433071849" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 65 "433071849" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 66 "676485814" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C1]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 66 "676485814" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[0].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 67 "2859603461" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 67 "2859603461" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[0].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 68 "499725081" "(gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[0].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 69 "2136469291" "(gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[0].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[0].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 70 "3457930055" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 70 "3457930055" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel))) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 70 "3457930055" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 71 "1202012" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 71 "1202012" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 72 "3948011572" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 73 "2058222911" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 73 "2058222911" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 74 "3215638766" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 74 "3215638766" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 75 "3769836816" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C1]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 75 "3769836816" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[1].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 76 "2034837615" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 76 "2034837615" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 77 "2239186227" "(gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[1].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 78 "2004432906" "(gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[1].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 79 "1357880086" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 79 "1357880086" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel))) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 79 "1357880086" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 80 "3927989974" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 80 "3927989974" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 81 "598777746" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 81 "598777746" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 82 "3219580251" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[2].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 82 "3219580251" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[2].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 83 "26276459" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 84 "1842145640" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[2].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[2].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 85 "147158886" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[2].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 86 "2038251222" "(gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[2].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[2].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 87 "1520563742" "(gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[2].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[2].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 88 "2599996672" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 88 "2599996672" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 89 "193340754" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] & gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 90 "2932823018" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 90 "2932823018" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].C0]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 109 "535495451" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[5].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 109 "535495451" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[5].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 110 "3231051018" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 111 "2023010" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[5].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[5].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 112 "2223050582" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[5].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 113 "1661998521" "(gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[5].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[5].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 114 "328876404" "(gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[5].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[5].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 115 "1323463256" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[5].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 115 "1323463256" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[5].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 116 "2448561063" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[5].Pa] & gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 117 "3273483488" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[5].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[5].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 118 "3667925887" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1])) 1 -1" (1 "00") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 118 "3667925887" "(((~gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) | (((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1])) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 119 "2125455247" "(((~gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0])) & gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 120 "2371949082" "(gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C0] | gen_normal_case.req_tree[gen_normal_case.gen_tree[3].gen_level[6].C1]) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 121 "4111290463" "(gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C1] | gen_normal_case.prio_tree[gen_normal_case.gen_tree[3].gen_level[6].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 122 "2669309532" "(gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel ? gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[6].C1] : gen_normal_case.idx_tree[gen_normal_case.gen_tree[3].gen_level[6].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 123 "1044549472" "(gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel ? gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[6].C1] : gen_normal_case.data_tree[gen_normal_case.gen_tree[3].gen_level[6].C0]) 1 -1" (1 "0") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 124 "2230658126" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel))) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 124 "2230658126" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & ((~gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 125 "1884579875" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 126 "1315088536" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] | gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].C0]) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 136 "2430171309" "(req_i[0] & gen_normal_case.prio_mask_q[0]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 136 "2430171309" "(req_i[0] & gen_normal_case.prio_mask_q[0]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 136 "2430171309" "(req_i[0] & gen_normal_case.prio_mask_q[0]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 137 "1731868698" "(req_i[0] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[0].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 139 "4029129651" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[0].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[0].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 140 "2870412309" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[0].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 141 "2424159075" "(req_i[1] & gen_normal_case.prio_mask_q[1]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 141 "2424159075" "(req_i[1] & gen_normal_case.prio_mask_q[1]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 141 "2424159075" "(req_i[1] & gen_normal_case.prio_mask_q[1]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 142 "1060032545" "(req_i[1] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 144 "2044991706" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 144 "2044991706" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] & ((~ready_i)))) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 145 "3094700199" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[1].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 146 "2442198833" "(req_i[2] & gen_normal_case.prio_mask_q[2]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 146 "2442198833" "(req_i[2] & gen_normal_case.prio_mask_q[2]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 146 "2442198833" "(req_i[2] & gen_normal_case.prio_mask_q[2]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 147 "1299459822" "(req_i[2] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 149 "303405805" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 149 "303405805" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] & ((~ready_i)))) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 150 "3088640414" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[2].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 151 "2436119807" "(req_i[3] & gen_normal_case.prio_mask_q[3]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 151 "2436119807" "(req_i[3] & gen_normal_case.prio_mask_q[3]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 151 "2436119807" "(req_i[3] & gen_normal_case.prio_mask_q[3]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 152 "358663893" "(req_i[3] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 154 "2614501764" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 154 "2614501764" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] & ((~ready_i)))) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 155 "2876935468" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[3].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 156 "1150101804" "(req_i[4] & gen_normal_case.prio_mask_q[4]) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 156 "1150101804" "(req_i[4] & gen_normal_case.prio_mask_q[4]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 156 "1150101804" "(req_i[4] & gen_normal_case.prio_mask_q[4]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 157 "2252512415" "(req_i[4] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 159 "2077403342" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 159 "2077403342" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] & ((~ready_i)))) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 160 "362208751" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[4].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 164 "4061205415" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[5].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[5].Pa] & ((~ready_i)))) 1 -1" (3 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 186 "1702269588" "(req_i[10] & gen_normal_case.prio_mask_q[10]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 186 "1702269588" "(req_i[10] & gen_normal_case.prio_mask_q[10]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 187 "565898016" "(req_i[10] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[10].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 189 "2771416427" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[10].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[10].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=10:vcs_gen_end:VC_COV_UNR" -Condition 190 "2876058957" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[10].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 196 "3119114945" "(req_i[12] & gen_normal_case.prio_mask_q[12]) 1 -1" (2 "10") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 196 "3119114945" "(req_i[12] & gen_normal_case.prio_mask_q[12]) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 197 "4217824807" "(req_i[12] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[12].Pa] & ready_i) 1 -1" (3 "110") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 199 "2102103111" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[12].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[12].Pa] & ((~ready_i)))) 1 -1" (2 "01") -ANNOTATION: "vcs_gen_start:level=4,offset=12:vcs_gen_end:VC_COV_UNR" -Condition 200 "3779810229" "(gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[12].Pa] & ((~ready_i))) 1 -1" (3 "11") -ANNOTATION: "vcs_gen_start:level=4,offset=13:vcs_gen_end:VC_COV_UNR" -Condition 204 "3359315662" "(gen_normal_case.mask_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] | (gen_normal_case.sel_tree[gen_normal_case.gen_tree[4].gen_level[13].Pa] & ((~ready_i)))) 1 -1" (1 "00") -CHECKSUM: "2032872600 3109464092" -INSTANCE: tb.dut.u_otp_ctrl_kdi.u_req_arb -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Condition 65 "2951635521" "(req_i[0] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[0].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Condition 70 "4160391802" "(req_i[1] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[1].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Condition 75 "2241885365" "(req_i[2] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[2].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=3:vcs_gen_end:VC_COV_UNR" -Condition 80 "3719601294" "(req_i[3] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[3].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=4:vcs_gen_end:VC_COV_UNR" -Condition 85 "1318504132" "(req_i[4] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[4].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Condition 90 "377630463" "(req_i[5] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[5].Pa] & ready_i) 1 -1" (1 "011") -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Condition 95 "1691930672" "(req_i[6] & gen_normal_case.sel_tree[gen_normal_case.gen_tree[3].gen_level[6].Pa] & ready_i) 1 -1" (1 "011") -CHECKSUM: "3655552781 2309055648" -INSTANCE: tb.dut.u_prim_edn_req.u_prim_packer_fifo -ANNOTATION: "VC_COV_UNR" -Condition 12 "2853235687" "((depth_q == FullDepth) && ((!clr_q))) 1 -1" (2 "10") -CHECKSUM: "4224194069 639524789" -INSTANCE: tb.dut.u_tlul_lc_gate -ANNOTATION: "VC_COV_UNR" -Condition 1 "1380914983" "(a_ack && ((!d_ack))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 2 "2824798557" "(d_ack && ((!a_ack))) 1 -1" (2 "10") -CHECKSUM: "903559179 1044941866" -INSTANCE: tb.dut.u_otp_ctrl_dai -ANNOTATION: "VC_COV_UNR" -Condition 6 "3686409107" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 8 "4163455672" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 9 "1539831361" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "vcs_gen_start:k=10:vcs_gen_end:VC_COV_UNR" -Condition 33 "138415549" "((dai_addr_i >= 11'b11110101000) & ({1'b0, dai_addr_i} < gen_part_sel[10].PartEndInt[otp_ctrl_reg_pkg::OtpByteAddrWidth:0])) 1 -1" (2 "10") -CHECKSUM: "1158524476 2909360515" -INSTANCE: tb.dut.u_otp_ctrl_kdi -ANNOTATION: "VC_COV_UNR" -Condition 2 "1539831361" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -CHECKSUM: "3162909804 4223786199" -INSTANCE: tb.dut.gen_partitions[3].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Condition 14 "2502713177" "(({tlul_addr_q, 2'b0} >= 11'b10001111000) && ({1'b0, tlul_addr_q, 2'b0} < PartEnd)) 1 -1" (2 "10") -CHECKSUM: "3162909804 475089886" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Condition 1 "1099175909" "(otp_err != NoError) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 2 "2883220586" "(otp_err != NoError) 1 -1" (2 "1") -CHECKSUM: "3162909804 1722272287" -INSTANCE: tb.dut.gen_partitions[1].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Condition 14 "478960819" "(({tlul_addr_q, 2'b0} >= 11'b00001000000) && ({1'b0, tlul_addr_q, 2'b0} < PartEnd)) 1 -1" (2 "10") -CHECKSUM: "3162909804 1775057944" -INSTANCE: tb.dut.gen_partitions[2].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Condition 14 "673734063" "(({tlul_addr_q, 2'b0} >= 11'b00110110000) && ({1'b0, tlul_addr_q, 2'b0} < PartEnd)) 1 -1" (2 "10") -CHECKSUM: "3162909804 4078376581" -INSTANCE: tb.dut.gen_partitions[4].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Condition 4 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 4 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 14 "677249997" "(({tlul_addr_q, 2'b0} >= 11'b11001010000) && ({1'b0, tlul_addr_q, 2'b0} < PartEnd)) 1 -1" (2 "10") -CHECKSUM: "3665351474 720525075" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (3 "11") -ANNOTATION: "VC_COV_UNR" -Condition 10 "4291765346" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -CHECKSUM: "3665351474 384791011" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 9 "1580211052" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -CHECKSUM: "3665351474 599055118" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (3 "11") -ANNOTATION: "VC_COV_UNR" -Condition 10 "4291765346" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -CHECKSUM: "3665351474 698462587" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 9 "1580211052" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -CHECKSUM: "3665351474 2302263073" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 18 "624370688" "((base_sel == DigOffset) ? DigestOffset : 11'b11110101000) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 19 "4038180897" "(base_sel == DigOffset) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 20 "705391888" "((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 21 "1499701630" "(data_sel == ScrmblData) 1 -1" (2 "1") -CHECKSUM: "3665351474 691864715" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Condition 3 "1999344180" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 9 "1580211052" "(scrmbl_mtx_gnt_i && scrmbl_ready_i) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 16 "3809681040" "(state_q != ErrorSt) 1 -1" (2 "1") -CHECKSUM: "7115036 2825631531" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_sramreqfifo -ANNOTATION: "VC_COV_UNR" -Condition 2 "1709501387" "(((~gen_normal_fifo.empty)) & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "101") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (1 "011") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -CHECKSUM: "7115036 2432857915" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_rspfifo -ANNOTATION: "VC_COV_UNR" -Condition 2 "1709501387" "(((~gen_normal_fifo.empty)) & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "101") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (1 "011") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -ANNOTATION: "VC_COV_UNR" -Condition 6 "4208363759" "(gen_normal_fifo.fifo_empty && wvalid_i) 1 -1" (1 "01") -CHECKSUM: "7115036 3923796707" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_reqfifo -ANNOTATION: "VC_COV_UNR" -Condition 2 "1709501387" "(((~gen_normal_fifo.empty)) & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "101") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (1 "011") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -CHECKSUM: "7115036 2279662283" -INSTANCE: tb.dut.u_otp_rsp_fifo -ANNOTATION: "VC_COV_UNR" -Condition 1 "2400173860" "(((~full_o)) & ((~gen_normal_fifo.under_rst))) 1 -1" (1 "01") -ANNOTATION: "VC_COV_UNR" -Condition 2 "1709501387" "(((~gen_normal_fifo.empty)) & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (2 "101") -ANNOTATION: "VC_COV_UNR" -Condition 3 "786039886" "(wvalid_i & wready_o & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (1 "011") -ANNOTATION: "VC_COV_UNR" -Condition 4 "1324655787" "(rvalid_o & rready_i & ((~gen_normal_fifo.under_rst))) 1 -1" (3 "110") -CHECKSUM: "3215070453 33318353" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_reqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Condition 1 "2532211833" "(incr_wptr_i & (wptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "2597027294" "(incr_rptr_i & (rptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 8 "1599734576" "((wptr_wrap_msb == rptr_wrap_msb) ? ((1'(wptr_o) - 1'(rptr_o))) : (((1'(Depth) - 1'(rptr_o)) + 1'(wptr_o)))) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 9 "446195871" "(wptr_wrap_msb == rptr_wrap_msb) 1 -1" (1 "0") -CHECKSUM: "3215070453 33318353" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_sramreqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Condition 1 "2532211833" "(incr_wptr_i & (wptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "2597027294" "(incr_rptr_i & (rptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 8 "1599734576" "((wptr_wrap_msb == rptr_wrap_msb) ? ((1'(wptr_o) - 1'(rptr_o))) : (((1'(Depth) - 1'(rptr_o)) + 1'(wptr_o)))) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 9 "446195871" "(wptr_wrap_msb == rptr_wrap_msb) 1 -1" (1 "0") -CHECKSUM: "3215070453 33318353" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_rspfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Condition 1 "2532211833" "(incr_wptr_i & (wptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 3 "2597027294" "(incr_rptr_i & (rptr_o == 1'((Depth - 1)))) 1 -1" (2 "10") -ANNOTATION: "VC_COV_UNR" -Condition 8 "1599734576" "((wptr_wrap_msb == rptr_wrap_msb) ? ((1'(wptr_o) - 1'(rptr_o))) : (((1'(Depth) - 1'(rptr_o)) + 1'(wptr_o)))) 1 -1" (1 "0") -ANNOTATION: "VC_COV_UNR" -Condition 9 "446195871" "(wptr_wrap_msb == rptr_wrap_msb) 1 -1" (1 "0") -CHECKSUM: "3215070453 563859410" -INSTANCE: tb.dut.u_otp_rsp_fifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Condition 5 "3619927060" "(wptr_wrap_cnt_q == (rptr_wrap_cnt_q ^ {1'b1, {(WrapPtrW - 1) {1'b0}}})) 1 -1" (2 "1") -ANNOTATION: "VC_COV_UNR" -Condition 7 "4040012966" "(full_o ? (2'(Depth)) : ((wptr_wrap_msb == rptr_wrap_msb) ? ((2'(wptr_o) - 2'(rptr_o))) : (((2'(Depth) - 2'(rptr_o)) + 2'(wptr_o))))) 1 -1" (2 "1") -CHECKSUM: "3171246264 3336016746" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic -ANNOTATION: "VC_COV_UNR" -Branch 3 "1554177250" "state_q" (1) "state_q ResetSt ,1,0,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1554177250" "state_q" (8) "state_q IdleSt ,-,-,1,default,-,-,-,-,-,-,-,-" -CHECKSUM: "3436844037 1401458059" -INSTANCE: tb.dut -ANNOTATION: "VC_COV_UNR" -Branch 4 "1264131593" "tlul_req" (1) "tlul_req 1,0" -CHECKSUM: "1746381268 3161287359" -INSTANCE: tb.dut.u_reg_core.u_socket -ANNOTATION: "VC_COV_UNR" -Branch 4 "3202860295" "(!rst_ni)" (2) "(!rst_ni) 0,1,0,-" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field3 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field4 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field5 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field6 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field7 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr3_field8 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field2 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field3 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field4 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr5_field5 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field0 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field1 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field2 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "4255502330 3554514034" -INSTANCE: tb.dut.u_otp.gen_generic.u_impl_generic.u_reg_top.u_csr7_field3 -ANNOTATION: "VC_COV_UNR" -Branch 0 "3759852512" "wr_en" (0) "wr_en 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "1017474648" "(!rst_ni)" (1) "(!rst_ni) 0,1" -CHECKSUM: "662936270 1924774061" -INSTANCE: tb.dut.u_tlul_adapter_sram -ANNOTATION: "VC_COV_UNR" -Branch 2 "1058271942" "(vld_rd_rsp && reqfifo_rdata.error)" (0) "(vld_rd_rsp && reqfifo_rdata.error) 1,-" -ANNOTATION: "VC_COV_UNR" -Branch 6 "744749108" "reqfifo_rvalid" (2) "reqfifo_rvalid 1,0,0" -CHECKSUM: "2032872600 3832429488" -INSTANCE: tb.dut.u_scrmbl_mtx -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 2 "1747167515" "gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=1,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 3 "1747167515" "gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[1].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 6 "3123337246" "gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=2,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 7 "3123337246" "gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[2].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 14 "840384514" "gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=0:vcs_gen_end:VC_COV_UNR" -Branch 15 "840384514" "gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[0].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Branch 16 "2813219087" "gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=1:vcs_gen_end:VC_COV_UNR" -Branch 17 "2813219087" "gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[1].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Branch 18 "2452890474" "gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=2:vcs_gen_end:VC_COV_UNR" -Branch 19 "2452890474" "gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[2].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Branch 24 "3811150440" "gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=5:vcs_gen_end:VC_COV_UNR" -Branch 25 "3811150440" "gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[5].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Branch 26 "3602118669" "gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel 0" -ANNOTATION: "vcs_gen_start:level=3,offset=6:vcs_gen_end:VC_COV_UNR" -Branch 27 "3602118669" "gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel" (1) "gen_normal_case.gen_tree[3].gen_level[6].gen_nodes.sel 0" -CHECKSUM: "4224194069 3219254590" -INSTANCE: tb.dut.u_tlul_lc_gate -ANNOTATION: "VC_COV_UNR" -Branch 2 "1850090820" "state_q" (8) "state_q StFlush ,-,-,-,0,0,-,-" -CHECKSUM: "3882079776 3692779052" -INSTANCE: tb.dut.u_otp_ctrl_scrmbl -ANNOTATION: "VC_COV_UNR" -Branch 5 "2137472258" "state_q" (8) "state_q IdleSt ,1,default,-,-,-,-,-" -CHECKSUM: "903559179 3978479804" -INSTANCE: tb.dut.u_otp_ctrl_dai -ANNOTATION: "VC_COV_UNR" -Branch 2 "2060689171" "state_q" (1) "state_q ResetSt ,1,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -CHECKSUM: "1158524476 2213598664" -INSTANCE: tb.dut.u_otp_ctrl_kdi -ANNOTATION: "VC_COV_UNR" -Branch 4 "853326673" "state_q" (20) "state_q DigWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,1,-,-,-" -CHECKSUM: "3162909804 3977884699" -INSTANCE: tb.dut.gen_partitions[0].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Branch 5 "490981166" "state_q" (4) "state_q InitSt ,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "490981166" "state_q" (5) "state_q InitWaitSt ,-,-,-,1,1,1,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "490981166" "state_q" (14) "state_q ReadWaitSt ,-,-,-,-,-,-,-,-,-,1,1,1,-,-,-" -CHECKSUM: "3162909804 1847756134" -INSTANCE: tb.dut.gen_partitions[4].gen_unbuffered.u_part_unbuf -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 3964686460" -INSTANCE: tb.dut.gen_partitions[7].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (20) "state_q CnstyReadSt ,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (35) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (43) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (47) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,-,0,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (49) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (50) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 3964686460" -INSTANCE: tb.dut.gen_partitions[8].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (20) "state_q CnstyReadSt ,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (35) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (43) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (47) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,-,0,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (49) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (50) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 3964686460" -INSTANCE: tb.dut.gen_partitions[9].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (20) "state_q CnstyReadSt ,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (35) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (43) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (47) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,-,0,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (49) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "3673468110" "state_q" (50) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 6 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 2334161493" -INSTANCE: tb.dut.gen_partitions[5].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (11) "state_q InitDescrSt ,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (12) "state_q InitDescrSt ,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (13) "state_q InitDescrWaitSt ,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (14) "state_q InitDescrWaitSt ,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (20) "state_q CnstyReadSt ,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (33) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (38) "state_q IntegScrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (39) "state_q IntegScrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (40) "state_q IntegScrWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (41) "state_q IntegScrWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (43) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (49) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (50) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 5 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 2334161493" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (11) "state_q InitDescrSt ,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (12) "state_q InitDescrSt ,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (13) "state_q InitDescrWaitSt ,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (14) "state_q InitDescrWaitSt ,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (20) "state_q CnstyReadSt ,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (33) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (38) "state_q IntegScrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (39) "state_q IntegScrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (40) "state_q IntegScrWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (41) "state_q IntegScrWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (42) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,1,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "344890278" "state_q" (45) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 5 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 5 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3665351474 2810977924" -INSTANCE: tb.dut.gen_partitions[10].gen_lifecycle.u_part_buf -ANNOTATION: "VC_COV_UNR" -Branch 0 "2541341865" "(base_sel == DigOffset)" (0) "(base_sel == DigOffset) 1" -ANNOTATION: "VC_COV_UNR" -Branch 1 "341865418" "(data_sel == ScrmblData)" (0) "(data_sel == ScrmblData) 1" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (12) "state_q InitDescrSt ,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (14) "state_q InitDescrWaitSt ,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (33) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,1,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (35) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (37) "state_q IntegDigClrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (39) "state_q IntegScrSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (41) "state_q IntegScrWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (45) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,0,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (47) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,1,0,-,-,0,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (48) "state_q IntegDigSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (50) "state_q IntegDigPadSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (52) "state_q IntegDigFinSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 3 "1949926999" "state_q" (56) "state_q IntegDigWaitSt ,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,0,-,-,-" -ANNOTATION: "VC_COV_UNR" -Branch 4 "375157548" "ecc_err" (0) "ecc_err 1,1" -ANNOTATION: "VC_COV_UNR" -Branch 4 "375157548" "ecc_err" (1) "ecc_err 1,0" -CHECKSUM: "3818998033 3877782530" -INSTANCE: tb.dut.gen_partitions[6].gen_buffered.u_part_buf.u_otp_ctrl_ecc_reg -ANNOTATION: "VC_COV_UNR" -Branch 1 "2154824802" "(32'(addr_i) < Depth)" (2) "(32'(addr_i) < Depth) 0,-" -CHECKSUM: "3215070453 1827096802" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_reqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Branch 0 "721764659" "full_o" (2) "full_o 0,0" -ANNOTATION: "VC_COV_UNR" -Branch 1 "2417346495" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -ANNOTATION: "VC_COV_UNR" -Branch 2 "456961687" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -CHECKSUM: "3215070453 1827096802" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_sramreqfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Branch 0 "721764659" "full_o" (2) "full_o 0,0" -ANNOTATION: "VC_COV_UNR" -Branch 1 "2417346495" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -ANNOTATION: "VC_COV_UNR" -Branch 2 "456961687" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -CHECKSUM: "3215070453 1827096802" -INSTANCE: tb.dut.u_tlul_adapter_sram.u_rspfifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Branch 0 "721764659" "full_o" (2) "full_o 0,0" -ANNOTATION: "VC_COV_UNR" -Branch 1 "2417346495" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -ANNOTATION: "VC_COV_UNR" -Branch 2 "456961687" "(!rst_ni)" (3) "(!rst_ni) 0,0,0,1" -CHECKSUM: "3215070453 1827096802" -INSTANCE: tb.dut.u_otp_rsp_fifo.gen_normal_fifo.u_fifo_cnt -ANNOTATION: "VC_COV_UNR" -Branch 0 "721764659" "full_o" (0) "full_o 1,-" diff --git a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg b/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg deleted file mode 100644 index d69a193276230..0000000000000 --- a/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - - -// The modules below are preverified in FPV testbench. -// There are many conditional coverage and hard to them all. --moduletree prim_secded_inv_72_64_dec --moduletree prim_secded_inv_72_64_enc - -begin tgl - +module prim_secded_inv_72_64_dec - +module prim_secded_inv_72_64_enc -end diff --git a/hw/ip/otp_ctrl/dv/doc/tb.svg b/hw/ip/otp_ctrl/dv/doc/tb.svg deleted file mode 100644 index a910d80617037..0000000000000 --- a/hw/ip/otp_ctrl/dv/doc/tb.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_ast_inputs_cfg.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_ast_inputs_cfg.sv deleted file mode 100644 index 4b723d7905ff2..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_ast_inputs_cfg.sv +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// -// Configuration values for DUT input signals -// -// -// This class randomizes values for DUT signal inputs -// and sets constraints on these values. -// -// This class will be instantiated inside otp_ctrl_env_cfg object, and will connect -// to it's otp_ctrl_vif signals and drive them each reset event -// -// The constraints can be hardened and softened as needed in -// closed-source environment. -// In order to override these constraints, please inherit this class -// and set a type override in the closed source environment - -class otp_ctrl_ast_inputs_cfg extends uvm_object; - `uvm_object_utils(otp_ctrl_ast_inputs_cfg); - `uvm_object_new - - // Group: Variables - rand otp_ast_rsp_t otp_ast_pwr_seq_h; - rand logic [otp_ctrl_pkg::OtpTestCtrlWidth-1:0] otp_vendor_test_ctrl; - rand prim_mubi_pkg::mubi4_t scanmode; - rand logic scan_en, scan_rst_n; - - // Group: Constraints - constraint dut_values_c { - otp_vendor_test_ctrl == 32'h0; - } - -endclass: otp_ctrl_ast_inputs_cfg diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core deleted file mode 100644 index 4b35e4c2118ab..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core +++ /dev/null @@ -1,59 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:otp_ctrl_env:0.1" -description: "OTP_CTRL DV UVM environment" -filesets: - files_dv: - depend: - - lowrisc:dv:ralgen - - lowrisc:dv:cip_lib - - lowrisc:dv:mem_bkdr_util - - lowrisc:dv:crypto_dpi_present - - lowrisc:dv:lc_ctrl_dv_utils - files: - - otp_ctrl_env_pkg.sv - - otp_ctrl_if.sv - - otp_ctrl_ast_inputs_cfg.sv: {is_include_file: true} - - otp_ctrl_env_cfg.sv: {is_include_file: true} - - otp_ctrl_env_cov.sv: {is_include_file: true} - - otp_ctrl_virtual_sequencer.sv: {is_include_file: true} - - otp_ctrl_scoreboard.sv: {is_include_file: true} - - otp_ctrl_env.sv: {is_include_file: true} - - seq_lib/otp_ctrl_vseq_list.sv: {is_include_file: true} - - seq_lib/otp_ctrl_callback_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_base_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_common_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_wake_up_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_smoke_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_partition_walk_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_low_freq_read_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_init_fail_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_dai_lock_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_dai_errs_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_macro_errs_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_background_chks_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_check_fail_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_parallel_base_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_regwen_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_parallel_key_req_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_parallel_lc_req_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_parallel_lc_esc_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_test_access_vseq.sv: {is_include_file: true} - - seq_lib/otp_ctrl_stress_all_vseq.sv: {is_include_file: true} - file_type: systemVerilogSource - -generate: - ral: - generator: ralgen - parameters: - name: otp_ctrl - ip_hjson: ../../data/otp_ctrl.hjson - -targets: - default: - filesets: - - files_dv - generate: - - ral diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv deleted file mode 100644 index 454d14df149ee..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_env #( - type CFG_T = otp_ctrl_env_cfg, - type COV_T = otp_ctrl_env_cov, - type VIRTUAL_SEQUENCER_T = otp_ctrl_virtual_sequencer, - type SCOREBOARD_T = otp_ctrl_scoreboard - ) - extends cip_base_env #( - .CFG_T (CFG_T), - .COV_T (COV_T), - .VIRTUAL_SEQUENCER_T(VIRTUAL_SEQUENCER_T), - .SCOREBOARD_T (SCOREBOARD_T) - ); - `uvm_component_param_utils(otp_ctrl_env #(CFG_T, COV_T, VIRTUAL_SEQUENCER_T, SCOREBOARD_T)) - - `uvm_component_new - - push_pull_agent#(.DeviceDataWidth(SRAM_DATA_SIZE)) m_sram_pull_agent[NumSramKeyReqSlots]; - push_pull_agent#(.DeviceDataWidth(OTBN_DATA_SIZE)) m_otbn_pull_agent; - push_pull_agent#(.DeviceDataWidth(FLASH_DATA_SIZE)) m_flash_addr_pull_agent; - push_pull_agent#(.DeviceDataWidth(FLASH_DATA_SIZE)) m_flash_data_pull_agent; - push_pull_agent#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE)) m_lc_prog_pull_agent; - - function void build_phase(uvm_phase phase); - super.build_phase(phase); - - // build sram-otp pull agent - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - string sram_agent_name = $sformatf("m_sram_pull_agent[%0d]", i); - m_sram_pull_agent[i] = push_pull_agent#(.DeviceDataWidth(SRAM_DATA_SIZE))::type_id::create( - sram_agent_name, this); - uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(SRAM_DATA_SIZE)))::set(this, - $sformatf("%0s*", sram_agent_name), "cfg", cfg.m_sram_pull_agent_cfg[i]); - end - - // build otbn-otp pull agent - m_otbn_pull_agent = push_pull_agent#(.DeviceDataWidth(OTBN_DATA_SIZE))::type_id::create( - "m_otbn_pull_agent", this); - uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(OTBN_DATA_SIZE)))::set( - this, "m_otbn_pull_agent", "cfg", cfg.m_otbn_pull_agent_cfg); - - // build flash-otp pull agent - m_flash_addr_pull_agent = push_pull_agent#(.DeviceDataWidth(FLASH_DATA_SIZE))::type_id::create( - "m_flash_addr_pull_agent", this); - uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set( - this, "m_flash_addr_pull_agent", "cfg", cfg.m_flash_addr_pull_agent_cfg); - m_flash_data_pull_agent = push_pull_agent#(.DeviceDataWidth(FLASH_DATA_SIZE))::type_id::create( - "m_flash_data_pull_agent", this); - uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set( - this, "m_flash_data_pull_agent", "cfg", cfg.m_flash_data_pull_agent_cfg); - - // build lc-otp program pull agent - m_lc_prog_pull_agent = push_pull_agent#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1)) - ::type_id::create("m_lc_prog_pull_agent", this); - uvm_config_db#(push_pull_agent_cfg#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1))):: - set(this, "m_lc_prog_pull_agent", "cfg", cfg.m_lc_prog_pull_agent_cfg); - - // config mem virtual interface - if (!uvm_config_db#(mem_bkdr_util)::get(this, "", "mem_bkdr_util", cfg.mem_bkdr_util_h)) begin - `uvm_fatal(`gfn, "failed to get mem_bkdr_util from uvm_config_db") - end - - // config otp_ctrl output data virtual interface - if (!uvm_config_db#(otp_ctrl_vif)::get(this, "", "otp_ctrl_vif", cfg.otp_ctrl_vif)) begin - `uvm_fatal(`gfn, "failed to get otp_ctrl_vif from uvm_config_db") - end - - // Check if `NumPart` constant is assigned to the correct value. - `DV_CHECK(NumPart == (LifeCycleIdx + 1)) - - endfunction - - function void connect_phase(uvm_phase phase); - super.connect_phase(phase); - - // connect SRAM sequencer and analysis ports - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - virtual_sequencer.sram_pull_sequencer_h[i] = m_sram_pull_agent[i].sequencer; - if (cfg.en_scb) begin - m_sram_pull_agent[i].monitor.analysis_port.connect( - scoreboard.sram_fifos[i].analysis_export); - end - end - - virtual_sequencer.otbn_pull_sequencer_h = m_otbn_pull_agent.sequencer; - virtual_sequencer.flash_addr_pull_sequencer_h = m_flash_addr_pull_agent.sequencer; - virtual_sequencer.flash_data_pull_sequencer_h = m_flash_data_pull_agent.sequencer; - virtual_sequencer.lc_prog_pull_sequencer_h = m_lc_prog_pull_agent.sequencer; - - if (cfg.en_scb) begin - m_otbn_pull_agent.monitor.analysis_port.connect(scoreboard.otbn_fifo.analysis_export); - m_flash_addr_pull_agent.monitor.analysis_port.connect( - scoreboard.flash_addr_fifo.analysis_export); - m_flash_data_pull_agent.monitor.analysis_port.connect( - scoreboard.flash_data_fifo.analysis_export); - m_lc_prog_pull_agent.monitor.analysis_port.connect(scoreboard.lc_prog_fifo.analysis_export); - end - - // connect the DUT cfg instance to the handle in the otp_ctrl_vif - this.cfg.otp_ctrl_vif.dut_cfg = this.cfg.dut_cfg; - endfunction - -endclass diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv deleted file mode 100644 index 52c67e8ff2d20..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -`define OTP_CLK_CONSTRAINT(FREQ_) \ - FREQ_ dist { \ - 6 :/ 2, \ - [24:25] :/ 2, \ - [26:47] :/ 1, \ - [48:50] :/ 2, \ - [51:95] :/ 1, \ - 96 :/ 1, \ - [97:99] :/ 1, \ - 100 :/ 1 \ - }; - -class otp_ctrl_env_cfg extends cip_base_env_cfg #(.RAL_T(otp_ctrl_core_reg_block)); - - // ext component cfgs - rand push_pull_agent_cfg#(.DeviceDataWidth(SRAM_DATA_SIZE)) - m_sram_pull_agent_cfg[NumSramKeyReqSlots]; - rand push_pull_agent_cfg#(.DeviceDataWidth(OTBN_DATA_SIZE)) m_otbn_pull_agent_cfg; - rand push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE)) m_flash_data_pull_agent_cfg; - rand push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE)) m_flash_addr_pull_agent_cfg; - rand push_pull_agent_cfg#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE)) - m_lc_prog_pull_agent_cfg; - - // Memory backdoor util instance for OTP. - mem_bkdr_util mem_bkdr_util_h; - - // ext interfaces - otp_ctrl_vif otp_ctrl_vif; - virtual clk_rst_if clk_rst_vif_otp_ctrl_prim_reg_block; - - bit backdoor_clear_mem; - - // Check ECC errors - otp_ecc_err_e ecc_chk_err [NumPart] = '{default:OtpNoEccErr}; - - // values for otp_ctrl_if signals connected to DUT - rand otp_ctrl_ast_inputs_cfg dut_cfg; - - // Introduce this flag to avoid close source conflict. - bit create_prim_tl_agent = 1; - - `uvm_object_utils_begin(otp_ctrl_env_cfg) - `uvm_object_utils_end - - `uvm_object_new - - constraint clk_freq_mhz_c { - `OTP_CLK_CONSTRAINT(clk_freq_mhz) - foreach (clk_freqs_mhz[i]) { - `OTP_CLK_CONSTRAINT(clk_freqs_mhz[i]) - } - } - - virtual function void initialize(bit [31:0] csr_base_addr = '1); - string prim_ral_name = "otp_ctrl_prim_reg_block"; - ral_model_names.push_back(prim_ral_name); - clk_freqs_mhz[prim_ral_name] = clk_freq_mhz; - - list_of_alerts = otp_ctrl_env_pkg::LIST_OF_ALERTS; - num_edn = 1; - tl_intg_alert_name = "fatal_bus_integ_error"; - sec_cm_alert_name = "fatal_check_error"; - - super.initialize(csr_base_addr); - - // create push_pull agent config obj - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - string cfg_name = $sformatf("sram_pull_agent_cfg[%0d]", i); - m_sram_pull_agent_cfg[i] = push_pull_agent_cfg#(.DeviceDataWidth(SRAM_DATA_SIZE))::type_id - ::create(cfg_name); - m_sram_pull_agent_cfg[i].agent_type = PullAgent; - end - - m_otbn_pull_agent_cfg = push_pull_agent_cfg#(.DeviceDataWidth(OTBN_DATA_SIZE))::type_id - ::create("m_otbn_pull_agent_cfg"); - m_otbn_pull_agent_cfg.agent_type = PullAgent; - - m_flash_data_pull_agent_cfg = push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE))::type_id - ::create("m_flash_data_pull_agent_cfg"); - m_flash_data_pull_agent_cfg.agent_type = PullAgent; - m_flash_addr_pull_agent_cfg = push_pull_agent_cfg#(.DeviceDataWidth(FLASH_DATA_SIZE))::type_id - ::create("m_flash_addr_pull_agent_cfg"); - m_flash_addr_pull_agent_cfg.agent_type = PullAgent; - - m_lc_prog_pull_agent_cfg = push_pull_agent_cfg#(.HostDataWidth(LC_PROG_DATA_SIZE), - .DeviceDataWidth(1))::type_id::create("m_lc_prog_pull_agent_cfg"); - m_lc_prog_pull_agent_cfg.agent_type = PullAgent; - - // set num_interrupts & num_alerts - num_interrupts = ral.intr_state.get_n_used_bits(); - - // only support 1 outstanding TL items in tlul_adapter - m_tl_agent_cfg.max_outstanding_req = 1; - m_tl_agent_cfgs["otp_ctrl_prim_reg_block"].max_outstanding_req = 1; - - // create the inputs cfg instance - dut_cfg = otp_ctrl_ast_inputs_cfg::type_id::create("dut_cfg"); - endfunction - -endclass - -`undef OTP_CLK_CONSTRAINT diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv deleted file mode 100644 index 10e7d90168fea..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -/** - * Covergoups that are dependent on run-time parameters that may be available - * only in build_phase can be defined here - * Covergroups may also be wrapped inside helper classes if needed. - */ -class otp_ctrl_unbuf_err_code_cg_wrap; - // Unbuffered partition can use TLUL interface to read out but cannot write, thus error_code does - // not have write_blank_err. - covergroup unbuf_err_code_cg(string name) with function sample(bit [TL_DW-1:0] val); - option.per_instance = 1; - option.name = name; - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins access_err = {OtpAccessError}; - bins check_fail = {OtpCheckFailError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - function new(string name); - unbuf_err_code_cg = new(name); - endfunction -endclass - -class otp_ctrl_buf_err_code_cg_wrap; - // Buffered partition must use DAI interface to access partition, so it does not have access_err - // and write_blank err. - covergroup buf_err_code_cg(string name) with function sample(bit [TL_DW-1:0] val); - option.per_instance = 1; - option.name = name; - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins check_fail = {OtpCheckFailError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - function new(string name); - buf_err_code_cg = new(name); - endfunction -endclass - -class otp_ctrl_csr_rd_after_alert_cg_wrap; - // This covergroup samples CSRs being checked (via CSR read) after fatal alert is issued. - covergroup csr_rd_after_alert_cg(otp_ctrl_core_reg_block ral) with function sample(bit[TL_DW-1:0] - csr_offset); - read_csr_after_alert_issued: coverpoint csr_offset { - bins unbuffered_digests = { - ral.vendor_test_digest[0].get_offset(), - ral.vendor_test_digest[1].get_offset(), - ral.creator_sw_cfg_digest[0].get_offset(), - ral.creator_sw_cfg_digest[1].get_offset(), - ral.owner_sw_cfg_digest[0].get_offset(), - ral.owner_sw_cfg_digest[1].get_offset(), - ral.rot_creator_auth_codesign_digest[0].get_offset(), - ral.rot_creator_auth_codesign_digest[1].get_offset(), - ral.rot_creator_auth_state_digest[0].get_offset(), - ral.rot_creator_auth_state_digest[1].get_offset() - }; - bins hw_digests = { - ral.hw_cfg0_digest[0].get_offset(), - ral.hw_cfg0_digest[1].get_offset(), - ral.hw_cfg1_digest[0].get_offset(), - ral.hw_cfg1_digest[1].get_offset() - }; - bins secret_digests = { - ral.secret0_digest[0].get_offset(), - ral.secret0_digest[1].get_offset(), - ral.secret1_digest[0].get_offset(), - ral.secret1_digest[1].get_offset(), - ral.secret2_digest[0].get_offset(), - ral.secret2_digest[1].get_offset() - }; - bins direct_access_rdata = { - ral.direct_access_rdata[0].get_offset(), - ral.direct_access_rdata[1].get_offset() - }; - bins status = { - ral.status.get_offset() - }; - bins error_code = { - ral.err_code[0].get_offset(), - ral.err_code[1].get_offset(), - ral.err_code[2].get_offset(), - ral.err_code[3].get_offset(), - ral.err_code[4].get_offset(), - ral.err_code[5].get_offset(), - ral.err_code[6].get_offset(), - ral.err_code[7].get_offset(), - ral.err_code[8].get_offset(), - ral.err_code[9].get_offset(), - ral.err_code[10].get_offset(), - ral.err_code[11].get_offset(), - ral.err_code[12].get_offset() - }; - } - endgroup - - function new(otp_ctrl_core_reg_block ral); - csr_rd_after_alert_cg = new(ral); - endfunction - - function void sample(bit[TL_DW-1:0] csr_offset); - csr_rd_after_alert_cg.sample(csr_offset); - endfunction -endclass - -class otp_ctrl_unbuf_access_lock_cg_wrap; - covergroup unbuf_access_lock_cg(string name) with function sample(bit read_lock, bit write_lock, - bit is_write); - option.per_instance = 1; - option.name = name; - read_access_locked: coverpoint read_lock; - write_access_locked: coverpoint write_lock; - operation_type: coverpoint is_write { - bins write_op = {1}; - bins read_op = {0}; - } - unbuf_part_access_cross: cross read_access_locked, write_access_locked, operation_type; - endgroup - - function new(string name); - unbuf_access_lock_cg = new(name); - endfunction - - function void sample(bit read_lock, bit write_lock, bit is_write); - unbuf_access_lock_cg.sample(read_lock, write_lock, is_write); - endfunction -endclass - -class otp_ctrl_env_cov extends cip_base_env_cov #(.CFG_T(otp_ctrl_env_cfg)); - `uvm_component_utils(otp_ctrl_env_cov) - - // the base class provides the following handles for use: - // otp_ctrl_env_cfg: cfg - - otp_ctrl_unbuf_err_code_cg_wrap unbuf_err_code_cg_wrap[NumPartUnbuf]; - otp_ctrl_buf_err_code_cg_wrap buf_err_code_cg_wrap[NumPartBuf]; - otp_ctrl_csr_rd_after_alert_cg_wrap csr_rd_after_alert_cg_wrap; - otp_ctrl_unbuf_access_lock_cg_wrap unbuf_access_lock_cg_wrap[NumPartUnbuf]; - - bit_toggle_cg_wrap lc_prog_cg; - bit_toggle_cg_wrap otbn_req_cg; - bit_toggle_cg_wrap status_csr_cg[OtpStatusFieldSize]; - - // covergroups - // This covergroup collects different conditions when outputs (hwcfg_o, keymgr_key_o) are checked - // in scb: - // - If lc_esc_en is On - // - If each partition is locked (expect LC) - covergroup power_on_cg with function sample (bit lc_esc_en, bit[NumPart-2:0] parts_locked); - lc_esc: coverpoint lc_esc_en; - vendor_test_lock: coverpoint parts_locked[0]; - creator_sw_cfg_lock: coverpoint parts_locked[1]; - owner_sw_cfg_lock: coverpoint parts_locked[2]; - rot_creator_auth_codesign_lock: coverpoint parts_locked[3]; - rot_creator_auth_state_lock: coverpoint parts_locked[4]; - hw_cfg0_lock: coverpoint parts_locked[5]; - hw_cfg1_lock: coverpoint parts_locked[6]; - secret0_lock: coverpoint parts_locked[7]; - secret1_lock: coverpoint parts_locked[8]; - secret2_lock: coverpoint parts_locked[9]; - endgroup - - // This covergroup is sampled only if flash request passed scb check. - covergroup flash_req_cg with function sample (int index, bit locked); - flash_index: coverpoint index { - bins flash_data_key = {FlashDataKey}; - bins flash_addr_key = {FlashAddrKey}; - illegal_bins il = default; - } - secret1_lock: coverpoint locked; - flash_req_lock_cross: cross flash_index, secret1_lock; - endgroup - - // This covergroup is sampled only if sram request passed scb check. - covergroup sram_req_cg with function sample (int index, bit locked); - sram_index: coverpoint index { - bins sram_key[NumSramKeyReqSlots] = {[0:(NumSramKeyReqSlots-1)]}; - illegal_bins il = default; - } - secret1_lock: coverpoint locked; - sram_req_lock_cross: cross sram_index, secret1_lock; - endgroup - - // This covergroup is sampled only if keymgr output passed scb check. - covergroup keymgr_o_cg with function sample (bit lc_seed_hw_rd_en, bit locked); - keymgr_rd_en: coverpoint lc_seed_hw_rd_en; - // TODO: probably should add all partitions with keymgr material here. - secret2_lock: coverpoint locked; - keymgr_output_conditions: cross keymgr_rd_en, secret2_lock; - endgroup - - // This covergroup samples dai request being issued after fatal alert is issued. - covergroup req_dai_access_after_alert_cg with function sample(bit [TL_DW-1:0] val); - req_dai_access_after_alert_issued: coverpoint val { - bins dai_write = {DaiWrite}; - bins dai_read = {DaiRead}; - bins dai_digest = {DaiDigest}; - } - endgroup - - // This covergroup samples background check being issued after fatal alert is issued. - covergroup issue_checks_after_alert_cg with function sample(bit [TL_DW-1:0] val); - issue_checks_after_alert_issued: coverpoint val { - bins integrity_check = {1}; - bins consistency_check = {2}; - } - endgroup - - // This covergroup collects DAI err_code value. - // DAI access does not have checks, thus no check_fail error. - covergroup dai_err_code_cg with function sample(bit [TL_DW-1:0] val, int part_idx); - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins ecc_corr_err = {OtpMacroEccCorrError}; - bins ecc_uncorr_err = {OtpMacroEccUncorrError}; - bins write_blank_err = {OtpMacroWriteBlankError}; - bins access_err = {OtpAccessError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - partition: coverpoint part_idx { - bins vendor_test = {VendorTestIdx}; - bins creator_sw_cfg = {CreatorSwCfgIdx}; - bins owner_sw_cfg = {OwnerSwCfgIdx}; - bins rot_creator_auth_codesign = {RotCreatorAuthCodesignIdx}; - bins rot_creator_auth_state = {RotCreatorAuthStateIdx}; - bins hw_cfg0 = {HwCfg0Idx}; - bins hw_cfg1 = {HwCfg1Idx}; - bins secret0 = {Secret0Idx}; - bins secret1 = {Secret1Idx}; - bins secret2 = {Secret2Idx}; - bins life_cycle = {LifeCycleIdx}; - bins illegal_idx = default; - } - // LC partition has a separate LCI err_code to collect macro related errors. - dai_err_code_for_all_partitions: cross err_code_vals, partition { - // Illegal bin - vendor_test partition does not have EccUncorrectable error. - illegal_bins vendor_test_ecc_uncorrectable_err = - binsof (partition.vendor_test) && binsof (err_code_vals.ecc_uncorr_err); - ignore_bins life_cycle_ignore = binsof (partition.life_cycle) && - binsof(err_code_vals) intersect {[OtpMacroError:OtpMacroWriteBlankError]}; - } - endgroup - - // This covergroup collects LCI err_code value. - // LCI access does not have digest, thus no access_err. Check_fail, ecc_errors are covered in lc - // buffered partition instead of LCI here. - covergroup lci_err_code_cg with function sample(bit [TL_DW-1:0] val); - err_code_vals: coverpoint val { - bins no_err = {OtpNoError}; - bins macro_err = {OtpMacroError}; - bins write_blank_err = {OtpMacroWriteBlankError}; - bins fsm_err = {OtpFsmStateError}; - illegal_bins illegal_err = default; - } - endgroup - - covergroup dai_access_secret2_cg with function sample(bit lc_rw_en, dai_cmd_e dai_cmd); - lc_creator_seed_sw_rw_en: coverpoint lc_rw_en; - dai_access_cmd: coverpoint dai_cmd { - bins dai_rd = {DaiRead}; - bins dai_wr = {DaiWrite}; - bins dai_digest = {DaiDigest}; - } - dai_access_secret2: cross lc_creator_seed_sw_rw_en, dai_access_cmd; - endgroup - - function new(string name, uvm_component parent); - super.new(name, parent); - // Create coverage from local covergroups. - power_on_cg = new(); - flash_req_cg = new(); - sram_req_cg = new(); - keymgr_o_cg = new(); - req_dai_access_after_alert_cg = new(); - issue_checks_after_alert_cg = new(); - dai_err_code_cg = new(); - lci_err_code_cg = new(); - dai_access_secret2_cg = new(); - endfunction : new - - virtual function void build_phase(uvm_phase phase); - super.build_phase(phase); - // Create instances from bit_toggle_cg_wrapper. - lc_prog_cg = new("lc_prog_cg", "", 0); - otbn_req_cg = new("otbn_req_cg", "", 0); - foreach (status_csr_cg[i]) begin - otp_status_e index = otp_status_e'(i); - status_csr_cg[i]= new(index.name, "status_csr_cg", 0); - end - - // Create instances from external wrapper classes. - csr_rd_after_alert_cg_wrap = new(cfg.ral); - foreach (unbuf_err_code_cg_wrap[i]) begin - otp_status_e index = otp_status_e'(i); - unbuf_err_code_cg_wrap[i] = new($sformatf("unbuf_err_code_cg_wrap[%0s]", index.name)); - end - foreach (buf_err_code_cg_wrap[i]) begin - otp_status_e index = otp_status_e'(i + 2); - buf_err_code_cg_wrap[i] = new($sformatf("buf_err_code_cg_wrap[%0s]", index.name)); - end - foreach (unbuf_access_lock_cg_wrap[i]) begin - part_idx_e index = part_idx_e'(i); - unbuf_access_lock_cg_wrap[i] = new($sformatf("buf_err_code_cg_wrap[%0s]", index.name)); - end - endfunction - - function void collect_status_cov(bit [TL_DW-1:0] val); - foreach (status_csr_cg[i]) begin - status_csr_cg[i].sample(val[i]); - end - endfunction - - // Collect coverage for err_code when it is a compact multi-reg. For DAI error it uses the given - // access_part_idx as the target of the DAI access. - function void collect_compact_err_code_cov(bit [TL_DW-1:0] val, int access_part_idx = DaiIdx); - dv_base_reg_field err_code_flds[$]; - cfg.ral.err_code[0].get_dv_base_reg_fields(err_code_flds); - foreach (err_code_flds[part]) begin - collect_err_code_cov(part, get_field_val(err_code_flds[part], val), access_part_idx); - end - endfunction - - // Collect coverage for a given partition error_code. For DAI error it uses the given - // access_part_idx as the target of the DAI access. - function void collect_err_code_cov(int part_idx, bit [TL_DW-1:0] val, - int access_part_idx = DaiIdx); - case (part_idx) - OtpVendorTestErrIdx: begin - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - end - OtpCreatorSwCfgErrIdx: begin - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - end - OtpOwnerSwCfgErrIdx: begin - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - end - OtpRotCreatorAuthCodesignErrIdx: begin - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - end - OtpRotCreatorAuthStateErrIdx: begin - unbuf_err_code_cg_wrap[part_idx].unbuf_err_code_cg.sample(val); - end - OtpHwCfg0ErrIdx: begin - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - end - OtpHwCfg1ErrIdx: begin - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - end - OtpSecret0ErrIdx: begin - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - end - OtpSecret1ErrIdx: begin - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - end - OtpSecret2ErrIdx: begin - buf_err_code_cg_wrap[part_idx - NumPartUnbuf].buf_err_code_cg.sample(val); - end - OtpLifeCycleErrIdx: begin - end - OtpDaiErrIdx: begin - dai_err_code_cg.sample(val, access_part_idx); - end - OtpLciErrIdx: begin - lci_err_code_cg.sample(val); - end - default: begin - `uvm_fatal(`gfn, $sformatf("invalid err_code index %0d", part_idx)) - end - endcase - endfunction -endclass diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv deleted file mode 100644 index 79026dbc95a43..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -package otp_ctrl_env_pkg; - // dep packages - import uvm_pkg::*; - import top_pkg::*; - import dv_utils_pkg::*; - import dv_lib_pkg::*; - import dv_base_reg_pkg::*; - import tl_agent_pkg::*; - import cip_base_pkg::*; - import csr_utils_pkg::*; - import push_pull_agent_pkg::*; - import otp_ctrl_core_ral_pkg::*; - import otp_ctrl_prim_ral_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_pkg::*; - import otp_ctrl_part_pkg::*; - import lc_ctrl_pkg::*; - import lc_ctrl_state_pkg::*; - import lc_ctrl_dv_utils_pkg::*; - import mem_bkdr_util_pkg::*; - import otp_scrambler_pkg::*; - import sec_cm_pkg::*; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // parameters - parameter string LIST_OF_ALERTS[] = {"fatal_macro_error", - "fatal_check_error", - "fatal_bus_integ_error", - "fatal_prim_otp_alert", - "recov_prim_otp_alert"}; - parameter uint NUM_ALERTS = 5; - parameter uint NUM_EDN = 1; - - parameter uint DIGEST_SIZE = 8; - parameter uint SW_WINDOW_BASE_ADDR = 'h800; - parameter uint SW_WINDOW_SIZE = NumSwCfgWindowWords * 4; - - parameter uint TL_SIZE = (TL_DW / 8); - // LC has its own storage in scb - // we can use the LC offset here because it will always be the last partition. - parameter uint OTP_ARRAY_SIZE = LcTransitionCntOffset / TL_SIZE; - - parameter int OTP_ADDR_WIDTH = OtpByteAddrWidth-2; - - parameter uint NUM_PRIM_REG = 8; - - // sram rsp data has 1 bit for seed_valid, the rest are for key and nonce - parameter uint SRAM_DATA_SIZE = 1 + SramKeyWidth + SramNonceWidth; - // otbn rsp data has 1 bit for seed_valid, the rest are for key and nonce - parameter uint OTBN_DATA_SIZE = 1 + OtbnKeyWidth + OtbnNonceWidth; - // flash rsp data has 1 bit for seed_valid, the rest are for key - parameter uint FLASH_DATA_SIZE = 1 + FlashKeyWidth; - // lc program data has lc_state data and lc_cnt data - parameter uint LC_PROG_DATA_SIZE = LcStateWidth + LcCountWidth; - - parameter uint NUM_SRAM_EDN_REQ = 12; - parameter uint NUM_OTBN_EDN_REQ = 10; - - parameter uint CHK_TIMEOUT_CYC = 40; - - // When fatal alert triggered, all partitions and the DAI & LCI go to error state and status will - // be set to 1. - parameter bit [NumErrorEntries-1:0] FATAL_EXP_STATUS = '1; - - // lc does not have dai access - parameter int PART_BASE_ADDRS [NumPart-1] = { - VendorTestOffset, - CreatorSwCfgOffset, - OwnerSwCfgOffset, - RotCreatorAuthCodesignOffset, - RotCreatorAuthStateOffset, - HwCfg0Offset, - HwCfg1Offset, - Secret0Offset, - Secret1Offset, - Secret2Offset - }; - - // lc does not have digest - parameter int PART_OTP_DIGEST_ADDRS [NumPart-1] = { - VendorTestDigestOffset >> 2, - CreatorSwCfgDigestOffset >> 2, - OwnerSwCfgDigestOffset >> 2, - RotCreatorAuthCodesignDigestOffset >> 2, - RotCreatorAuthStateDigestOffset >> 2, - HwCfg0DigestOffset >> 2, - HwCfg1DigestOffset >> 2, - Secret0DigestOffset >> 2, - Secret1DigestOffset >> 2, - Secret2DigestOffset >> 2 - }; - - // types - typedef enum bit [1:0] { - OtpOperationDone, - OtpErr, - NumOtpCtrlIntr - } otp_intr_e; - - typedef enum bit [5:0] { - OtpVendorTestErrIdx, - OtpCreatorSwCfgErrIdx, - OtpOwnerSwCfgErrIdx, - OtpRotCreatorAuthCodesignErrIdx, - OtpRotCreatorAuthStateErrIdx, - OtpHwCfg0ErrIdx, - OtpHwCfg1ErrIdx, - OtpSecret0ErrIdx, - OtpSecret1ErrIdx, - OtpSecret2ErrIdx, - OtpLifeCycleErrIdx, - OtpDaiErrIdx, - OtpLciErrIdx, - OtpTimeoutErrIdx, - OtpLfsrFsmErrIdx, - OtpScramblingFsmErrIdx, - OtpDerivKeyFsmErrIdx, - OtpBusIntegErrorIdx, - OtpDaiIdleIdx, - OtpCheckPendingIdx, - OtpStatusFieldSize - } otp_status_e; - - typedef enum bit [2:0] { - OtpNoError, - OtpMacroError, - OtpMacroEccCorrError, - OtpMacroEccUncorrError, - OtpMacroWriteBlankError, - OtpAccessError, - OtpCheckFailError, - OtpFsmStateError - } otp_err_code_e; - - typedef enum bit [1:0] { - OtpNoEccErr, - OtpEccCorrErr, - OtpEccUncorrErr - } otp_ecc_err_e; - - typedef enum bit [1:0] { - OtpNoAlert, - OtpCheckAlert, - OtpMacroAlert - } otp_alert_e; - - typedef struct packed { - bit read_lock; - bit write_lock; - } otp_part_access_lock_t; - - // OTP conditions when driving specific port. - typedef enum bit [2:0] { - DuringOTPInit, - DuringOTPDaiBusy, - DuringOTPDaiDigest, - DuringOTPRead, - DriveRandomly - } port_drive_condition_e; - - typedef virtual otp_ctrl_if otp_ctrl_vif; - - parameter otp_err_code_e OTP_TERMINAL_ERRS[4] = {OtpMacroEccUncorrError, - OtpCheckFailError, - OtpFsmStateError, - OtpMacroError}; - - // functions - function automatic int get_part_index(bit [TL_DW-1:0] addr); - int index; - for (index = 0; index < NumPart; index++) begin - if (PartInfo[index].offset > addr) begin - index--; - break; - end - end - if (index == NumPart) index--; - return index; - endfunction - - function automatic bit is_secret(bit [TL_DW-1:0] addr); - int part_index = get_part_index(addr); - return PartInfo[part_index].secret; - endfunction - - function automatic bit part_has_digest(int part_idx); - return PartInfo[part_idx].hw_digest || PartInfo[part_idx].sw_digest; - endfunction - - function automatic bit part_has_hw_digest(int part_idx); - return PartInfo[part_idx].hw_digest; - endfunction - - function automatic bit is_sw_digest(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - if (PartInfo[part_idx].sw_digest) begin - // If the partition contains a digest, it will be located in the last 64bit of the partition. - return {addr[TL_DW-1:3], 3'b0} == ((PartInfo[part_idx].offset + PartInfo[part_idx].size) - 8); - end else begin - return 0; - end - endfunction - - function automatic bit is_digest(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - if (PartInfo[part_idx].sw_digest || PartInfo[part_idx].hw_digest) begin - // If the partition contains a digest, it will be located in the last 64bit of the partition. - return {addr[TL_DW-1:3], 3'b0} == ((PartInfo[part_idx].offset + PartInfo[part_idx].size) - 8); - end else begin - return 0; - end - endfunction - - function automatic bit is_sw_part(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - return is_sw_part_idx(part_idx); - endfunction - - function automatic bit is_sw_part_idx(int part_idx); - return (PartInfo[part_idx].variant == Unbuffered); - endfunction - - function automatic bit is_hw_part(bit [TL_DW-1:0] addr); - int part_idx = get_part_index(addr); - return is_hw_part_idx(part_idx); - endfunction - - function automatic bit is_hw_part_idx(int part_idx); - return (PartInfo[part_idx].variant == Buffered); - endfunction - - // Returns true if this partition supports ECC. Otherwise, no ECC errors are reported, and - // the single bit errors are not corrected. - function automatic bit part_has_integrity(int part_idx); - return PartInfo[part_idx].integrity; - endfunction - - // Resolve an offset within the software window as an offset within the whole otp_ctrl block. - function automatic bit [TL_AW-1:0] get_sw_window_offset(bit [TL_AW-1:0] dai_addr); - return dai_addr + SW_WINDOW_BASE_ADDR; - endfunction - - function automatic bit [TL_DW-1:0] normalize_dai_addr(bit [TL_DW-1:0] dai_addr); - normalize_dai_addr = (is_secret(dai_addr) || is_digest(dai_addr)) ? dai_addr >> 3 << 3 : - dai_addr >> 2 << 2; - endfunction - - // package sources - `include "otp_ctrl_ast_inputs_cfg.sv" - `include "otp_ctrl_env_cfg.sv" - `include "otp_ctrl_env_cov.sv" - `include "otp_ctrl_virtual_sequencer.sv" - `include "otp_ctrl_scoreboard.sv" - `include "otp_ctrl_env.sv" - `include "otp_ctrl_vseq_list.sv" - -endpackage diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv deleted file mode 100644 index a2ae621cdbf53..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -// This interface collect the broadcast output data from OTP, -// and drive input requests coming into OTP. -`define ECC_REG_PATH gen_ecc_reg.u_otp_ctrl_ecc_reg.gen_ecc_dec[0].u_prim_secded_inv_72_64_dec - -// This only supports buffered partitions. -`define BUF_PART_OTP_CMD_PATH(i) \ - tb.dut.gen_partitions[``i``].gen_buffered.u_part_buf.otp_cmd_o - -`define LC_PART_OTP_CMD_PATH \ - tb.dut.gen_partitions[LifeCycleIdx].gen_lifecycle.u_part_buf.otp_cmd_o - -`define FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(i) \ - if (forced_part_access_sel[``i``].read_lock) begin \ - force tb.dut.part_access[``i``].read_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); \ - force tb.dut.part_access_dai[``i``].read_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); \ - end \ - if (forced_part_access_sel[``i``].write_lock) begin \ - force tb.dut.part_access[``i``].write_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); \ - force tb.dut.part_access_dai[``i``].write_lock = get_rand_mubi8_val(.t_weight(0), .f_weight(0)); \ - end - -`ifndef PRIM_GENERIC_OTP_PATH - `define PRIM_GENERIC_OTP_PATH\ - tb.dut.u_otp -`endif - -`ifndef PRIM_GENERIC_OTP_CMD_I_PATH - `define PRIM_GENERIC_OTP_CMD_I_PATH \ - `PRIM_GENERIC_OTP_PATH.gen_generic.u_impl_generic.cmd_i -`endif - -interface otp_ctrl_if(input clk_i, input rst_ni); - import uvm_pkg::*; - import otp_ctrl_env_pkg::*; - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; - import cip_base_pkg::*; - - // Output from DUT - otp_broadcast_t otp_broadcast_o; - otp_keymgr_key_t keymgr_key_o; - otp_lc_data_t lc_data_o; - logic pwr_otp_done_o, pwr_otp_idle_o; - - // Inputs to DUT - logic pwr_otp_init_i, scan_en_i, scan_rst_ni, ext_voltage_h_io; - lc_ctrl_pkg::lc_tx_t lc_dft_en_i, lc_escalate_en_i, lc_check_byp_en_i, - lc_creator_seed_sw_rw_en_i, lc_owner_seed_sw_rw_en_i, - lc_seed_hw_rd_en_i; - prim_mubi_pkg::mubi4_t scanmode_i; - otp_ast_rsp_t otp_ast_pwr_seq_h_i; - ast_pkg::ast_obs_ctrl_t obs_ctrl_i; - - // Unused in prim_generic_otp memory. - logic [OtpTestCtrlWidth-1:0] otp_vendor_test_ctrl_i; - logic [OtpTestStatusWidth-1:0] otp_vendor_test_status_o; - logic [OtpTestVectWidth-1:0] cio_test_o; - logic [OtpTestVectWidth-1:0] cio_test_en_o; - - // Connect with lc_prog push_pull interface. - logic lc_prog_req, lc_prog_err; - logic lc_prog_err_dly1, lc_prog_no_sta_check; - - // Connect push_pull interfaces ack signals for assertion checks. - logic otbn_ack, lc_prog_ack; - logic [1:0] flash_acks; - logic [NumSramKeyReqSlots-1:0] sram_acks; - - // Variables for internal interface logic. - // `lc_escalate_en` is async, take two clock cycles to synchronize. - lc_ctrl_pkg::lc_tx_t lc_esc_dly1, lc_esc_dly2; - - // Variable for scoreboard. - // For `lc_escalate_en`, any value that is not `Off` is a `On`. - bit lc_esc_on; - - // Probe design signal for alert request. - logic alert_reqs; - - // Usually the `lc_check_byp_en` will be automatically set to `On` when LC program request is - // issued, and stays `On` until reset is issued. - // Set this variable to 0 after a LC program request might cause otp checks to fail. - bit lc_check_byp_en = 1; - - // Internal veriable to track which sw partitions have ECC reg error. - bit [NumPartUnbuf-1:0] force_sw_parts_ecc_reg; - - // DUT configuration object - otp_ctrl_ast_inputs_cfg dut_cfg; - - // for DV macros ID - string msg_id = "otp_ctrl_if"; - - // Lc_err could trigger during LC program, so check intr and status after lc_req is finished. - // Lc_err takes one clock cycle to propogate to intr signal. So avoid intr check if it happens - // during the transition. - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - lc_prog_err_dly1 <= 0; - lc_esc_dly1 <= lc_ctrl_pkg::Off; - lc_esc_dly2 <= lc_ctrl_pkg::Off; - lc_check_byp_en_i <= get_rand_lc_tx_val(); - lc_esc_on <= 0; - end else begin - lc_prog_err_dly1 <= lc_prog_err; - lc_esc_dly1 <= lc_escalate_en_i; - lc_esc_dly2 <= lc_esc_dly1; - if (lc_prog_req) begin - lc_check_byp_en_i <= lc_check_byp_en ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; - end - if (lc_esc_dly2 != lc_ctrl_pkg::Off && !lc_esc_on) begin - lc_esc_on <= 1; - end - end - end - - assign lc_prog_no_sta_check = lc_prog_err | lc_prog_err_dly1 | lc_prog_req | lc_esc_on; - - function automatic void drive_pwr_otp_init(logic val); - pwr_otp_init_i = val; - endfunction - - function automatic void drive_ext_voltage_h_io(logic val); - ext_voltage_h_io = val; - endfunction - - function automatic void drive_lc_creator_seed_sw_rw_en(lc_ctrl_pkg::lc_tx_t val); - lc_creator_seed_sw_rw_en_i = val; - endfunction - - function automatic void drive_lc_owner_seed_sw_rw_en(lc_ctrl_pkg::lc_tx_t val); - lc_owner_seed_sw_rw_en_i = val; - endfunction - - function automatic void drive_lc_dft_en(lc_ctrl_pkg::lc_tx_t val); - lc_dft_en_i = val; - endfunction - - function automatic void drive_lc_escalate_en(lc_ctrl_pkg::lc_tx_t val); - lc_escalate_en_i = val; - endfunction - - function automatic void drive_lc_seed_hw_rd_en(lc_ctrl_pkg::lc_tx_t val); - lc_seed_hw_rd_en_i = val; - endfunction - - function automatic bit under_error_states(); - return lc_esc_on | alert_reqs; - endfunction - - // SW partitions do not have any internal checks. - // Here we force internal ECC check to fail. - task automatic force_sw_check_fail( - bit[NumPartUnbuf-1:0] fail_idx = $urandom_range(1, (1'b1 << NumPartUnbuf) - 1)); - @(posedge clk_i); - if (fail_idx[VendorTestIdx]) begin - force tb.dut.gen_partitions[VendorTestIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[VendorTestIdx] = 1; - end - if (fail_idx[CreatorSwCfgIdx]) begin - force tb.dut.gen_partitions[CreatorSwCfgIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[CreatorSwCfgIdx] = 1; - end - if (fail_idx[OwnerSwCfgIdx]) begin - force tb.dut.gen_partitions[OwnerSwCfgIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[OwnerSwCfgIdx] = 1; - end - if (fail_idx[RotCreatorAuthCodesignIdx]) begin - force tb.dut.gen_partitions[RotCreatorAuthCodesignIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[RotCreatorAuthCodesignIdx] = 1; - end - if (fail_idx[RotCreatorAuthStateIdx]) begin - force tb.dut.gen_partitions[RotCreatorAuthStateIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0] = 1; - force_sw_parts_ecc_reg[RotCreatorAuthStateIdx] = 1; - end - endtask - - task automatic release_sw_check_fail(); - @(posedge clk_i); - if (force_sw_parts_ecc_reg[VendorTestIdx]) begin - release tb.dut.gen_partitions[VendorTestIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[VendorTestIdx] = 0; - end - if (force_sw_parts_ecc_reg[CreatorSwCfgIdx]) begin - release tb.dut.gen_partitions[CreatorSwCfgIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[CreatorSwCfgIdx] = 0; - end - if (force_sw_parts_ecc_reg[OwnerSwCfgIdx]) begin - release tb.dut.gen_partitions[OwnerSwCfgIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[OwnerSwCfgIdx] = 0; - end - if (force_sw_parts_ecc_reg[RotCreatorAuthCodesignIdx]) begin - release tb.dut.gen_partitions[RotCreatorAuthCodesignIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[RotCreatorAuthCodesignIdx] = 0; - end - if (force_sw_parts_ecc_reg[RotCreatorAuthStateIdx]) begin - release tb.dut.gen_partitions[RotCreatorAuthStateIdx].gen_unbuffered. - u_part_unbuf.`ECC_REG_PATH.data_i[0]; - force_sw_parts_ecc_reg[RotCreatorAuthStateIdx] = 0; - end - endtask - - // Force prim_generic_otp input cmd_i to a invalid value. - task automatic force_invalid_otp_cmd_i(); - @(posedge clk_i); - force `PRIM_GENERIC_OTP_CMD_I_PATH = prim_otp_pkg::cmd_e'(2'b10); - endtask - - task automatic release_invalid_otp_cmd_i(); - @(posedge clk_i); - release `PRIM_GENERIC_OTP_CMD_I_PATH; - endtask - - // Force part_buf partitions output otp_cmd_o to a invalid value. - task automatic force_invalid_part_cmd_o(int part_idx); - @(posedge clk_i); - case (part_idx) - HwCfg0Idx: force `BUF_PART_OTP_CMD_PATH(HwCfg0Idx) = prim_otp_pkg::cmd_e'(2'b10); - HwCfg1Idx: force `BUF_PART_OTP_CMD_PATH(HwCfg1Idx) = prim_otp_pkg::cmd_e'(2'b10); - Secret0Idx: force `BUF_PART_OTP_CMD_PATH(Secret0Idx) = prim_otp_pkg::cmd_e'(2'b10); - Secret1Idx: force `BUF_PART_OTP_CMD_PATH(Secret1Idx) = prim_otp_pkg::cmd_e'(2'b10); - Secret2Idx: force `BUF_PART_OTP_CMD_PATH(Secret2Idx) = prim_otp_pkg::cmd_e'(2'b10); - LifeCycleIdx: force `LC_PART_OTP_CMD_PATH = prim_otp_pkg::cmd_e'(2'b10); - default: begin - `uvm_fatal("otp_ctrl_if", - $sformatf("force invalid otp_cmd_o only supports buffered partitions: %0d", part_idx)) - end - endcase - endtask - - task automatic release_invalid_part_cmd_o(int part_idx); - @(posedge clk_i); - case (part_idx) - HwCfg0Idx: release `BUF_PART_OTP_CMD_PATH(HwCfg0Idx); - HwCfg1Idx: release `BUF_PART_OTP_CMD_PATH(HwCfg1Idx); - Secret0Idx: release `BUF_PART_OTP_CMD_PATH(Secret0Idx); - Secret1Idx: release `BUF_PART_OTP_CMD_PATH(Secret1Idx); - Secret2Idx: release `BUF_PART_OTP_CMD_PATH(Secret2Idx); - LifeCycleIdx: release `LC_PART_OTP_CMD_PATH; - default: begin - `uvm_fatal("otp_ctrl_if", - $sformatf("release invalid otp_cmd_o only supports buffered partitions: %0d", - part_idx)) - end - endcase - endtask - - // This task forces otp_ctrl's internal mubi signals to values that are not mubi::true or mubi:: - // false. Then scb will check if design treats these values as locking the partition access. - task automatic force_part_access_mubi(otp_part_access_lock_t forced_part_access_sel[NumPart-1]); - @(posedge clk_i); - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(VendorTestIdx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(CreatorSwCfgIdx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(OwnerSwCfgIdx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(RotCreatorAuthCodesignIdx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(RotCreatorAuthStateIdx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(HwCfg0Idx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(HwCfg1Idx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(Secret0Idx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(Secret1Idx) - `FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL(Secret2Idx) - endtask - - task automatic release_part_access_mubi(); - @(posedge clk_i); - release tb.dut.part_access; - release tb.dut.part_access_dai; - endtask - - // Connectivity assertions for test related I/Os. - `ASSERT(LcOtpTestStatusO_A, otp_vendor_test_status_o == `PRIM_GENERIC_OTP_PATH.test_status_o) - `ASSERT(LcOtpTestCtrlI_A, otp_vendor_test_ctrl_i == `PRIM_GENERIC_OTP_PATH.test_ctrl_i) - - `ASSERT(CioTestOWithDftOn_A, lc_dft_en_i == lc_ctrl_pkg::On |-> - ##[2:3] cio_test_o == `PRIM_GENERIC_OTP_PATH.test_vect_o) - `ASSERT(CioTestOWithDftOff_A, lc_dft_en_i != lc_ctrl_pkg::On |-> ##[2:3] cio_test_o == 0) - `ASSERT(CioTestEnOWithDftOn_A, lc_dft_en_i == lc_ctrl_pkg::On |-> ##[2:3] cio_test_en_o == '1) - `ASSERT(CioTestEnOWithDftOff_A, lc_dft_en_i != lc_ctrl_pkg::On |-> ##[2:3] cio_test_en_o == 0) - - - `define OTP_ASSERT_WO_LC_ESC(NAME, SEQ) \ - `ASSERT(NAME, SEQ, clk_i, !rst_ni || lc_esc_on || alert_reqs) - - // If pwr_otp_idle is set only if pwr_otp init is done - `OTP_ASSERT_WO_LC_ESC(OtpPwrDoneWhenIdle_A, pwr_otp_idle_o |-> pwr_otp_done_o) - - // otp_broadcast_o is valid only when otp init is done - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgValidOn_A, pwr_otp_done_o |-> - otp_broadcast_o.valid == lc_ctrl_pkg::On) - // If otp_broadcast is Off, then hw partition is not finished calculation, - // then otp init is not done - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgValidOff_A, otp_broadcast_o.valid == lc_ctrl_pkg::Off |-> - pwr_otp_done_o == 0) - // Once OTP init is done, otp_broadcast_o output value stays stable until next power cycle - `OTP_ASSERT_WO_LC_ESC(OtpHwCfgStable_A, otp_broadcast_o.valid == lc_ctrl_pkg::On |=> - $stable(otp_broadcast_o)) - - // Otp_keymgr valid is related to part_digest, should not be changed after otp_pwr_init - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable0_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_root_key_share0_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable1_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_root_key_share1_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable2_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.creator_seed_valid)) - `OTP_ASSERT_WO_LC_ESC(OtpKeymgrValidStable3_A, pwr_otp_done_o |-> - $stable(keymgr_key_o.owner_seed_valid)) - - // During lc_prog_req, either otp_idle will be reset or lc_error is set - `OTP_ASSERT_WO_LC_ESC(LcProgReq_A, $rose(lc_prog_req) |=> - (pwr_otp_idle_o == 0 || $rose(lc_prog_err)) within lc_prog_req[*1:$]) - - // During fatal alert, check if otp outputs revert back to default value. - // Wait three clock cycles until error propogates to each FSM states and regs. - `define OTP_FATAL_ERR_ASSERT(NAME, SEQ) \ - `ASSERT(FatalErr``NAME``, alert_reqs |-> ##3 SEQ) - - `OTP_FATAL_ERR_ASSERT(LcDataValid_A, lc_data_o.valid == 0 && lc_data_o.error == 1) - `OTP_FATAL_ERR_ASSERT(LcDataState_A, lc_data_o.state == - PartInvDefault[LcStateOffset*8+:LcStateSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataCount_A, lc_data_o.count == - PartInvDefault[LcTransitionCntOffset*8+:LcTransitionCntSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataTestUnlockToken_A, lc_data_o.test_unlock_token == - PartInvDefault[TestUnlockTokenOffset*8+:TestUnlockTokenSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataTestExitToken_A, lc_data_o.test_exit_token == - PartInvDefault[TestExitTokenOffset*8+:TestExitTokenSize*8]) - `OTP_FATAL_ERR_ASSERT(LcDataRmaToken_A, lc_data_o.rma_token == - PartInvDefault[RmaTokenOffset*8+:RmaTokenSize*8]) - - `OTP_FATAL_ERR_ASSERT(KeymgrKeyData_A, keymgr_key_o.creator_root_key_share0 == - PartInvDefault[CreatorRootKeyShare0Offset*8+:CreatorRootKeyShare0Size*8] && - keymgr_key_o.creator_root_key_share1 == - PartInvDefault[CreatorRootKeyShare1Offset*8+:CreatorRootKeyShare1Size*8]) - - `OTP_FATAL_ERR_ASSERT(HwCfgOValid_A, otp_broadcast_o.valid == lc_ctrl_pkg::Off) - `OTP_FATAL_ERR_ASSERT(HwCfg0OData_A, otp_broadcast_o.hw_cfg0_data == - PartInvDefault[HwCfg0Offset*8+:HwCfg0Size*8]) - `OTP_FATAL_ERR_ASSERT(HwCfg1OData_A, otp_broadcast_o.hw_cfg1_data == - PartInvDefault[HwCfg1Offset*8+:HwCfg1Size*8]) - - `OTP_FATAL_ERR_ASSERT(LcProgAck_A, lc_prog_ack == 0) - `OTP_FATAL_ERR_ASSERT(FlashAcks_A, flash_acks == 0) - `OTP_FATAL_ERR_ASSERT(SramAcks_A, sram_acks == 0) - `OTP_FATAL_ERR_ASSERT(OtbnAck_A, otbn_ack == 0) - - `undef OTP_ASSERT_WO_LC_ESC - `undef OTP_FATAL_ERR_ASSERT - `undef ECC_REG_PATH - `undef BUF_PART_OTP_CMD_PATH - `undef LC_PART_OTP_CMD_PATH - `undef PRIM_GENERIC_OTP_PATH - `undef PRIM_GENERIC_OTP_CMD_I_PATH - `undef FORCE_OTP_PART_LOCK_WITH_RAND_NON_MUBI_VAL -endinterface diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv deleted file mode 100644 index 81dac97e9f5b4..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv +++ /dev/null @@ -1,1699 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -class otp_ctrl_scoreboard #(type CFG_T = otp_ctrl_env_cfg) - extends cip_base_scoreboard #( - .CFG_T(CFG_T), - .RAL_T(otp_ctrl_core_reg_block), - .COV_T(otp_ctrl_env_cov) - ); - `uvm_component_param_utils(otp_ctrl_scoreboard #(CFG_T)) - - // local variables - bit [TL_DW-1:0] otp_a [OTP_ARRAY_SIZE]; - - // lc_state and lc_cnt that stored in OTP - bit [LC_PROG_DATA_SIZE-1:0] otp_lc_data; - bit [EDN_BUS_WIDTH-1:0] edn_data_q[$]; - - // This flag is used when reset is issued during otp dai write access. - bit dai_wr_ip; - int dai_digest_ip = LifeCycleIdx; // Default to LC as it does not have digest. - bit ignore_digest_chk = 0; - - // This bit is used for DAI interface to mark if the read access is valid. - bit dai_read_valid; - - // This captures the regwen state as configured by the SW side (i.e. without HW modulation - // with the idle signal overlaid). - bit direct_access_regwen_state = 1; - - // ICEBOX(#17798): currently scb will skip checking the readout value if the ECC error is - // uncorrectable. Because if the error is uncorrectable, current scb does not track all the - // backdoor injected values. - // This issue proposes to track the otp_memory_array in mem_bkdr_if and once backdoor inject any - // value, mem_bkdr_if will update its otp_memory_array. - bit check_dai_rd_data = 1; - - // Status related variables - bit under_chk, under_dai_access; - bit [TL_DW-1:0] exp_status, status_mask; - - otp_alert_e exp_alert = OtpNoAlert; - - // TLM agent fifos - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(SRAM_DATA_SIZE))) - sram_fifos[NumSramKeyReqSlots]; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(OTBN_DATA_SIZE))) otbn_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE))) flash_addr_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE))) flash_data_fifo; - uvm_tlm_analysis_fifo #(push_pull_item#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE))) - lc_prog_fifo; - - // local queues to hold incoming packets pending comparison - - `uvm_component_new - - function void build_phase(uvm_phase phase); - super.build_phase(phase); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - sram_fifos[i] = new($sformatf("sram_fifos[%0d]", i), this); - end - otbn_fifo = new("otbn_fifo", this); - flash_addr_fifo = new("flash_addr_fifo", this); - flash_data_fifo = new("flash_data_fifo", this); - lc_prog_fifo = new("lc_prog_fifo", this); - endfunction - - function void connect_phase(uvm_phase phase); - super.connect_phase(phase); - endfunction - - task run_phase(uvm_phase phase); - super.run_phase(phase); - fork - process_wipe_mem(); - process_otp_power_up(); - process_lc_esc(); - process_lc_prog_req(); - process_edn_req(); - check_otbn_rsp(); - check_flash_rsps(); - check_sram_rsps(); - recover_lc_prog_req(); - join_none - endtask - - // Once sequence uses backdoor method to clear memory, this task resets internal otp_a and - // resets `cfg.backdoor_clear_mem` to 0. - virtual task process_wipe_mem(); - forever begin - @(posedge cfg.backdoor_clear_mem) begin - bit [SCRAMBLE_DATA_SIZE-1:0] data; - otp_a = '{default:0}; - otp_lc_data = '{default:0}; - // secret partitions have been scrambled before writing to OTP. - // here calculate the pre-srambled raw data when clearing internal OTP to all 0s. - data = descramble_data(0, Secret0Idx); - for (int i = Secret0Offset / TL_SIZE; - i <= Secret0DigestOffset / TL_SIZE - 1; - i++) begin - otp_a[i] = ((i - Secret0Offset / TL_SIZE) % 2) ? - data[SCRAMBLE_DATA_SIZE-1:TL_DW] : data[TL_DW-1:0]; - end - // secret partitions have been scrambled before writing to OTP. - // here calculate the pre-srambled raw data when clearing internal OTP to all 0s. - data = descramble_data(0, Secret1Idx); - for (int i = Secret1Offset / TL_SIZE; - i <= Secret1DigestOffset / TL_SIZE - 1; - i++) begin - otp_a[i] = ((i - Secret1Offset / TL_SIZE) % 2) ? - data[SCRAMBLE_DATA_SIZE-1:TL_DW] : data[TL_DW-1:0]; - end - // secret partitions have been scrambled before writing to OTP. - // here calculate the pre-srambled raw data when clearing internal OTP to all 0s. - data = descramble_data(0, Secret2Idx); - for (int i = Secret2Offset / TL_SIZE; - i <= Secret2DigestOffset / TL_SIZE - 1; - i++) begin - otp_a[i] = ((i - Secret2Offset / TL_SIZE) % 2) ? - data[SCRAMBLE_DATA_SIZE-1:TL_DW] : data[TL_DW-1:0]; - end - `uvm_info(`gfn, "clear internal memory and digest", UVM_HIGH) - cfg.backdoor_clear_mem = 0; - dai_wr_ip = 0; - dai_digest_ip = LifeCycleIdx; - end - end - endtask - - // This task process the following logic in during otp_power_up: - // 1. After reset deasserted, otp access is locked until pwr_otp_done_o is set - // 2. After reset deasserted, if power otp_init request is on, and if testbench uses backdoor to - // clear OTP memory to all zeros, clear all digests and re-calculate secret partitions - virtual task process_otp_power_up(); - forever begin - wait (cfg.en_scb); - @(posedge cfg.otp_ctrl_vif.pwr_otp_done_o || cfg.under_reset || - cfg.otp_ctrl_vif.alert_reqs) begin - if (!cfg.under_reset && !cfg.otp_ctrl_vif.alert_reqs && cfg.en_scb) begin - otp_ctrl_part_pkg::otp_hw_cfg0_data_t exp_hw_cfg0_data; - otp_ctrl_part_pkg::otp_hw_cfg1_data_t exp_hw_cfg1_data; - otp_ctrl_pkg::otp_keymgr_key_t exp_keymgr_data; - otp_ctrl_pkg::otp_lc_data_t exp_lc_data; - bit [otp_ctrl_pkg::KeyMgrKeyWidth-1:0] exp_keymgr_key0, exp_keymgr_key1; - - if (PartInfo[dai_digest_ip].sw_digest || PartInfo[dai_digest_ip].hw_digest) begin - bit [TL_DW-1:0] otp_addr = PART_OTP_DIGEST_ADDRS[dai_digest_ip]; - otp_a[otp_addr] = cfg.mem_bkdr_util_h.read32(otp_addr << 2); - otp_a[otp_addr+1] = cfg.mem_bkdr_util_h.read32((otp_addr << 2) + 4); - dai_digest_ip = LifeCycleIdx; - end - predict_digest_csrs(); - - if (cfg.otp_ctrl_vif.under_error_states() == 0) begin - // Dai access is unlocked because the power init is done - void'(ral.direct_access_regwen.predict(direct_access_regwen_state)); - - // Dai idle is set because the otp init is done - exp_status[OtpDaiIdleIdx] = 1; - end - - // Hwcfg_o gets data from OTP HW cfg partition - exp_hw_cfg0_data = cfg.otp_ctrl_vif.under_error_states() ? - otp_ctrl_part_pkg::PartInvDefault[HwCfg0Offset*8 +: HwCfg0Size*8] : - otp_hw_cfg0_data_t'({<<32 {otp_a[HwCfg0Offset/4 +: HwCfg0Size/4]}}); - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.valid, lc_ctrl_pkg::On) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.hw_cfg0_data, exp_hw_cfg0_data) - - // Hwcfg_o gets data from OTP HW cfg partition - exp_hw_cfg1_data = cfg.otp_ctrl_vif.under_error_states() ? - otp_ctrl_part_pkg::PartInvDefault[HwCfg1Offset*8 +: HwCfg1Size*8] : - otp_hw_cfg1_data_t'({<<32 {otp_a[HwCfg1Offset/4 +: HwCfg1Size/4]}}); - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.valid, lc_ctrl_pkg::On) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.otp_broadcast_o.hw_cfg1_data, exp_hw_cfg1_data) - - if (!cfg.otp_ctrl_vif.under_error_states()) begin - // ---------------------- Check lc_data_o output ----------------------------------- - // Because initialization was succesful, the valid should be set and error should be - // reset. - exp_lc_data.valid = 1; - exp_lc_data.error = 0; - - // Secrets and tokens valid signals are depend on whether secret partitions are - // locked. - exp_lc_data.secrets_valid = get_otp_digest_val(Secret2Idx) ? On : Off; - exp_lc_data.test_tokens_valid = get_otp_digest_val(Secret0Idx) ? On : Off; - exp_lc_data.rma_token_valid = get_otp_digest_val(Secret2Idx) ? On : Off; - - // LC output is depend on LC partitions value. - exp_lc_data.count = otp_lc_data[0 +: LcCountWidth]; - exp_lc_data.state = otp_lc_data[LcCountWidth +: LcStateWidth]; - - // Token values are depend on secret partitions value. - exp_lc_data.test_unlock_token = - {<<32 {otp_a[TestUnlockTokenOffset/4 +: TestUnlockTokenSize/4]}}; - exp_lc_data.test_exit_token = - {<<32 {otp_a[TestExitTokenOffset/4 +: TestExitTokenSize/4]}}; - exp_lc_data.rma_token = {<<32 {otp_a[RmaTokenOffset/4 +: RmaTokenSize/4]}}; - - // Check otp_lc_data_t struct by item is easier to debug. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.valid, exp_lc_data.valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.error, exp_lc_data.error) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.state, exp_lc_data.state) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.count, exp_lc_data.count) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.secrets_valid, exp_lc_data.secrets_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_tokens_valid, - exp_lc_data.test_tokens_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_unlock_token, - exp_lc_data.test_unlock_token) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.test_exit_token, exp_lc_data.test_exit_token) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.rma_token_valid, exp_lc_data.rma_token_valid) - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o.rma_token, exp_lc_data.rma_token) - - // Check otp_lc_data_t all together in case there is any missed item. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.lc_data_o, exp_lc_data) - - // ---------------------- Check keymgr_key_o output --------------------------------- - // Otp_keymgr outputs creator and owner keys from secret partitions. - // Depends on lc_seed_hw_rd_en_i, it will output the real keys or a constant - exp_keymgr_data = '0; - exp_keymgr_data.creator_root_key_share0_valid = get_otp_digest_val(Secret2Idx) != 0; - if (cfg.otp_ctrl_vif.lc_seed_hw_rd_en_i == lc_ctrl_pkg::On) begin - exp_keymgr_data.creator_root_key_share0 = - {<<32 {otp_a[CreatorRootKeyShare0Offset/4 +: CreatorRootKeyShare0Size/4]}}; - end else begin - exp_keymgr_data.creator_root_key_share0 = - PartInvDefault[CreatorRootKeyShare0Offset*8 +: CreatorRootKeyShare0Size*8]; - end - // Check otp_keymgr_key_t struct by item is easier to debug. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.keymgr_key_o.creator_root_key_share0_valid, - exp_keymgr_data.creator_root_key_share0_valid) - exp_keymgr_data.creator_root_key_share1_valid = get_otp_digest_val(Secret2Idx) != 0; - if (cfg.otp_ctrl_vif.lc_seed_hw_rd_en_i == lc_ctrl_pkg::On) begin - exp_keymgr_data.creator_root_key_share1 = - {<<32 {otp_a[CreatorRootKeyShare1Offset/4 +: CreatorRootKeyShare1Size/4]}}; - end else begin - exp_keymgr_data.creator_root_key_share1 = - PartInvDefault[CreatorRootKeyShare1Offset*8 +: CreatorRootKeyShare1Size*8]; - end - // Check otp_keymgr_key_t struct by item is easier to debug. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.keymgr_key_o.creator_root_key_share1_valid, - exp_keymgr_data.creator_root_key_share1_valid) - - // Check otp_keymgr_key_t struct all together in case there is any missed item. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.keymgr_key_o, exp_keymgr_data) - - if (cfg.en_cov) begin - cov.keymgr_o_cg.sample(cfg.otp_ctrl_vif.lc_seed_hw_rd_en_i == lc_ctrl_pkg::On, - exp_keymgr_data.creator_root_key_share0_valid); - end - end - end else if (cfg.otp_ctrl_vif.alert_reqs) begin - // Ignore digest CSR check when otp_ctrl initialization is interrupted by fatal errors. - // SCB cannot predict how many partitions already finished initialization and updated - // the digest value to CSRs. - ignore_digest_chk = 1; - end - if (cfg.en_cov) begin - bit [NumPart-2:0] parts_locked; - foreach (parts_locked[i]) parts_locked[i] = (get_otp_digest_val(i) != 0); - cov.power_on_cg.sample(cfg.otp_ctrl_vif.lc_esc_on, parts_locked); - end - end - end - endtask - - // This task monitors internal escalation triggered by two methods: - // 1. Externally lc_escalation_en is set to lc_ctrl_pkg::On. - // 2. Internal fatal alert triggered and all partitions are driven to error states. - virtual task process_lc_esc(); - forever begin - wait(cfg.otp_ctrl_vif.alert_reqs == 1 && cfg.en_scb); - - if (cfg.otp_ctrl_vif.lc_esc_on == 0) `DV_CHECK_NE(exp_alert, OtpNoAlert) - - if (exp_alert != OtpCheckAlert) set_exp_alert("fatal_check_error", 1, 5); - - // If the lc_escalation is triggered by internal fatal alert, wait 2 negedge until status is - // updated internally - if (cfg.otp_ctrl_vif.lc_esc_on == 0) begin - cfg.clk_rst_vif.wait_n_clks(2); - exp_status[OtpCheckPendingIdx] = 0; - exp_status[OtpDaiIdleIdx] = 0; - end else begin - exp_status = '0; - // Only lc_esc_on will set these bits to 1. - exp_status[OtpDerivKeyFsmErrIdx:OtpLfsrFsmErrIdx] = '1; - end - - // Update status bits. - foreach (FATAL_EXP_STATUS[i]) begin - if (FATAL_EXP_STATUS[i]) begin - predict_err(.status_err_idx(otp_status_e'(i)), .err_code(OtpFsmStateError), - .update_esc_err(1)); - end - end - - // Update digest values and direct_access_regwen. - predict_rdata(1, 0, 0); - void'(ral.direct_access_regwen.predict(.value(0), .kind(UVM_PREDICT_READ))); - - // DAI access is locked until reset, so no need to backdoor read otp write value until reset. - - wait(cfg.otp_ctrl_vif.alert_reqs == 0); - end - endtask - - // This task monitors if lc_program req is interrupted by reset. - // If it happens, scb cannot predict how many bits have been written to OTP_CTRL. - // So here we will backdoor read back OTP lc partitions bits. - virtual task recover_lc_prog_req(); - forever begin - wait(cfg.otp_ctrl_vif.lc_prog_req == 1); - wait(cfg.otp_ctrl_vif.lc_prog_req == 0); - // Wait one 1ps to avoid race condition. - #1ps; - if (cfg.otp_ctrl_vif.rst_ni == 0) begin - for (int i = 0; i < LC_PROG_DATA_SIZE/32; i++) begin - otp_lc_data[i*32+:32] = cfg.mem_bkdr_util_h.read32(LifeCycleOffset + i * 4); - end - end - end - endtask - - virtual task process_lc_prog_req(); - forever begin - push_pull_item#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE)) rcv_item; - bit exp_err_bit; - bit [15:0] rcv_words [LC_PROG_DATA_SIZE/16]; - - lc_prog_fifo.get(rcv_item); - - // LCI is updated by OTP word. - rcv_words = {<< 16{rcv_item.h_data}}; - foreach (rcv_words[i]) begin - bit [15:0] curr_word = otp_lc_data[i*16 +: 16]; - if ((curr_word & rcv_words[i]) == curr_word) otp_lc_data[i*16 +: 16] = rcv_words[i]; - else exp_err_bit = 1; - end - - if (exp_err_bit) predict_err(OtpLciErrIdx, OtpMacroWriteBlankError); - else predict_no_err(OtpLciErrIdx); - - // LC program request data is valid means no OTP macro error. - `DV_CHECK_EQ(rcv_item.d_data, exp_err_bit) - - if (cfg.en_cov) cov.lc_prog_cg.sample(exp_err_bit); - end - endtask - - virtual task process_edn_req(); - forever begin - push_pull_item#(.DeviceDataWidth(EDN_DATA_WIDTH)) edn_item; - edn_fifos[0].get(edn_item); - edn_data_q.push_back(edn_item.d_data[EDN_BUS_WIDTH-1:0]); - end - endtask - - virtual task check_otbn_rsp(); - forever begin - push_pull_item#(.DeviceDataWidth(OTBN_DATA_SIZE)) rcv_item; - bit [SCRAMBLE_KEY_SIZE-1:0] edn_key2, edn_key1; - bit [SCRAMBLE_KEY_SIZE-1:0] sram_key; - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - bit [OtbnKeyWidth-1:0] key, exp_key; - bit [OtbnNonceWidth-1:0] nonce, exp_nonce; - bit seed_valid; - bit part_locked; - - otbn_fifo.get(rcv_item); - seed_valid = rcv_item.d_data[0]; - nonce = rcv_item.d_data[1+:OtbnNonceWidth]; - key = rcv_item.d_data[OtbnNonceWidth+1+:OtbnKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - - // seed is valid as long as secret1 is locked - `DV_CHECK_EQ(seed_valid, part_locked, "otbn seed_valid mismatch") - - // If edn_data_q matches the OTBN requested size, check OTBN outputs - if (edn_data_q.size() == NUM_OTBN_EDN_REQ) begin - {exp_nonce, edn_key2, edn_key1} = {<<32{edn_data_q}}; - - // check nonce value - `DV_CHECK_EQ(nonce, exp_nonce, "otbn nonce mismatch") - - // calculate key - sram_key = get_key_from_otp(part_locked, SramDataKeySeedOffset / 4); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key1), - .num_round(2)); - - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key2), - .num_round(2)); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, "otbn key mismatch") - - if (cfg.en_cov) cov.otbn_req_cg.sample(part_locked); - - // If during OTBN key request, the LFSR timer expired and trigger an EDN request to acquire - // two EDN keys, then ignore the OTBN output checking, because scb did not know which EDN - // keys are used for LFSR. - // Thus any edn_data_q size equal to (16+2*N) is exempted from checking. - end else if ((edn_data_q.size() - NUM_OTBN_EDN_REQ) % 2 != 0) begin - `uvm_error(`gfn, $sformatf("Unexpected edn_data_q size (%0d) during OTBN request", - edn_data_q.size())) - end - edn_data_q.delete(); - end - endtask - - virtual task check_flash_rsps(); - for (int i = FlashDataKey; i <= FlashAddrKey; i++) begin - automatic digest_sel_e sel_flash = digest_sel_e'(i); - fork - forever begin - push_pull_item#(.DeviceDataWidth(FLASH_DATA_SIZE)) rcv_item; - bit [SCRAMBLE_KEY_SIZE-1:0] flash_key; - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - bit [FlashKeyWidth-1:0] key, exp_key; - bit seed_valid, part_locked; - int flash_key_index; - - if (sel_flash == FlashAddrKey) begin - flash_addr_fifo.get(rcv_item); - flash_key_index = FlashAddrKeySeedOffset / 4; - end else begin - flash_data_fifo.get(rcv_item); - flash_key_index = FlashDataKeySeedOffset / 4; - end - seed_valid = rcv_item.d_data[0]; - key = rcv_item.d_data[1+:FlashKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - `DV_CHECK_EQ(seed_valid, part_locked, - $sformatf("flash %0s seed_valid mismatch", sel_flash.name())) - - // calculate key - flash_key = get_key_from_otp(part_locked, flash_key_index); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[sel_flash]), - .key(flash_key), - .final_const(RndCnstDigestConst[sel_flash])); - - flash_key = get_key_from_otp(part_locked, flash_key_index + 4); - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[sel_flash]), - .key(flash_key), - .final_const(RndCnstDigestConst[sel_flash])); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, $sformatf("flash %s key mismatch", sel_flash.name())) - - if (cfg.en_cov) cov.flash_req_cg.sample(sel_flash, part_locked); - end - join_none; - end - endtask - - virtual task check_sram_rsps(); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - automatic int index = i; - fork - forever begin - push_pull_item#(.DeviceDataWidth(SRAM_DATA_SIZE)) rcv_item; - sram_key_t key, exp_key; - sram_nonce_t nonce, exp_nonce; - bit seed_valid, part_locked; - bit [SCRAMBLE_KEY_SIZE-1:0] edn_key2, edn_key1; - bit [SCRAMBLE_KEY_SIZE-1:0] sram_key; // key used as input to present algo - bit [SCRAMBLE_DATA_SIZE-1:0] exp_key_lower, exp_key_higher; - - sram_fifos[index].get(rcv_item); - seed_valid = rcv_item.d_data[0]; - nonce = rcv_item.d_data[1+:SramNonceWidth]; - key = rcv_item.d_data[SramNonceWidth+1+:SramKeyWidth]; - part_locked = {`gmv(ral.secret1_digest[0]), `gmv(ral.secret1_digest[1])} != '0; - - // seed is valid as long as secret1 is locked - `DV_CHECK_EQ(seed_valid, part_locked, $sformatf("sram_%0d seed_valid mismatch", index)) - - // If edn_data_q matches the OTBN requested size, check OTBN outputs - if (edn_data_q.size() == NUM_SRAM_EDN_REQ) begin - {exp_nonce, edn_key2, edn_key1} = {<<32{edn_data_q}}; - - // check nonce value - `DV_CHECK_EQ(nonce, exp_nonce, $sformatf("sram_%0d nonce mismatch", index)) - - // calculate key - sram_key = get_key_from_otp(part_locked, SramDataKeySeedOffset / 4); - exp_key_lower = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key1), - .num_round(2)); - - exp_key_higher = present_encode_with_final_const( - .data(RndCnstDigestIV[SramDataKey]), - .key(sram_key), - .final_const(RndCnstDigestConst[SramDataKey]), - .second_key(edn_key2), - .num_round(2)); - exp_key = {exp_key_higher, exp_key_lower}; - `DV_CHECK_EQ(key, exp_key, $sformatf("sram_%0d key mismatch", index)) - if (cfg.en_cov) cov.sram_req_cg.sample(index, part_locked); - - end else if ((edn_data_q.size() - NUM_SRAM_EDN_REQ) % 2 != 0) begin - `uvm_error(`gfn, $sformatf("Unexpected edn_data_q size (%0d) during SRAM request", - edn_data_q.size())) - end - edn_data_q.delete(); - end - join_none - end - endtask - - virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); - bit write = item.is_write(); - uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - bit [TL_AW-1:0] addr_mask = ral.get_addr_mask(); - - bit addr_phase_read = (!write && channel == AddrChannel); - bit addr_phase_write = (write && channel == AddrChannel); - bit data_phase_read = (!write && channel == DataChannel); - bit data_phase_write = (write && channel == DataChannel); - - if (ral_name != "otp_ctrl_prim_reg_block") begin - process_core_tl_access(item, csr_addr, ral_name, addr_mask, - addr_phase_read, addr_phase_write, data_phase_read, data_phase_write); - end else begin - process_prim_tl_access(item, csr_addr, ral_name, addr_phase_write, data_phase_read); - end - endtask - - virtual function void process_prim_tl_access(tl_seq_item item, uvm_reg_addr_t csr_addr, - string ral_name, bit addr_phase_write, bit data_phase_read); - - uvm_reg csr; - dv_base_reg dv_reg; - csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr); - `DV_CHECK_NE_FATAL(csr, null) - `downcast(dv_reg, csr) - - if (addr_phase_write) begin - void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); - end else if (data_phase_read) begin - `DV_CHECK_EQ((csr.get_mirrored_value() | status_mask), (item.d_data | status_mask), - $sformatf("reg name: status, compare_mask %0h", status_mask)) - end - endfunction - - virtual function void process_core_tl_access(tl_seq_item item, uvm_reg_addr_t csr_addr, - string ral_name, bit [TL_AW-1:0] addr_mask, bit addr_phase_read, bit addr_phase_write, - bit data_phase_read, bit data_phase_write); - - bit do_read_check = 1; - uvm_reg csr; - dv_base_reg dv_reg; - string csr_name; - - `uvm_info(`gfn, $sformatf("sw state %d, reg state %d", direct_access_regwen_state, - `gmv(ral.direct_access_regwen)), UVM_LOW); - - // if access was to a valid csr, get the csr handle - if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin - csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr); - `DV_CHECK_NE_FATAL(csr, null) - `downcast(dv_reg, csr) - // SW CFG window - end else if ((csr_addr & addr_mask) inside - {[SW_WINDOW_BASE_ADDR : SW_WINDOW_BASE_ADDR + SW_WINDOW_SIZE]}) begin - if (data_phase_read) begin - bit [TL_AW-1:0] dai_addr = (csr_addr & addr_mask - SW_WINDOW_BASE_ADDR); - bit [TL_AW-1:0] otp_addr = dai_addr >> 2; - int part_idx = get_part_index(dai_addr); - bit [TL_DW-1:0] read_out; - int ecc_err = OtpNoEccErr; - - // We can't get an ECC error if the partition does not have integrity. - if (part_has_integrity(part_idx)) begin - ecc_err = read_a_word_with_ecc(dai_addr, read_out); - end else begin - ecc_err = read_a_word_with_ecc_raw(dai_addr, read_out); - end - - if (part_has_digest(part_idx) && cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[part_idx].sample(.read_lock(0), - .write_lock(get_digest_reg_val(part_idx) != 0), .is_write(0)); - end - - // Any alert that indicates the OTP block is in the final error state should not enter the - // logic here, but gated at `is_tl_mem_access_allowed` function. - `DV_CHECK_EQ(cfg.otp_ctrl_vif.alert_reqs, 0) - - // ECC uncorrectable errors are gated by `is_tl_mem_access_allowed` function. - if (ecc_err != OtpNoEccErr && part_has_integrity(part_idx)) begin - - predict_err(otp_status_e'(part_idx), OtpMacroEccCorrError); - if (ecc_err == OtpEccCorrErr) begin - `DV_CHECK_EQ(item.d_data, otp_a[otp_addr], - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - end else begin - // Only check the first 16 bits because if ECC readout detects uncorrectable error, it - // won't continue read the remaining 16 bits. - `DV_CHECK_EQ(item.d_data & 16'hffff, read_out & 16'hffff, - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - end - // If there is an injected error, but the partition cannot detect it, we have to compare - // to the value read via the backdoor instead of otp_a[otp_addr] since otherwise the - // perturbed value does not get modelled correctly. - end else if (ecc_err != OtpNoEccErr && !part_has_integrity(part_idx)) begin - `DV_CHECK_EQ(item.d_data, read_out, - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - predict_no_err(otp_status_e'(part_idx)); - end else if (ecc_err == OtpNoEccErr) begin - `DV_CHECK_EQ(item.d_data, otp_a[otp_addr], - $sformatf("mem read mismatch at TLUL addr %0h, csr_addr %0h", - csr_addr, dai_addr)) - predict_no_err(otp_status_e'(part_idx)); - end - end - return; - end else begin - `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr)) - end - - csr_name = csr.get_name(); - - if (addr_phase_write) begin - if (cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs && csr_name == "direct_access_cmd") begin - cov.req_dai_access_after_alert_cg.sample(item.a_data); - end - - // Skip predict if the register is locked by `direct_access_regwen`. - // An exception is the direct_access_regwen which may always be written. - if (ral.direct_access_regwen.locks_reg_or_fld(dv_reg) && - `gmv(ral.direct_access_regwen) == 0 && - csr_name != "direct_access_regwen") return; - - void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); - end - - // process the csr req - // for write, update local variable and fifo at address phase - // for read, update predication at address phase and compare at data phase - case (csr_name) - // add individual case item for each csr - "intr_state": begin - if (data_phase_read) begin - // Disable intr_state checking when lc_program is in progress, because scb cannot - // accurately predict when program_error will be triggered. - // We will check the intr_state after lc_program request is done, and the error bit will - // be checked in the `process_lc_prog_req` task. - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check) do_read_check = 0; - if (do_read_check) begin - bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); - bit [NumOtpCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state); - - foreach (intr_exp[i]) begin - otp_intr_e intr = otp_intr_e'(i); - `DV_CHECK_CASE_EQ(cfg.intr_vif.pins[i], (intr_en[i] & intr_exp[i]), - $sformatf("Interrupt_pin: %0s", intr.name)); - if (cfg.en_cov) begin - cov.intr_cg.sample(i, intr_en[i], item.d_data[i]); - cov.intr_pins_cg.sample(i, cfg.intr_vif.pins[i]); - end - end - end - end - end - "intr_test": begin - if (addr_phase_write) begin - bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); - bit [NumOtpCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state) | item.a_data; - - void'(ral.intr_state.predict(.value(intr_exp))); - if (cfg.en_cov) begin - foreach (intr_exp[i]) begin - cov.intr_test_cg.sample(i, item.a_data[i], intr_en[i], intr_exp[i]); - end - end - end - end - "direct_access_cmd": begin - if (addr_phase_write && !cfg.otp_ctrl_vif.under_error_states()) begin - // here only normalize to 2 lsb, if is secret, will be reduced further - bit [TL_AW-1:0] dai_addr = normalize_dai_addr(`gmv(ral.direct_access_address)); - int part_idx = get_part_index(dai_addr); - bit sw_read_lock = 0; - void'(ral.direct_access_regwen.predict(0)); - under_dai_access = 1; - - // Check if it is sw partition read lock - this can be used in `DaiRead` branch and also - // coverage collection. - if (part_idx == VendorTestIdx) begin - sw_read_lock = `gmv(ral.vendor_test_read_lock) == 0; - end else if (part_idx == CreatorSwCfgIdx) begin - sw_read_lock = `gmv(ral.creator_sw_cfg_read_lock) == 0; - end else if (part_idx == OwnerSwCfgIdx) begin - sw_read_lock = `gmv(ral.owner_sw_cfg_read_lock) == 0; - end else if (part_idx == RotCreatorAuthCodesignIdx) begin - sw_read_lock = `gmv(ral.rot_creator_auth_codesign_read_lock) == 0; - end else if (part_idx == RotCreatorAuthStateIdx) begin - sw_read_lock = `gmv(ral.rot_creator_auth_state_read_lock) == 0; - end - - // LC partition cannot be access via DAI - if (part_idx == LifeCycleIdx) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - if (item.a_data == DaiRead) predict_rdata(is_secret(dai_addr), 0, 0); - end else begin - // Collect coverage. - if (cfg.en_cov) begin - if (part_idx == Secret2Idx) begin - cov.dai_access_secret2_cg.sample( - !(cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On), - dai_cmd_e'(item.a_data)); - end else if (is_sw_part_idx(part_idx) && part_has_digest(part_idx) && - item.a_data inside {DaiRead, DaiWrite}) begin - cov.unbuf_access_lock_cg_wrap[part_idx].sample(.read_lock(sw_read_lock), - .write_lock(get_digest_reg_val(part_idx) != 0), - .is_write(item.a_data == DaiWrite)); - - end - end - - case (item.a_data) - DaiDigest: cal_digest_val(part_idx); - DaiRead: begin - // Check if it is sw partition read lock - check_dai_rd_data = 1; - - // SW partitions write read_lock_csr can lock read access. - if (sw_read_lock || - // Secret partitions cal digest can also lock read access. - // However, digest is always readable except SW partitions (Issue #5752). - (is_secret(dai_addr) && get_digest_reg_val(part_idx) != 0 && - !is_digest(dai_addr)) || - // If the partition has creator key material and lc_creator_seed_sw_rw is - // disable, then return access error. - (PartInfo[part_idx].iskeymgr_creator && !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), 0, 0); - end else if (sw_read_lock || - // Secret partitions cal digest can also lock read access. - // However, digest is always readable except SW partitions (Issue #5752). - (is_secret(dai_addr) && get_digest_reg_val(part_idx) != 0 && - !is_digest(dai_addr)) || - // If the partition has owner key material and lc_owner_seed_sw_rw is disable, - // then return access error. - (PartInfo[part_idx].iskeymgr_owner && !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), 0, 0); - - end else begin - bit [TL_DW-1:0] read_out0, read_out1; - bit [TL_AW-1:0] otp_addr = get_scb_otp_addr(); - int ecc_err = 0; - - // Backdoor read to check if there is any ECC error. - if (part_has_integrity(part_idx)) begin - ecc_err = read_a_word_with_ecc(dai_addr, read_out0); - if (is_secret(dai_addr) || is_digest(dai_addr)) begin - ecc_err = max2(read_a_word_with_ecc(dai_addr + 4, read_out1), ecc_err); - end - end else begin - ecc_err = read_a_word_with_ecc_raw(dai_addr, read_out0); - if (is_secret(dai_addr) || is_digest(dai_addr)) begin - ecc_err = max2(read_a_word_with_ecc_raw(dai_addr + 4, read_out1), ecc_err); - end - end - - if (ecc_err == OtpEccCorrErr && part_has_integrity(part_idx)) begin - predict_err(OtpDaiErrIdx, OtpMacroEccCorrError); - backdoor_update_otp_array(dai_addr); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - otp_a[otp_addr], otp_a[otp_addr+1]); - end else if (ecc_err == OtpEccUncorrErr && part_has_integrity(part_idx)) begin - predict_err(OtpDaiErrIdx, OtpMacroEccUncorrError); - // Max wait 20 clock cycles because scb did not know when exactly OTP will - // finish reading and reporting the uncorrectable error. - set_exp_alert("fatal_macro_error", 1, 20); - predict_rdata(1, 0, 0); - // Some partitions do not interpret/report ECC errors. In those cases - // we still need to model the read data correctly if it has been perturbed. - end else if (ecc_err inside {OtpEccCorrErr, OtpEccUncorrErr} && - !part_has_integrity(part_idx)) begin - predict_no_err(OtpDaiErrIdx); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - read_out0, read_out1); - // do not check direct_access_rdata_* on ECC errors in - // non-integrity partitions - check_dai_rd_data = 0; - end else begin - predict_no_err(OtpDaiErrIdx); - predict_rdata(is_secret(dai_addr) || is_digest(dai_addr), - otp_a[otp_addr], otp_a[otp_addr+1]); - end - end - end - DaiWrite: begin - bit[TL_AW-1:0] otp_addr = get_scb_otp_addr(); - bit is_write_locked; - // check if write locked - if (part_has_digest(part_idx)) begin - is_write_locked = get_digest_reg_val(part_idx) != 0; - end else begin - is_write_locked = 0; - end - - if (is_write_locked || (PartInfo[part_idx].iskeymgr_creator && - !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - end else if (is_write_locked || (PartInfo[part_idx].iskeymgr_owner && - !is_digest(dai_addr) && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - end else begin - predict_no_err(OtpDaiErrIdx); - // write digest - if (is_sw_digest(dai_addr)) begin - bit [TL_DW*2-1:0] curr_digest, prev_digest; - curr_digest = {`gmv(ral.direct_access_wdata[1]), - `gmv(ral.direct_access_wdata[0])}; - prev_digest = {otp_a[otp_addr+1], otp_a[otp_addr]}; - dai_wr_ip = 1; - // allow bit write - if ((prev_digest & curr_digest) == prev_digest) begin - update_digest_to_otp(part_idx, curr_digest); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end else if (is_digest(dai_addr)) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - // write OTP memory - end else begin - dai_wr_ip = 1; - if (!is_secret(dai_addr)) begin - bit [TL_DW-1:0] wr_data = `gmv(ral.direct_access_wdata[0]); - // allow bit write - if ((otp_a[otp_addr] & wr_data) == otp_a[otp_addr]) begin - otp_a[otp_addr] = wr_data; - check_otp_idle(.val(0), .wait_clks(3)); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end else begin - bit [SCRAMBLE_DATA_SIZE-1:0] secret_data = {otp_a[otp_addr + 1], - otp_a[otp_addr]}; - bit [SCRAMBLE_DATA_SIZE-1:0] wr_data = {`gmv(ral.direct_access_wdata[1]), - `gmv(ral.direct_access_wdata[0])}; - wr_data = scramble_data(wr_data, part_idx); - secret_data = scramble_data(secret_data, part_idx); - if ((secret_data & wr_data) == secret_data) begin - otp_a[otp_addr] = `gmv(ral.direct_access_wdata[0]); - otp_a[otp_addr + 1] = `gmv(ral.direct_access_wdata[1]); - // wait until secret scrambling is done - check_otp_idle(.val(0), .wait_clks(34)); - end else begin - predict_err(OtpDaiErrIdx, OtpMacroWriteBlankError); - end - end - end - end - end - default: begin - `uvm_fatal(`gfn, $sformatf("invalid cmd: %0d", item.a_data)) - end - endcase - // regwen is set to 0 only if the dai operation is successfully - if (`gmv(ral.intr_state.otp_error) == 0) void'(ral.direct_access_regwen.predict(0)); - end - end - end - "status": begin - if (addr_phase_read) begin - void'(ral.status.predict(.value(exp_status), .kind(UVM_PREDICT_READ))); - - // update status mask - status_mask = 0; - // Mask out check_pending field - we do not know how long it takes to process checks. - // Check failure can trigger all kinds of errors. - if (under_chk) status_mask = '1; - - // Mask out otp_dai access related field - we do not know how long it takes to finish - // DAI access. - if (under_dai_access) begin - status_mask[OtpDaiIdleIdx] = 1; - status_mask[OtpDaiErrIdx] = 1; - end - - // Mask out LCI error bit if lc_req is set. - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check) status_mask[OtpLciErrIdx] = 1; - - end else if (data_phase_read) begin - if (cfg.en_cov) begin - cov.collect_status_cov(item.d_data); - if (cfg.otp_ctrl_vif.alert_reqs) begin - cov.csr_rd_after_alert_cg_wrap.sample(csr.get_offset()); - end - end - - if (item.d_data[OtpDaiIdleIdx]) begin - check_otp_idle(1); - dai_wr_ip = 0; - dai_digest_ip = LifeCycleIdx; - end - - // STATUS register check with mask - if (do_read_check) begin - `DV_CHECK_EQ((csr.get_mirrored_value() | status_mask), (item.d_data | status_mask), - $sformatf("reg name: status, compare_mask %0h", status_mask)) - end - - // Check if OtpCheckPending is set correctly, then ignore checking until check is done - if (under_chk) begin - if (item.d_data[OtpCheckPendingIdx] == 0) begin - exp_status[OtpCheckPendingIdx] = 0; - under_chk = 0; - end - end - - if (under_dai_access && !cfg.otp_ctrl_vif.under_error_states()) begin - if (item.d_data[OtpDaiIdleIdx]) begin - under_dai_access = 0; - void'(ral.direct_access_regwen.predict(direct_access_regwen_state)); - void'(ral.intr_state.otp_operation_done.predict(1)); - end - end - end - // checked in this block above - do_read_check = 0; - end - "check_trigger": begin - if (addr_phase_write && cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs) begin - cov.issue_checks_after_alert_cg.sample(item.a_data); - end - - if (addr_phase_write && `gmv(ral.check_trigger_regwen) && item.a_data inside {[1:3]}) begin - bit [TL_DW-1:0] check_timeout = `gmv(ral.check_timeout) == 0 ? '1 : - `gmv(ral.check_timeout); - exp_status[OtpCheckPendingIdx] = 1; - under_chk = 1; - if (check_timeout <= CHK_TIMEOUT_CYC) begin - set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout)); - predict_err(OtpTimeoutErrIdx); - end else begin - if (get_field_val(ral.check_trigger.consistency, item.a_data)) begin - foreach (cfg.ecc_chk_err[i]) begin - if (cfg.ecc_chk_err[i] == OtpEccCorrErr && part_has_integrity(i)) begin - predict_err(otp_status_e'(i), OtpMacroEccCorrError); - end else if (cfg.ecc_chk_err[i] == OtpEccUncorrErr && - part_has_integrity(i)) begin - set_exp_alert("fatal_macro_error", 1, 40_000); - predict_err(otp_status_e'(i), OtpMacroEccUncorrError); - end - end - end - end - end - end - "direct_access_regwen": begin - if (addr_phase_write) begin - // This locks the DAI until the next reset. - if (!item.a_data[0]) begin - direct_access_regwen_state = 0; - void'(ral.direct_access_regwen.predict(0)); - end - end - end - // For error codes, if lc_prog in progress, err_code might update anytime in DUT. Ignore - // checking until req is acknowledged. - - "err_code_0": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(0, item.d_data, access_part_idx); - end - end - "err_code_1": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(1, item.d_data, access_part_idx); - end - end - "err_code_2": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(2, item.d_data, access_part_idx); - end - end - "err_code_3": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(3, item.d_data, access_part_idx); - end - end - "err_code_4": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(4, item.d_data, access_part_idx); - end - end - "err_code_5": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(5, item.d_data, access_part_idx); - end - end - "err_code_6": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(6, item.d_data, access_part_idx); - end - end - "err_code_7": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(7, item.d_data, access_part_idx); - end - end - "err_code_8": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(8, item.d_data, access_part_idx); - end - end - "err_code_9": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(9, item.d_data, access_part_idx); - end - end - "err_code_10": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(10, item.d_data, access_part_idx); - end - end - "err_code_11": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(11, item.d_data, access_part_idx); - end - end - "err_code_12": begin - if (cfg.m_lc_prog_pull_agent_cfg.vif.req) do_read_check = 0; - if (cfg.en_cov && do_read_check && data_phase_read) begin - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address) >> 2 << 2; - int access_part_idx = get_part_index(dai_addr); - cov.collect_err_code_cov(12, item.d_data, access_part_idx); - end - end - "vendor_test_digest_0", "vendor_test_digest_1", - "creator_sw_cfg_digest_0", "creator_sw_cfg_digest_1", - "owner_sw_cfg_digest_0", "owner_sw_cfg_digest_1", - "rot_creator_auth_codesign_digest_0", "rot_creator_auth_codesign_digest_1", - "rot_creator_auth_state_digest_0", "rot_creator_auth_state_digest_1", - "hw_cfg0_digest_0", "hw_cfg0_digest_1", - "hw_cfg1_digest_0", "hw_cfg1_digest_1", - "secret0_digest_0", "secret0_digest_1", - "secret1_digest_0", "secret1_digest_1", - "secret2_digest_0", "secret2_digest_1": begin - if (ignore_digest_chk) do_read_check = 0; - end - "vendor_test_read_lock", - "creator_sw_cfg_read_lock", - "owner_sw_cfg_read_lock", - "rot_creator_auth_codesign_read_lock", - "rot_creator_auth_state_read_lock", - "direct_access_wdata_0", - "direct_access_wdata_1", - "direct_access_address", - "check_regwen", - "check_trigger_regwen", - "check_trigger", - "check_timeout", - "intr_enable", - "integrity_check_period", - "consistency_check_period", - "alert_test": begin - // Do nothing - end - // DAI read data - "direct_access_rdata_0", "direct_access_rdata_1": do_read_check = check_dai_rd_data; - default: begin - `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name())) - end - endcase - - // On reads, if do_read_check, is set, then check mirrored_value against item.d_data - if (data_phase_read) begin - if (do_read_check) begin - `DV_CHECK_EQ(csr.get_mirrored_value(), item.d_data, - $sformatf("reg name: %0s", csr.get_full_name())) - if (cfg.en_cov && cfg.otp_ctrl_vif.alert_reqs) begin - cov.csr_rd_after_alert_cg_wrap.sample(csr.get_offset()); - end - end - void'(csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ))); - end - endfunction - - // If reset or lc_escalate_en is issued during otp program, this function will backdoor update - // otp memory write value because scb did not know how many cells haven been written. - // We won't update csr `direct_access_address` after fatal alert happened, so in this function - // we can directly call method `get_scb_otp_addr` to get the interrupted dai address. - virtual function void recover_interrupted_op(); - if (dai_wr_ip) begin - bit [TL_DW-1:0] otp_addr = get_scb_otp_addr(); - bit [TL_DW-1:0] dai_addr = otp_addr << 2; - backdoor_update_otp_array(dai_addr); - dai_wr_ip = 0; - end - endfunction - - virtual function void backdoor_update_otp_array(bit [TL_DW-1:0] dai_addr); - bit [TL_DW-1:0] otp_addr = dai_addr >> 2; - bit [TL_DW-1:0] readout_word, readout_word1; - int part_idx = get_part_index(dai_addr); - if (part_has_integrity(part_idx)) begin - void'(read_a_word_with_ecc(dai_addr, readout_word)); - void'(read_a_word_with_ecc(dai_addr + 4, readout_word1)); - end else begin - void'(read_a_word_with_ecc_raw(dai_addr, readout_word)); - void'(read_a_word_with_ecc_raw(dai_addr + 4, readout_word1)); - end - - otp_a[otp_addr] = readout_word; - - if (is_digest(dai_addr)) begin - otp_a[otp_addr+1] = readout_word1; - end else if (is_secret(dai_addr)) begin - bit [TL_DW*2-1:0] mem_rd_val, descrambled_val; - mem_rd_val = {readout_word1 ,readout_word}; - descrambled_val = descramble_data(mem_rd_val, part_idx); - otp_a[otp_addr+1] = descrambled_val[TL_DW*2-1:TL_DW]; - otp_a[otp_addr] = descrambled_val[TL_DW-1:0]; - end - endfunction - - virtual function bit [1:0] read_a_word_with_ecc(bit [TL_DW-1:0] dai_addr, - ref bit [TL_DW-1:0] readout_word); - prim_secded_pkg::secded_22_16_t ecc_rd_data0 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr); - prim_secded_pkg::secded_22_16_t ecc_rd_data1 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr + 2); - readout_word[15:0] = ecc_rd_data0.data; - readout_word[31:16] = ecc_rd_data1.data; - return max2(ecc_rd_data0.err, ecc_rd_data1.err); - endfunction - - // Returns the ECC error but does not correct the data bits (i.e. returns the raw data). - virtual function bit [1:0] read_a_word_with_ecc_raw(bit [TL_DW-1:0] dai_addr, - ref bit [TL_DW-1:0] readout_word); - prim_secded_pkg::secded_22_16_t ecc_rd_data0 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr); - prim_secded_pkg::secded_22_16_t ecc_rd_data1 = cfg.mem_bkdr_util_h.ecc_read16(dai_addr + 2); - readout_word[15:0] = 16'hFFFF & cfg.mem_bkdr_util_h.read(dai_addr); - readout_word[31:16] = 16'hFFFF & cfg.mem_bkdr_util_h.read(dai_addr + 2); - return max2(ecc_rd_data0.err, ecc_rd_data1.err); - endfunction - - - virtual function void reset(string kind = "HARD"); - recover_interrupted_op(); - super.reset(kind); - // flush fifos - otbn_fifo.flush(); - flash_addr_fifo.flush(); - flash_data_fifo.flush(); - lc_prog_fifo.flush(); - for (int i = 0; i < NumSramKeyReqSlots; i++) begin - sram_fifos[i].flush(); - end - - direct_access_regwen_state = 1; - under_chk = 0; - under_dai_access = 0; - ignore_digest_chk = 0; - exp_status = `gmv(ral.status); - exp_alert = OtpNoAlert; - - edn_data_q.delete(); - - // Out of reset: lock dai access until power init is done - if (cfg.en_scb) void'(ral.direct_access_regwen.predict(0)); - endfunction - - virtual function void check_otp_idle(bit val, int wait_clks = 0); - fork - begin - fork - begin - // use negedge to avoid race condition - cfg.clk_rst_vif.wait_n_clks(wait_clks + 1); - `uvm_error(`gfn, - $sformatf("pwr_otp_idle output is %0b while expect %0b within %0d cycles", - cfg.otp_ctrl_vif.pwr_otp_idle_o, val, wait_clks)) - end - begin - wait(cfg.under_reset || cfg.otp_ctrl_vif.pwr_otp_idle_o == val || - // Due to OTP access arbitration, any KDI request during DAI access might block - // write secret until KDI request is completed. Since the KDI process time could - // vary depends on the push-pull-agent, we are going to ignore the checking if - // this scenario happens. - cfg.m_otbn_pull_agent_cfg.vif.req || - cfg.m_flash_data_pull_agent_cfg.vif.req || - cfg.m_flash_addr_pull_agent_cfg.vif.req || - cfg.m_sram_pull_agent_cfg[0].vif.req || - cfg.m_sram_pull_agent_cfg[1].vif.req || - cfg.m_sram_pull_agent_cfg[2].vif.req || - cfg.m_sram_pull_agent_cfg[3].vif.req || - cfg.m_lc_prog_pull_agent_cfg.vif.req || - // When lc_escalation is on, the DAI interface goes to ErrorSt, so ignore - // otp_idle checking. - cfg.otp_ctrl_vif.alert_reqs || - // Check timeout will keep doing background check, issue #5616 - exp_status[OtpTimeoutErrIdx]); - end - join_any - disable fork; - end - join_none - endfunction - - // predict digest registers - virtual function void predict_digest_csrs(); - void'(ral.vendor_test_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[VendorTestIdx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.vendor_test_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[VendorTestIdx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.creator_sw_cfg_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[CreatorSwCfgIdx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.creator_sw_cfg_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[CreatorSwCfgIdx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.owner_sw_cfg_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[OwnerSwCfgIdx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.owner_sw_cfg_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[OwnerSwCfgIdx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.rot_creator_auth_codesign_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[RotCreatorAuthCodesignIdx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.rot_creator_auth_codesign_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[RotCreatorAuthCodesignIdx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.rot_creator_auth_state_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[RotCreatorAuthStateIdx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.rot_creator_auth_state_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[RotCreatorAuthStateIdx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.hw_cfg0_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[HwCfg0Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.hw_cfg0_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[HwCfg0Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.hw_cfg1_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[HwCfg1Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.hw_cfg1_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[HwCfg1Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.secret0_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret0Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.secret0_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret0Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.secret1_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret1Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.secret1_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret1Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - - void'(ral.secret2_digest[0].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret2Idx]]), - .kind(UVM_PREDICT_DIRECT))); - void'(ral.secret2_digest[1].predict( - .value(otp_a[PART_OTP_DIGEST_ADDRS[Secret2Idx] + 1]), - .kind(UVM_PREDICT_DIRECT))); - endfunction - - function void update_digest_to_otp(int part_idx, bit [TL_DW*2-1:0] digest); - otp_a[PART_OTP_DIGEST_ADDRS[part_idx]] = digest[31:0]; - otp_a[PART_OTP_DIGEST_ADDRS[part_idx] + 1] = digest[63:32]; - endfunction - - function void check_phase(uvm_phase phase); - super.check_phase(phase); - // post test checks - ensure that all local fifos and queues are empty - endfunction - - // Calculate digest value for each partition - // According to the design spec, the calculation is based on 64-rounds of PRESENT cipher - // The 64-bit data_in state is initialized with a silicon creator constant, and each 128 bit - // chunk of partition data are fed in as keys - // The last 64-round PRESENT calculation will use a global digest constant as key input - function void cal_digest_val(int part_idx); - bit [TL_DW-1:0] mem_q[$]; - int array_size; - bit [SCRAMBLE_DATA_SIZE-1:0] digest; - - if (cfg.otp_ctrl_vif.under_error_states()) return; - - if (!part_has_hw_digest(part_idx) || get_digest_reg_val(part_idx) != 0) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else if (PartInfo[part_idx].iskeymgr_creator && - cfg.otp_ctrl_vif.lc_creator_seed_sw_rw_en_i != lc_ctrl_pkg::On) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else if (PartInfo[part_idx].iskeymgr_owner && - cfg.otp_ctrl_vif.lc_owner_seed_sw_rw_en_i != lc_ctrl_pkg::On) begin - predict_err(OtpDaiErrIdx, OtpAccessError); - return; - end else begin - predict_no_err(OtpDaiErrIdx); - dai_digest_ip = part_idx; - end - case (part_idx) - HwCfg0Idx: mem_q = otp_a[HwCfg0Offset / TL_SIZE : HwCfg0DigestOffset / TL_SIZE - 1]; - HwCfg1Idx: mem_q = otp_a[HwCfg1Offset / TL_SIZE : HwCfg1DigestOffset / TL_SIZE - 1]; - Secret0Idx: mem_q = otp_a[Secret0Offset / TL_SIZE : Secret0DigestOffset / TL_SIZE - 1]; - Secret1Idx: mem_q = otp_a[Secret1Offset / TL_SIZE : Secret1DigestOffset / TL_SIZE - 1]; - Secret2Idx: mem_q = otp_a[Secret2Offset / TL_SIZE : Secret2DigestOffset / TL_SIZE - 1]; - default: begin - `uvm_fatal(`gfn, $sformatf("Access unexpected partition %0d", part_idx)) - end - endcase - - array_size = mem_q.size(); - - // for secret partitions, need to use otp scrambled value as data input - if (PartInfo[part_idx].secret) begin - bit [TL_DW-1:0] scrambled_mem_q[$]; - for (int i = 0; i < array_size/2; i++) begin - bit [SCRAMBLE_DATA_SIZE-1:0] scrambled_data; - scrambled_data = scramble_data({mem_q[i*2+1], mem_q[i*2]}, part_idx); - scrambled_mem_q.push_back(scrambled_data[TL_DW-1:0]); - scrambled_mem_q.push_back(scrambled_data[SCRAMBLE_DATA_SIZE-1:TL_DW]); - end - mem_q = scrambled_mem_q; - end - - digest = otp_scrambler_pkg::cal_digest(part_idx, mem_q); - update_digest_to_otp(part_idx, digest); - endfunction - - - // this function go through present encode algo two or three iterations: - // first iteration with input key, - // second iteration with second_key, this iteration only happens if num_round is 2 - // third iteration with a final constant as key - // this is mainly used for unlock token hashing, key derivation - virtual function bit [SCRAMBLE_DATA_SIZE-1:0] present_encode_with_final_const( - bit [SCRAMBLE_DATA_SIZE-1:0] data, - bit [SCRAMBLE_KEY_SIZE-1:0] key, - bit [SCRAMBLE_KEY_SIZE-1:0] final_const, - bit [SCRAMBLE_KEY_SIZE-1:0] second_key = '0, - int num_round = 1); - bit [SCRAMBLE_DATA_SIZE-1:0] enc_data; - bit [SCRAMBLE_DATA_SIZE-1:0] intermediate_state; - crypto_dpi_present_pkg::sv_dpi_present_encrypt(data, key, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - // XOR the previous state into the digest result according to the Davies-Meyer scheme. - intermediate_state = data ^ enc_data; - - if (num_round == 2) begin - crypto_dpi_present_pkg::sv_dpi_present_encrypt(intermediate_state, second_key, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - intermediate_state = intermediate_state ^ enc_data; - end else if (num_round > 2) begin - `uvm_fatal(`gfn, $sformatf("does not support num_round: %0d > 2", num_round)) - end - - crypto_dpi_present_pkg::sv_dpi_present_encrypt(intermediate_state, final_const, - SCRAMBLE_KEY_SIZE, NUM_ROUND, enc_data); - // XOR the previous state into the digest result according to the Davies-Meyer scheme. - present_encode_with_final_const = intermediate_state ^ enc_data; - endfunction - - // Get address for scoreboard's otp_a array from the `direct_access_address` CSR - function bit [TL_DW-1:0] get_scb_otp_addr(); - bit [TL_DW-1:0] dai_addr = `gmv(ral.direct_access_address); - get_scb_otp_addr = normalize_dai_addr(dai_addr) >> 2; - endfunction - - // This function predict OTP error related registers: intr_state, status, and err_code - virtual function void predict_err(otp_status_e status_err_idx, - otp_err_code_e err_code = OtpNoError, - bit update_esc_err = 0); - if (cfg.otp_ctrl_vif.under_error_states() && !update_esc_err) return; - - // Update intr_state - void'(ral.intr_state.otp_error.predict(.value(1), .kind(UVM_PREDICT_READ))); - // Update status - exp_status[status_err_idx] = 1; - - // Only first status errors up to the LCI have corresponding err_code - if (status_err_idx <= OtpLciErrIdx) begin - dv_base_reg_field err_code_flds[$]; - if (err_code == OtpNoError) begin - `uvm_error(`gfn, $sformatf("please set status error: %0s error code", status_err_idx.name)) - end - ral.err_code[status_err_idx].get_dv_base_reg_fields(err_code_flds); - - if (`gmv(err_code_flds[0]) inside {OTP_TERMINAL_ERRS}) begin - `uvm_info(`gfn, "terminal error cannot be updated", UVM_HIGH) - end else if (status_err_idx == OtpLciErrIdx && - `gmv(err_code_flds[0]) != OtpNoError) begin - `uvm_info(`gfn, "For LC partition, all errors are terminal error!", UVM_HIGH) - end else begin - void'(err_code_flds[0].predict(.value(err_code), .kind(UVM_PREDICT_READ))); - end - end - - endfunction - - virtual function void predict_no_err(otp_status_e status_err_idx); - if (cfg.otp_ctrl_vif.under_error_states()) return; - - exp_status[status_err_idx] = 0; - if (status_err_idx == OtpDaiErrIdx) exp_status[OtpDaiIdleIdx] = 1; - - if (status_err_idx <= OtpLciErrIdx) begin - dv_base_reg_field err_code_flds[$]; - ral.err_code[status_err_idx].get_dv_base_reg_fields(err_code_flds); - void'(err_code_flds[0].predict(OtpNoError)); - end - endfunction - - virtual function void predict_rdata(bit is_64_bits, bit [TL_DW-1:0] rdata0, - bit [TL_DW-1:0] rdata1 = 0); - void'(ral.direct_access_rdata[0].predict(.value(rdata0), .kind(UVM_PREDICT_READ))); - if (is_64_bits) begin - void'(ral.direct_access_rdata[1].predict(.value(rdata1), .kind(UVM_PREDICT_READ))); - end - endfunction - - // this function retrieves keys (128 bits) from scb's otp_array with a starting address - // if not locked, it will return 0 - // this is mainly used for scrambling key algo - virtual function bit [SCRAMBLE_KEY_SIZE-1:0] get_key_from_otp(bit locked, int start_i); - bit [SCRAMBLE_KEY_SIZE-1:0] key; - if (!locked) return 0; - for (int i = 0; i < 4; i++) key |= otp_a[i + start_i] << (TL_DW * i); - return key; - endfunction - - // The following two methods are all retrieving digest val. - // get_otp_digest_val: is the digest value from OTP memory - // get_digest_reg_val: is the digest value in register. This value is identical to OTP - // memory's digest value after a power cycle reset. - virtual function bit [TL_DW*2-1:0] get_otp_digest_val(int part_idx); - get_otp_digest_val[31:0] = otp_a[PART_OTP_DIGEST_ADDRS[part_idx]]; - get_otp_digest_val[63:32] = otp_a[PART_OTP_DIGEST_ADDRS[part_idx] + 1]; - endfunction - - virtual function bit [TL_DW*2-1:0] get_digest_reg_val(int part_idx); - bit [TL_DW*2-1:0] digest; - case (part_idx) - VendorTestIdx: begin - digest = {`gmv(ral.vendor_test_digest[1]), - `gmv(ral.vendor_test_digest[0])}; - end - CreatorSwCfgIdx: begin - digest = {`gmv(ral.creator_sw_cfg_digest[1]), - `gmv(ral.creator_sw_cfg_digest[0])}; - end - OwnerSwCfgIdx: begin - digest = {`gmv(ral.owner_sw_cfg_digest[1]), - `gmv(ral.owner_sw_cfg_digest[0])}; - end - RotCreatorAuthCodesignIdx: begin - digest = {`gmv(ral.rot_creator_auth_codesign_digest[1]), - `gmv(ral.rot_creator_auth_codesign_digest[0])}; - end - RotCreatorAuthStateIdx: begin - digest = {`gmv(ral.rot_creator_auth_state_digest[1]), - `gmv(ral.rot_creator_auth_state_digest[0])}; - end - HwCfg0Idx: begin - digest = {`gmv(ral.hw_cfg0_digest[1]), - `gmv(ral.hw_cfg0_digest[0])}; - end - HwCfg1Idx: begin - digest = {`gmv(ral.hw_cfg1_digest[1]), - `gmv(ral.hw_cfg1_digest[0])}; - end - Secret0Idx: begin - digest = {`gmv(ral.secret0_digest[1]), - `gmv(ral.secret0_digest[0])}; - end - Secret1Idx: begin - digest = {`gmv(ral.secret1_digest[1]), - `gmv(ral.secret1_digest[0])}; - end - Secret2Idx: begin - digest = {`gmv(ral.secret2_digest[1]), - `gmv(ral.secret2_digest[0])}; - end - default: `uvm_fatal(`gfn, $sformatf("Partition %0d does not have digest", part_idx)) - endcase - return digest; - endfunction - - virtual function bit is_tl_mem_access_allowed(input tl_seq_item item, input string ral_name, - output bit mem_byte_access_err, - output bit mem_wo_err, - output bit mem_ro_err, - output bit custom_err); - - uvm_reg_addr_t addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - bit [TL_AW-1:0] addr_mask = ral.get_addr_mask(); - bit [TL_AW-1:0] dai_addr = (csr_addr & addr_mask - SW_WINDOW_BASE_ADDR); - - bit mem_access_allowed = super.is_tl_mem_access_allowed(item, ral_name, mem_byte_access_err, - mem_wo_err, mem_ro_err, custom_err); - - if (ral_name == "otp_ctrl_prim_reg_block") return mem_access_allowed; - - // Ensure the address is within the memory window range. - // Also will skip checking if memory access is not allowed due to TLUL bus error. - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr : - cfg.ral_models[ral_name].mem_ranges[0].end_addr]} && - mem_access_allowed) begin - - // If sw partition is read locked, then access policy changes from RO to no access - if (`gmv(ral.vendor_test_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + VendorTestOffset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + VendorTestOffset + - VendorTestSize - 1]}) begin - predict_err(OtpVendorTestErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[VendorTestIdx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(VendorTestIdx) != 0), .is_write(0)); - end - return 0; - end - end - if (`gmv(ral.creator_sw_cfg_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + CreatorSwCfgOffset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + CreatorSwCfgOffset + - CreatorSwCfgSize - 1]}) begin - predict_err(OtpCreatorSwCfgErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[CreatorSwCfgIdx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(CreatorSwCfgIdx) != 0), .is_write(0)); - end - return 0; - end - end - if (`gmv(ral.owner_sw_cfg_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + OwnerSwCfgOffset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + OwnerSwCfgOffset + - OwnerSwCfgSize - 1]}) begin - predict_err(OtpOwnerSwCfgErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[OwnerSwCfgIdx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(OwnerSwCfgIdx) != 0), .is_write(0)); - end - return 0; - end - end - if (`gmv(ral.rot_creator_auth_codesign_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + RotCreatorAuthCodesignOffset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + RotCreatorAuthCodesignOffset + - RotCreatorAuthCodesignSize - 1]}) begin - predict_err(OtpRotCreatorAuthCodesignErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[RotCreatorAuthCodesignIdx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(RotCreatorAuthCodesignIdx) != 0), .is_write(0)); - end - return 0; - end - end - if (`gmv(ral.rot_creator_auth_state_read_lock) == 0 || - cfg.otp_ctrl_vif.under_error_states()) begin - if (addr inside { - [cfg.ral_models[ral_name].mem_ranges[0].start_addr + RotCreatorAuthStateOffset : - cfg.ral_models[ral_name].mem_ranges[0].start_addr + RotCreatorAuthStateOffset + - RotCreatorAuthStateSize - 1]}) begin - predict_err(OtpRotCreatorAuthStateErrIdx, OtpAccessError); - custom_err = 1; - if (cfg.en_cov) begin - cov.unbuf_access_lock_cg_wrap[RotCreatorAuthStateIdx].sample(.read_lock(1), - .write_lock(get_digest_reg_val(RotCreatorAuthStateIdx) != 0), .is_write(0)); - end - return 0; - end - end - - // Check ECC uncorrectable fatal error. - if (dai_addr < LifeCycleOffset) begin - int part_idx = get_part_index(dai_addr); - bit [TL_DW-1:0] read_out; - int ecc_err = read_a_word_with_ecc(dai_addr, read_out); - if (ecc_err == OtpEccUncorrErr && part_has_integrity(part_idx)) begin - predict_err(otp_status_e'(part_idx), OtpMacroEccUncorrError); - set_exp_alert("fatal_macro_error", 1, 20); - custom_err = 1; - return 0; - end - end - end - - return mem_access_allowed; - endfunction - - virtual function bit predict_tl_err(tl_seq_item item, tl_channels_e channel, string ral_name); - if (ral_name == "otp_ctrl_prim_reg_block" && - cfg.otp_ctrl_vif.lc_dft_en_i != lc_ctrl_pkg::On) begin - if (channel == DataChannel) begin - `DV_CHECK_EQ(item.d_error, 1, - $sformatf({"On interface %0s, TL item: %0s, access gated by lc_dft_en_i"}, - ral_name, item.sprint(uvm_default_line_printer))) - - // In data read phase, check d_data when d_error = 1. - if (item.d_error && (item.d_opcode == tlul_pkg::AccessAckData)) begin - check_tl_read_value_after_error(item, ral_name); - end - end - return 1; - end - return super.predict_tl_err(item, channel, ral_name); - endfunction - - virtual function void set_exp_alert(string alert_name, bit is_fatal = 0, int max_delay = 0); - exp_alert = alert_name == "fatal_check_error" ? OtpCheckAlert : OtpMacroAlert; - super.set_exp_alert(alert_name, is_fatal, max_delay); - endfunction - -endclass diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv deleted file mode 100644 index 4780a80659940..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_virtual_sequencer extends cip_base_virtual_sequencer #( - .CFG_T(otp_ctrl_env_cfg), - .COV_T(otp_ctrl_env_cov) - ); - `uvm_component_utils(otp_ctrl_virtual_sequencer) - - `uvm_component_new - - push_pull_sequencer#(.DeviceDataWidth(SRAM_DATA_SIZE)) sram_pull_sequencer_h[NumSramKeyReqSlots]; - push_pull_sequencer#(.DeviceDataWidth(OTBN_DATA_SIZE)) otbn_pull_sequencer_h; - push_pull_sequencer#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_data_pull_sequencer_h; - push_pull_sequencer#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_addr_pull_sequencer_h; - push_pull_sequencer#(.DeviceDataWidth(1), .HostDataWidth(LC_PROG_DATA_SIZE)) - lc_prog_pull_sequencer_h; -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_background_chks_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_background_chks_vseq.sv deleted file mode 100644 index d316e1a12a521..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_background_chks_vseq.sv +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This simple sequence checks if the background check can be triggered once the period is set. - -class otp_ctrl_background_chks_vseq extends otp_ctrl_dai_lock_vseq; - `uvm_object_utils(otp_ctrl_background_chks_vseq) - - `uvm_object_new - - rand bit [1:0] trigger_chks; - rand uint check_period; - - constraint regwens_c {check_regwen_val == 1;} - - // At least one check will be triggered - constraint check_triggers_c {trigger_chks > 0;} - - constraint check_period_c { - check_period < 20; - check_period > 0; - } - - task body(); - int check_wait_cycles; - super.body(); - - // For stress_all_with_rand_reset test, if previous lc_esc_en is not cleared, then skip the - // background check. - if (cfg.otp_ctrl_vif.lc_esc_on == 0) begin - - // Write background check - if (trigger_chks[0]) csr_wr(ral.integrity_check_period, check_period); - if (trigger_chks[1]) csr_wr(ral.consistency_check_period, check_period); - `uvm_info(`gfn, $sformatf("trigger background check %0h", trigger_chks), UVM_LOW) - - cfg.en_scb = 0; - // According to spec, check period will append an 'hFF from the LSF. Add 10 cycle buffers for - // register updates. - check_wait_cycles = (check_period + 1) << 8 + 10; - - // Wait for first check done - repeat($countones(trigger_chks)) begin - csr_spinwait(.ptr(ral.status.check_pending), .exp_data(1), - .timeout_ns(cfg.clk_rst_vif.clk_period_ps / 1000 * check_wait_cycles)); - - csr_spinwait(.ptr(ral.status.check_pending), .exp_data(0)); - end - - // Configure timeout settings to trigger check error - csr_wr(ral.check_timeout, $urandom_range(1, 5)); - `uvm_info(`gfn, "trigger check timeout error", UVM_LOW) - - // Wait for fatal alert - `DV_SPINWAIT_EXIT( - wait(cfg.m_alert_agent_cfgs["fatal_check_error"].vif.alert_tx_final.alert_p);, - cfg.clk_rst_vif.wait_clks(check_wait_cycles);, - $sformatf("Timeout waiting for alert %0s", "fatal_check_error")) - check_fatal_alert_nonblocking("fatal_check_error"); - - cfg.clk_rst_vif.wait_clks($urandom_range(50, 1000)); - csr_rd_check(.ptr(ral.status.timeout_error), .compare_value(1)); - end - endtask - - // Enable scoreboard is done in stress_all sequence and `apply_resets_concurrently` task to - // avoid otp_ctrl_scoreboard reporting failures when reset has not been issued. - virtual task post_start(); - expect_fatal_alerts = 1; - super.post_start(); - endtask -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv deleted file mode 100644 index 4f7744fe621f9..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv +++ /dev/null @@ -1,705 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -class otp_ctrl_base_vseq extends cip_base_vseq #( - .RAL_T (otp_ctrl_core_reg_block), - .CFG_T (otp_ctrl_env_cfg), - .COV_T (otp_ctrl_env_cov), - .VIRTUAL_SEQUENCER_T (otp_ctrl_virtual_sequencer) - ); - `uvm_object_utils(otp_ctrl_base_vseq) - `uvm_object_new - - // various knobs to enable certain routines - bit do_otp_ctrl_init = 1'b1; - bit do_otp_pwr_init = 1'b1; - - // To only write unused OTP address, sequence will collect all the written addresses to an - // associative array to avoid `write_blank_addr_error`. - bit write_unused_addr = 1; - static bit used_dai_addrs[bit [OTP_ADDR_WIDTH - 1 : 0]]; - - rand bit [NumOtpCtrlIntr-1:0] en_intr; - - rand int apply_reset_during_pwr_init_cycles; - - bit is_valid_dai_op = 1; - - // According to spec, the period between digest calculation and reset should not issue any write. - bit [NumPart-2:0] digest_calculated; - - // For stress_all_with_rand reset sequence to issue reset during OTP operations. - bit do_digest_cal, do_otp_rd, do_otp_wr; - - // LC program request will use a separate variable to automatically set to non-blocking setting - // when LC error bit is set. - bit default_req_blocking = 1; - bit lc_prog_blocking = 1; - bit dai_wr_inprogress = 0; - uint32_t op_done_spinwait_timeout_ns = 20_000_000; - - // Collect current lc_state and lc_cnt. This is used to create next lc_state and lc_cnt without - // error. - lc_ctrl_state_pkg::lc_state_e lc_state; - lc_ctrl_state_pkg::lc_cnt_e lc_cnt; - - otp_ctrl_callback_vseq callback_vseq; - - constraint apply_reset_during_pwr_init_cycles_c { - apply_reset_during_pwr_init_cycles == 0; - } - - virtual task pre_start(); - `uvm_create_on(callback_vseq, p_sequencer); - super.pre_start(); - endtask - - virtual task dut_init(string reset_kind = "HARD"); - // OTP has dut and edn reset. If assign OTP values after `super.dut_init()`, and if dut reset - // deasserts earlier than edn reset, some OTP outputs might remain X or Z when dut clock is - // running. - otp_ctrl_vif_init(); - super.dut_init(reset_kind); - callback_vseq.dut_init_callback(); - - cfg.backdoor_clear_mem = 0; - // reset power init pin and lc pins - if (do_otp_ctrl_init && do_apply_reset) otp_ctrl_init(); - cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); - if (do_otp_pwr_init && do_apply_reset) otp_pwr_init(); - callback_vseq.post_otp_pwr_init(); - endtask - - // Cfg errors are cleared after reset - virtual task apply_reset(string kind = "HARD"); - super.apply_reset(kind); - cfg.otp_ctrl_vif.release_part_access_mubi(); - clear_seq_flags(); - endtask - - virtual function void clear_seq_flags(); - do_digest_cal = 0; - do_otp_rd = 0; - do_otp_wr = 0; - endfunction - - virtual task otp_ctrl_vif_init(); - cfg.otp_ctrl_vif.drive_lc_creator_seed_sw_rw_en(lc_ctrl_pkg::On); - cfg.otp_ctrl_vif.drive_lc_owner_seed_sw_rw_en(lc_ctrl_pkg::On); - cfg.otp_ctrl_vif.drive_lc_seed_hw_rd_en(get_rand_lc_tx_val()); - cfg.otp_ctrl_vif.drive_lc_dft_en(get_rand_lc_tx_val(.t_weight(0))); - cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off); - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - cfg.otp_ctrl_vif.drive_ext_voltage_h_io(1'bz); - - // Unused signals in open sourced OTP memory - `DV_CHECK_RANDOMIZE_FATAL(cfg.dut_cfg) - cfg.otp_ctrl_vif.otp_ast_pwr_seq_h_i = cfg.dut_cfg.otp_ast_pwr_seq_h; - cfg.otp_ctrl_vif.scan_en_i = cfg.dut_cfg.scan_en; - cfg.otp_ctrl_vif.scan_rst_ni = cfg.dut_cfg.scan_rst_n; - cfg.otp_ctrl_vif.scanmode_i = cfg.dut_cfg.scanmode; - cfg.otp_ctrl_vif.otp_vendor_test_ctrl_i = cfg.dut_cfg.otp_vendor_test_ctrl; - endtask - - // drive otp_pwr req pin to initialize OTP, and wait until init is done - virtual task otp_pwr_init(); - cfg.otp_ctrl_vif.drive_pwr_otp_init(1); - if (apply_reset_during_pwr_init_cycles > 0) begin - `DV_SPINWAIT_EXIT( - cfg.clk_rst_vif.wait_clks(apply_reset_during_pwr_init_cycles);, - wait (cfg.otp_ctrl_vif.pwr_otp_done_o == 1);) - if (cfg.otp_ctrl_vif.pwr_otp_done_o == 0) begin - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - apply_reset(); - cfg.otp_ctrl_vif.drive_pwr_otp_init(1); - end - end - wait (cfg.otp_ctrl_vif.pwr_otp_done_o == 1); - cfg.otp_ctrl_vif.drive_pwr_otp_init(0); - digest_calculated = 0; - endtask - - // setup basic otp_ctrl features - virtual task otp_ctrl_init(); - // reset memory to avoid readout X - clear_otp_memory(); - lc_state = lc_state_e'(0); - lc_cnt = lc_cnt_e'(0); - endtask - - virtual function void clear_otp_memory(); - cfg.mem_bkdr_util_h.clear_mem(); - cfg.backdoor_clear_mem = 1; - used_dai_addrs.delete(); - endfunction - - // Overide this task for otp_ctrl_common_vseq and otp_ctrl_stress_all_with_rand_reset_vseq - // because some registers won't set to default value until otp_init is done. - virtual task read_and_check_all_csrs_after_reset(); - cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off); - otp_pwr_init(); - super.read_and_check_all_csrs_after_reset(); - endtask - - // this task triggers an OTP write sequence via the DAI interface - virtual task dai_wr(bit [TL_DW-1:0] addr, - bit [TL_DW-1:0] wdata0, - bit [TL_DW-1:0] wdata1 = 0); - bit [TL_DW-1:0] val; - dai_wr_inprogress = 1; - if (write_unused_addr) begin - if (used_dai_addrs.exists(addr[OTP_ADDR_WIDTH - 1 : 0])) begin - `uvm_info(`gfn, $sformatf("addr %0h is already written!", addr), UVM_MEDIUM) - dai_wr_inprogress = 0; - return; - end else begin - used_dai_addrs[addr] = 1; - end - end - addr = randomize_dai_addr(addr); - `uvm_info(`gfn, $sformatf("dai write addr %0h, data %0h", addr, wdata0), UVM_HIGH) - csr_wr(ral.direct_access_address, addr); - csr_wr(ral.direct_access_wdata[0], wdata0); - if (is_secret(addr) || is_sw_digest(addr)) csr_wr(ral.direct_access_wdata[1], wdata1); - - do_otp_wr = 1; - csr_wr(ral.direct_access_cmd, int'(otp_ctrl_pkg::DaiWrite)); - `uvm_info(`gfn, $sformatf("DAI write, address %0h, data0 %0h data1 %0h, is_secret = %0b", - addr, wdata0, wdata1, is_secret(addr)), UVM_DEBUG) - - // Direct_access_regwen and dai_idle are checked only when following conditions are met: - // - the dai operation is valid, otherwise it is hard to predict which cycle the error is - // detected - // - zero delays in TLUL interface, otherwise dai operation might be finished before reading - // these two CSRs - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - wait_dai_op_done(); - rd_and_clear_intrs(); - dai_wr_inprogress = 0; - endtask : dai_wr - - // This task triggers an OTP readout sequence via the DAI interface - virtual task dai_rd(input bit [TL_DW-1:0] addr, - output bit [TL_DW-1:0] rdata0, - output bit [TL_DW-1:0] rdata1); - bit [TL_DW-1:0] val; - addr = randomize_dai_addr(addr); - - csr_wr(ral.direct_access_address, addr); - do_otp_rd = 1; - csr_wr(ral.direct_access_cmd, int'(otp_ctrl_pkg::DaiRead)); - - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - - wait_dai_op_done(); - csr_rd(ral.direct_access_rdata[0], rdata0); - if (is_secret(addr) || is_digest(addr)) csr_rd(ral.direct_access_rdata[1], rdata1); - rd_and_clear_intrs(); - endtask : dai_rd - - virtual task dai_rd_check(bit [TL_DW-1:0] addr, - bit [TL_DW-1:0] exp_data0, - bit [TL_DW-1:0] exp_data1 = 0); - bit [TL_DW-1:0] rdata0, rdata1; - dai_rd(addr, rdata0, rdata1); - if (!cfg.under_reset) begin - `DV_CHECK_EQ(rdata0, exp_data0, $sformatf("dai addr %0h rdata0 readout mismatch", addr)) - if (is_secret(addr) || is_digest(addr)) begin - `DV_CHECK_EQ(rdata1, exp_data1, $sformatf("dai addr %0h rdata1 readout mismatch", addr)) - end - end - endtask: dai_rd_check - - // this task exercises an OTP digest calculation via the DAI interface - virtual task cal_digest(int part_idx); - bit [TL_DW-1:0] val; - csr_wr(ral.direct_access_address, PART_BASE_ADDRS[part_idx]); - csr_wr(ral.direct_access_cmd, otp_ctrl_pkg::DaiDigest); - - if (cfg.zero_delays && is_valid_dai_op && - cfg.otp_ctrl_vif.lc_escalate_en_i == lc_ctrl_pkg::Off) begin - csr_rd_check(ral.status.dai_idle, .compare_value(0), .backdoor(1)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(val)); - end - do_digest_cal = 1; - wait_dai_op_done(); - digest_calculated[part_idx] = 1; - rd_and_clear_intrs(); - endtask - - // this task provisions all HW partitions - // SW partitions could not be provisioned via DAI interface - // LC partitions cannot be locked - virtual task cal_hw_digests(bit [NumPart-1:0] trigger_digest = $urandom()); - foreach (PartInfo[i]) begin - if (PartInfo[i].hw_digest && trigger_digest[i]) begin - cal_digest(i); - end - end - endtask - - // SW digest data are calculated in sw and won't be checked in OTP. - // Here to simplify testbench, write random data to sw digest. - virtual task write_sw_digests(bit [NumPartUnbuf-1:0] wr_digest = $urandom()); - bit [TL_DW*2-1:0] wdata; - if (wr_digest[VendorTestIdx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(VendorTestDigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end - if (wr_digest[CreatorSwCfgIdx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(CreatorSwCfgDigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end - if (wr_digest[OwnerSwCfgIdx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(OwnerSwCfgDigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end - if (wr_digest[RotCreatorAuthCodesignIdx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(RotCreatorAuthCodesignDigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end - if (wr_digest[RotCreatorAuthStateIdx]) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata); - dai_wr(RotCreatorAuthStateDigestOffset, wdata[TL_DW-1:0], wdata[TL_DW*2-1:TL_DW]); - end - endtask - - virtual task write_sw_rd_locks(bit [NumPartUnbuf-1:0] do_rd_lock= $urandom()); - if (do_rd_lock[VendorTestIdx]) csr_wr(ral.vendor_test_read_lock, 0); - if (do_rd_lock[CreatorSwCfgIdx]) csr_wr(ral.creator_sw_cfg_read_lock, 0); - if (do_rd_lock[OwnerSwCfgIdx]) csr_wr(ral.owner_sw_cfg_read_lock, 0); - if (do_rd_lock[RotCreatorAuthCodesignIdx]) csr_wr(ral.rot_creator_auth_codesign_read_lock, 0); - if (do_rd_lock[RotCreatorAuthStateIdx]) csr_wr(ral.rot_creator_auth_state_read_lock, 0); - endtask - - // The digest CSR values are verified in otp_ctrl_scoreboard - virtual task rd_digests(); - bit [TL_DW-1:0] val; - csr_rd(.ptr(ral.vendor_test_digest[0]), .value(val)); - csr_rd(.ptr(ral.vendor_test_digest[1]), .value(val)); - csr_rd(.ptr(ral.creator_sw_cfg_digest[0]), .value(val)); - csr_rd(.ptr(ral.creator_sw_cfg_digest[1]), .value(val)); - csr_rd(.ptr(ral.owner_sw_cfg_digest[0]), .value(val)); - csr_rd(.ptr(ral.owner_sw_cfg_digest[1]), .value(val)); - csr_rd(.ptr(ral.rot_creator_auth_codesign_digest[0]), .value(val)); - csr_rd(.ptr(ral.rot_creator_auth_codesign_digest[1]), .value(val)); - csr_rd(.ptr(ral.rot_creator_auth_state_digest[0]), .value(val)); - csr_rd(.ptr(ral.rot_creator_auth_state_digest[1]), .value(val)); - csr_rd(.ptr(ral.hw_cfg0_digest[0]), .value(val)); - csr_rd(.ptr(ral.hw_cfg0_digest[1]), .value(val)); - csr_rd(.ptr(ral.hw_cfg1_digest[0]), .value(val)); - csr_rd(.ptr(ral.hw_cfg1_digest[1]), .value(val)); - csr_rd(.ptr(ral.secret0_digest[0]), .value(val)); - csr_rd(.ptr(ral.secret0_digest[1]), .value(val)); - csr_rd(.ptr(ral.secret1_digest[0]), .value(val)); - csr_rd(.ptr(ral.secret1_digest[1]), .value(val)); - csr_rd(.ptr(ral.secret2_digest[0]), .value(val)); - csr_rd(.ptr(ral.secret2_digest[1]), .value(val)); - endtask - - // If the partition is read/write locked, there is 20% chance we will force the internal mubi - // access signal to the values other than mubi::true or mubi::false. - virtual task force_mubi_part_access(); - // Stress_all_with_rand_reset seq will issue reset and wait until reset is done then kill the - // parallel sequence. This gating logic avoid injecting error during reset active. - if (cfg.otp_ctrl_vif.alert_reqs == 0 && !cfg.under_reset) begin - otp_part_access_lock_t forced_mubi_part_access[NumPart-1]; - - // Digest write locks - if ((`gmv(ral.vendor_test_digest[0]) || - `gmv(ral.vendor_test_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[VendorTestIdx].write_lock = 1; - end - if ((`gmv(ral.creator_sw_cfg_digest[0]) || - `gmv(ral.creator_sw_cfg_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[CreatorSwCfgIdx].write_lock = 1; - end - if ((`gmv(ral.owner_sw_cfg_digest[0]) || - `gmv(ral.owner_sw_cfg_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[OwnerSwCfgIdx].write_lock = 1; - end - if ((`gmv(ral.rot_creator_auth_codesign_digest[0]) || - `gmv(ral.rot_creator_auth_codesign_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[RotCreatorAuthCodesignIdx].write_lock = 1; - end - if ((`gmv(ral.rot_creator_auth_state_digest[0]) || - `gmv(ral.rot_creator_auth_state_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[RotCreatorAuthStateIdx].write_lock = 1; - end - if ((`gmv(ral.hw_cfg0_digest[0]) || - `gmv(ral.hw_cfg0_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[HwCfg0Idx].write_lock = 1; - end - if ((`gmv(ral.hw_cfg1_digest[0]) || - `gmv(ral.hw_cfg1_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[HwCfg1Idx].write_lock = 1; - end - if ((`gmv(ral.secret0_digest[0]) || - `gmv(ral.secret0_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret0Idx].write_lock = 1; - end - if ((`gmv(ral.secret1_digest[0]) || - `gmv(ral.secret1_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret1Idx].write_lock = 1; - end - if ((`gmv(ral.secret2_digest[0]) || - `gmv(ral.secret2_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret2Idx].write_lock = 1; - end - - // CSR read locks - if ((`gmv(ral.vendor_test_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[VendorTestIdx].read_lock = 1; - end - if ((`gmv(ral.creator_sw_cfg_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[CreatorSwCfgIdx].read_lock = 1; - end - if ((`gmv(ral.owner_sw_cfg_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[OwnerSwCfgIdx].read_lock = 1; - end - if ((`gmv(ral.rot_creator_auth_codesign_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[RotCreatorAuthCodesignIdx].read_lock = 1; - end - if ((`gmv(ral.rot_creator_auth_state_read_lock) == 0) && !$urandom_range(0, 4)) begin - forced_mubi_part_access[RotCreatorAuthStateIdx].read_lock = 1; - end - - - // Digest read locks - if ((`gmv(ral.secret0_digest[0]) || - `gmv(ral.secret0_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret0Idx].read_lock = 1; - end - if ((`gmv(ral.secret1_digest[0]) || - `gmv(ral.secret1_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret1Idx].read_lock = 1; - end - if ((`gmv(ral.secret2_digest[0]) || - `gmv(ral.secret2_digest[1])) && - !$urandom_range(0, 4)) begin - forced_mubi_part_access[Secret2Idx].read_lock = 1; - end - - foreach (forced_mubi_part_access[i]) begin - `uvm_info(`gfn, $sformatf("partition %0d inject mubi value: read=%0b, write=%0b", i, - forced_mubi_part_access[i].read_lock, forced_mubi_part_access[i].write_lock), UVM_HIGH) - end - - cfg.otp_ctrl_vif.force_part_access_mubi(forced_mubi_part_access); - end - endtask - - // This function backdoor inject error according to ecc_err: - // - for OtpEccUncorrErr it injects a 2 bit eror - // - for OtpEccCorrErr it injects a 1 bit eror - // This function will output original backdoor read data for the given address - // so the error can be cleared. - virtual function bit [TL_DW-1:0] backdoor_inject_ecc_err(bit [TL_DW-1:0] addr, - otp_ecc_err_e ecc_err); - bit [TL_DW-1:0] val; - addr = {addr[TL_DW-1:2], 2'b00}; - val = cfg.mem_bkdr_util_h.read32(addr); - if (ecc_err == OtpNoEccErr || addr >= (LifeCycleOffset + LifeCycleSize)) return val; - - // Backdoor read and write back with error bits - cfg.mem_bkdr_util_h.inject_errors(addr, (ecc_err == OtpEccUncorrErr) ? 2 : 1); - `uvm_info(`gfn, $sformatf("original val %0h, addr %0h, err_type %0s", - val, addr, ecc_err.name), UVM_HIGH) - return val; - endfunction - - virtual task trigger_checks(bit [1:0] val, - bit wait_done = 1, - otp_ecc_err_e ecc_err = OtpNoEccErr); - bit [TL_DW-1:0] backdoor_rd_val, addr; - - // If ECC and check error happens in the same consistency check, the scb cannot predict which - // error will happen first, so it cannot correctly predict the error status and alert - // triggered. - // So the sequence only allows one error at a time. - if (get_field_val(ral.check_trigger.consistency, val) && - `gmv(ral.check_timeout) > 0 && `gmv(ral.check_timeout) <= CHK_TIMEOUT_CYC) begin - ecc_err = OtpNoEccErr; - end - - // Backdoor write ECC errors - if (ecc_err != OtpNoEccErr) begin - int part_idx = $urandom_range(HwCfg0Idx, LifeCycleIdx); - - // Only HW cfgs check digest correctness - if (part_idx != LifeCycleIdx) begin - addr = $urandom_range(0, 1) ? PART_OTP_DIGEST_ADDRS[part_idx] << 2 : - (PART_OTP_DIGEST_ADDRS[part_idx] + 1) << 2; - end else begin - addr = $urandom_range(LifeCycleOffset, LifeCycleOffset + LifeCycleSize - 1); - addr = {addr[TL_DW-1:2], 2'b00}; - end - backdoor_rd_val = backdoor_inject_ecc_err(addr, ecc_err); - cfg.ecc_chk_err[part_idx] = ecc_err; - end - - csr_wr(ral.check_trigger, val); - if (wait_done && val) csr_spinwait(ral.status.check_pending, 0); - - if (ecc_err != OtpNoEccErr) begin - cfg.mem_bkdr_util_h.write32(addr, backdoor_rd_val); - cfg.ecc_chk_err = '{default: OtpNoEccErr}; - end - endtask - - // For a DAI interface operation to finish, either way until status dai_idle is set, or check - // err_code and see if fatal error happened. In any case, break out of this wait if there - // is a need to stop transaction generators, since a spinwait will otherwise just stop - // when it times-out. - virtual task wait_dai_op_done(); - if (cfg.stop_transaction_generators()) return; - fork begin - fork - begin - csr_spinwait(.ptr(ral.status.dai_idle), - .exp_data(1), - .timeout_ns(op_done_spinwait_timeout_ns), - .spinwait_delay_ns($urandom_range(0, 5))); - end - begin - forever begin - bit [TL_DW-1:0] err_val; - cfg.clk_rst_vif.wait_clks(1); - csr_rd(.ptr(ral.err_code[DaiIdx].err_code), .value(err_val), .backdoor(1)); - // Break if error will cause fatal alerts - if (err_val inside {OTP_TERMINAL_ERRS}) break; - end - end - begin - forever begin - cfg.clk_rst_vif.wait_clks(1); - if (cfg.stop_transaction_generators()) break; - end - end - join_any - wait_no_outstanding_access(); - disable fork; - end join - endtask - - virtual task rd_and_clear_intrs(); - bit [TL_DW-1:0] val; - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check == 0) begin - csr_rd(ral.intr_state, val); - // In case lc_program request is issued after intr_state read - if (cfg.otp_ctrl_vif.lc_prog_no_sta_check == 0) csr_wr(ral.intr_state, val); - end - endtask - - // first two or three LSB bits of DAI address can be randomized based on if it is secret - virtual function bit [TL_AW-1:0] randomize_dai_addr(bit [TL_AW-1:0] dai_addr); - if (is_secret(dai_addr)) begin - bit [2:0] rand_addr = $urandom(); - randomize_dai_addr = {dai_addr[TL_DW-1:3], rand_addr}; - end else begin - bit [1:0] rand_addr = $urandom(); - randomize_dai_addr = {dai_addr[TL_DW-1:2], rand_addr}; - end - endfunction - - // The following interface requests are separated to blocking and non-blocking accesses. - // The non-blocking access is mainly used when lc_escalate_en is On, which acts like a reset and - // move all design state machines to ErrorSt. Thus pending request will never get a response - // until reset. - virtual task req_sram_key(int index, bit blocking = default_req_blocking); - // Return if the request is already high, this is mainly due to lc_escalate_en On. - if (cfg.m_sram_pull_agent_cfg[index].vif.req === 1'b1) return; - - if (blocking) begin - req_sram_key_sub(index); - end else begin - fork - begin - req_sram_key_sub(index); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_sram_key_sub(int index); - push_pull_host_seq#(.DeviceDataWidth(SRAM_DATA_SIZE)) sram_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(sram_pull_seq, p_sequencer.sram_pull_sequencer_h[index]); - `DV_CHECK_RANDOMIZE_FATAL(sram_pull_seq) - `uvm_send(sram_pull_seq) - endtask - - virtual task req_all_sram_keys(bit blocking = default_req_blocking); - for (int i = 0; i < NumSramKeyReqSlots; i++) req_sram_key(i, blocking); - endtask - - virtual task req_otbn_key(bit blocking = default_req_blocking); - if (cfg.m_otbn_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_otbn_key_sub(); - end else begin - fork - begin - req_otbn_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_otbn_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(OTBN_DATA_SIZE)) otbn_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(otbn_pull_seq, p_sequencer.otbn_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(otbn_pull_seq) - `uvm_send(otbn_pull_seq) - endtask - - virtual task req_flash_addr_key(bit blocking = default_req_blocking); - if (cfg.m_flash_addr_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_flash_addr_key_sub(); - end else begin - fork - begin - req_flash_addr_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_flash_addr_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_addr_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(flash_addr_pull_seq, p_sequencer.flash_addr_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(flash_addr_pull_seq) - `uvm_send(flash_addr_pull_seq) - endtask - - virtual task req_flash_data_key(bit blocking = default_req_blocking); - if (cfg.m_flash_data_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_flash_data_key_sub(); - end else begin - fork - begin - req_flash_data_key_sub(); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_flash_data_key_sub(); - push_pull_host_seq#(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_data_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(flash_data_pull_seq, p_sequencer.flash_data_pull_sequencer_h); - `DV_CHECK_RANDOMIZE_FATAL(flash_data_pull_seq) - `uvm_send(flash_data_pull_seq) - endtask - - virtual task req_lc_transition(bit check_intr = 0, - bit blocking = default_req_blocking, - bit wr_blank_err = !write_unused_addr); - if (cfg.m_lc_prog_pull_agent_cfg.vif.req === 1'b1) return; - - if (blocking) begin - req_lc_transition_sub(check_intr, wr_blank_err); - end else begin - fork - begin - req_lc_transition_sub(check_intr, wr_blank_err); - end - join_none; - // Add #0 to ensure that this thread starts executing before any subsequent call - #0; - end - endtask - - virtual task req_lc_transition_sub(bit check_intr = 0, bit wr_blank_err = !write_unused_addr); - lc_ctrl_state_pkg::lc_cnt_e next_lc_cnt; - lc_ctrl_state_pkg::dec_lc_state_e next_lc_state, lc_state_dec; - bit [TL_DW-1:0] intr_val; - push_pull_host_seq#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1)) - lc_prog_pull_seq; - wait(cfg.under_reset == 0); - `uvm_create_on(lc_prog_pull_seq, p_sequencer.lc_prog_pull_sequencer_h); - - if (!wr_blank_err) begin - // Find valid next state and next cnt using lc_ctrl_dv_utils_pkg. - // If terminal state or max LcCnt reaches, will not program any new data. - if ((lc_state != LcStScrap) && (lc_cnt != LcCnt24)) begin - lc_state_dec = lc_ctrl_dv_utils_pkg::dec_lc_state(lc_state); - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(next_lc_state, - next_lc_state inside {VALID_NEXT_STATES[lc_state_dec]};) - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(next_lc_cnt, next_lc_cnt > lc_cnt;) - lc_state = lc_ctrl_dv_utils_pkg::encode_lc_state(next_lc_state); - lc_cnt = next_lc_cnt; - end - cfg.m_lc_prog_pull_agent_cfg.add_h_user_data({lc_cnt, lc_state}); - end - - `DV_CHECK_RANDOMIZE_FATAL(lc_prog_pull_seq) - `uvm_send(lc_prog_pull_seq) - - if (check_intr) rd_and_clear_intrs(); - endtask - - // This test access OTP_CTRL's test_access memory. The open-sourced code only test if the access - // is valid. Please override this task in proprietary OTP. - virtual task otp_test_access(); - if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin - repeat (10) begin - bit [TL_DW-1:0] data; - bit test_access_en; - bit [TL_AW-1:0] rand_addr = $urandom_range(0, NUM_PRIM_REG - 1) * 4; - bit [TL_AW-1:0] tlul_addr = - cfg.ral_models["otp_ctrl_prim_reg_block"].get_addr_from_offset(rand_addr); - if (cfg.stop_transaction_generators()) break; - rand_drive_dft_en(); - `DV_CHECK_STD_RANDOMIZE_FATAL(data) - test_access_en = cfg.otp_ctrl_vif.lc_dft_en_i == lc_ctrl_pkg::On; - tl_access(.addr(tlul_addr), .write(1), .data(data), .exp_err_rsp(~test_access_en), - .tl_sequencer_h(p_sequencer.tl_sequencer_hs["otp_ctrl_prim_reg_block"])); - tl_access(.addr(tlul_addr), .write(0), .data(data), .exp_err_rsp(~test_access_en), - .tl_sequencer_h(p_sequencer.tl_sequencer_hs["otp_ctrl_prim_reg_block"])); - end - end - endtask - - // Empty task, only drive it under `otp_ctrl_test_access_vseq` - virtual task rand_drive_dft_en(); - endtask -endclass : otp_ctrl_base_vseq diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_callback_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_callback_vseq.sv deleted file mode 100644 index 155e6f5e3615c..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_callback_vseq.sv +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// A sequence hook to attach to otp_ctrl_base_vseq. -class otp_ctrl_callback_vseq extends cip_base_vseq #( - .RAL_T (otp_ctrl_core_reg_block), - .CFG_T (otp_ctrl_env_cfg), - .COV_T (otp_ctrl_env_cov), - .VIRTUAL_SEQUENCER_T (otp_ctrl_virtual_sequencer) - ); - `uvm_object_utils(otp_ctrl_callback_vseq) - `uvm_object_new - - virtual task dut_init_callback(); - // Do nothing but can be overridden in closed source environment. - endtask - - virtual task post_otp_pwr_init(); - // Do nothing but can be overridden in closed source environment. - endtask : post_otp_pwr_init -endclass : otp_ctrl_callback_vseq diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv deleted file mode 100644 index 061ebe96a30a0..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This sequence creates the following check failure scenarios: -// 1. Check timeout -// 2. Correctable ECC check error -// 3. Uncorrectable ECC error -class otp_ctrl_check_fail_vseq extends otp_ctrl_dai_lock_vseq; - `uvm_object_utils(otp_ctrl_check_fail_vseq) - - `uvm_object_new - - constraint ecc_otp_err_c { - ecc_otp_err inside {OtpEccCorrErr, OtpNoEccErr}; - } - - constraint ecc_chk_err_c { - ecc_chk_err dist {OtpNoEccErr :/ 1, - OtpEccCorrErr :/ 1, - OtpEccUncorrErr :/1 }; - } - - // 50% chance of having a check timeout - // Because of the regwen, even though we constrain the timeout value, it might not apply to the - // DUT. - constraint check_timeout_val_c { - check_timeout_val dist {[1 : CHK_TIMEOUT_CYC] :/ 1, - [100_000 :'1] :/ 1}; - } - -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_common_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_common_vseq.sv deleted file mode 100644 index 58f419c77c0ad..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_common_vseq.sv +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_common_vseq extends otp_ctrl_base_vseq; - `uvm_object_utils(otp_ctrl_common_vseq) - - rand bit [TL_DW-1:0] dai_addr, wdata0, wdata1; - rand port_drive_condition_e reset_drive_cond; - - string prim_otp_alert_name = "fatal_prim_otp_alert"; - string integ_err_alert_name = "fatal_bus_integ_error"; - - // This flag is used to identify if the sec_cm or tl_intg_err uses prim_otp_tl_i/o. - protected bit is_prim_otp; - - constraint dai_addr_c { - dai_addr dist { - [0 : (PartInfo[LifeCycleIdx].offset - 1)] :/ 1, - [PartInfo[LifeCycleIdx].offset : {OTP_ADDR_WIDTH{1'b1}}] :/ 1}; - } - - constraint reset_drive_cond_c { - reset_drive_cond dist { - DriveRandomly :/ 7, - DuringOTPDaiBusy :/ 1, - DuringOTPRead :/ 1, - DuringOTPDaiDigest :/ 1 - }; - } - - constraint num_trans_c { - num_trans inside {[1:2]}; - } - `uvm_object_new - - virtual task dut_init(string reset_kind = "HARD"); - super.dut_init(reset_kind); - // drive dft_en pins to access the test_access memory - cfg.otp_ctrl_vif.drive_lc_dft_en(lc_ctrl_pkg::On); - // once turn on lc_dft_en regiser, will need some time to update the state register - // two clock cycles for lc_async mode, one clock cycle for driving dft_en, one more clock cycle - // so there is no racing condition. - if (cfg.en_dv_cdc) cfg.clk_rst_vif.wait_clks(5); - else cfg.clk_rst_vif.wait_clks(3); - endtask - - virtual task body(); - if (common_seq_type == "sec_cm_fi") begin - // OTP_CTRL has many sec_cm items, so too many iterations of this test will consume too much - // simulation time and eventually causes timeout. So we reduce to 10 iterations. - run_sec_cm_fi_vseq(10); - end else begin - run_common_vseq_wrapper(num_trans); - end - endtask : body - - virtual task apply_resets_concurrently(int reset_duration_ps = 0); - // For stress_all_with_rand_reset test only - backdoor clear OTP memory, - // and re-initialize OTP_ctrl after reset. - if (common_seq_type == "stress_all_with_rand_reset") begin - cfg.otp_ctrl_vif.release_part_access_mubi(); - cfg.otp_ctrl_vif.drive_lc_escalate_en(lc_ctrl_pkg::Off); - // Set dft_en to On to allow the csr_test to check all registers' default value after reset. - cfg.otp_ctrl_vif.drive_lc_dft_en(lc_ctrl_pkg::On); - otp_ctrl_init(); - otp_pwr_init(); - super.apply_resets_concurrently(reset_duration_ps); - cfg.en_scb = 1; - end else begin - super.apply_resets_concurrently(reset_duration_ps); - end - clear_seq_flags(); - endtask - - virtual task wait_to_issue_reset(uint reset_delay_bound = 10_000_000); - `DV_CHECK_MEMBER_RANDOMIZE_FATAL(reset_drive_cond) - case (reset_drive_cond) - DriveRandomly: begin - super.wait_to_issue_reset(reset_delay_bound); - end - DuringOTPDaiBusy: begin - `DV_SPINWAIT_EXIT( - wait (do_otp_wr); - cfg.clk_rst_vif.wait_clks($urandom_range(1, 70));, - super.wait_to_issue_reset(reset_delay_bound);) - #($urandom_range(0, cfg.clk_rst_vif.clk_period_ps) * 1ps); - end - DuringOTPDaiDigest: begin - `DV_SPINWAIT_EXIT( - wait (do_digest_cal); - cfg.clk_rst_vif.wait_clks($urandom_range(1, 350));, - super.wait_to_issue_reset(reset_delay_bound);) - #($urandom_range(0, cfg.clk_rst_vif.clk_period_ps) * 1ps); - end - DuringOTPRead: begin - `DV_SPINWAIT_EXIT( - wait (do_otp_rd); - cfg.clk_rst_vif.wait_clks($urandom_range(1, 10));, - super.wait_to_issue_reset(reset_delay_bound);) - #($urandom_range(0, cfg.clk_rst_vif.clk_period_ps) * 1ps); - end - default: `uvm_fatal(`gfn, $sformatf("Unsupported reset_drive_cond %0d", reset_drive_cond)) - endcase - endtask : wait_to_issue_reset - - // This task overrides the check for `prim_onehot_check` and `tl_intg_error`. - // Alerts coming from the `prim_otp` module will only bypass OTP_CTRL, it won't affect the - // OTP_CTRL and will fire its own alerts. - virtual task check_tl_intg_error_response(); - if (is_prim_otp) begin - repeat ($urandom_range(5, 20)) begin - wait_alert_trigger(prim_otp_alert_name, .wait_complete(1)); - end - end else begin - super.check_tl_intg_error_response(); - end - endtask - - virtual task check_sec_cm_alert(string sec_type_name, string alert_name); - `uvm_info(`gfn, $sformatf("expected fatal alert is triggered for %s", - sec_type_name), UVM_LOW) - - // This is a fatal alert and design keeps sending it until reset is issued. - // Check alerts are triggered for a few times - repeat (5) begin - wait_alert_trigger(alert_name, .wait_complete(1)); - end - endtask - - // In tl_intg_err test, override this task to set is_prim_otp flag. - virtual task run_tl_intg_err_vseq_sub(string ral_name); - if (ral_name == "otp_ctrl_prim_reg_block") is_prim_otp = 1; - else is_prim_otp = 0; - super.run_tl_intg_err_vseq_sub(ral_name); - endtask - - virtual task check_sec_cm_fi_resp(sec_cm_base_if_proxy if_proxy); - bit [TL_DW-1:0] exp_status_val, rdata0, rdata1; - string prim_otp_alert_name = "fatal_prim_otp_alert"; - string integ_err_alert_name = "fatal_bus_integ_error"; - - // Alerts coming from the `prim_otp` module will only bypass OTP_CTRL, it won't affect the - // OTP_CTRL and will fire its own alerts. - if (is_prim_otp) begin - check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name); - - // Alerts coming from the `u_tlul_lc_gate` module will only trigger bus_integrity alerts, and - // bus_integrity related status. - // This error won't local escalate to OTP partitions. - end else if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin - check_sec_cm_alert(if_proxy.sec_cm_type.name, integ_err_alert_name); - - exp_status_val[OtpBusIntegErrorIdx] = 1; - exp_status_val[OtpDaiIdleIdx] = 1; - - // All other errors triggers normal fatal alerts, and will locally escalate to other - // partitions. - end else begin - super.check_sec_cm_fi_resp(if_proxy); - - // Set expected status error val. - for (int i = 0; i <= OtpLciErrIdx; i++) exp_status_val[i] = 1; - if (!uvm_re_match("*.u_otp_ctrl_lfsr_timer*", if_proxy.path)) begin - exp_status_val[OtpLfsrFsmErrIdx] = 1; - end else if (!uvm_re_match("*u_otp_ctrl_kdi*", if_proxy.path)) begin - exp_status_val[OtpDerivKeyFsmErrIdx] = 1; - end else if (!uvm_re_match("*u_otp_ctrl_scrmbl*", if_proxy.path)) begin - exp_status_val[OtpScramblingFsmErrIdx] = 1; - end - - csr_rd_check(.ptr(ral.status), .compare_value(exp_status_val), .err_msg( - $sformatf("cm_fi status failed at injection %0s", if_proxy.sec_cm_type.name))); - - // Check OTP is locked after fault error. - `DV_CHECK_RANDOMIZE_FATAL(this) - is_valid_dai_op = 0; - - // Access OTP via DAI interface. - dai_wr(dai_addr, wdata0, wdata1); - dai_rd(dai_addr, rdata0, rdata1); - `DV_CHECK_EQ(rdata0, 0) - `DV_CHECK_EQ(rdata1, 0) - if (is_sw_part(dai_addr)) begin - uvm_reg_addr_t tlul_addr = cfg.ral.get_addr_from_offset(get_sw_window_offset(dai_addr)); - tl_access(.addr(tlul_addr), .write(0), .data(rdata0), .blocking(1), .check_rsp(1), - .exp_err_rsp(1), .exp_data('1)); - end - cal_hw_digests(); - write_sw_digests(); - - // Access OTP via app interface. - if ($urandom_range(0, 1)) req_otbn_key(0); - if ($urandom_range(0, 1)) req_flash_addr_key(0); - if ($urandom_range(0, 1)) req_flash_data_key(0); - if ($urandom_range(0, 1)) req_all_sram_keys(0); - cfg.clk_rst_vif.wait_clks($urandom_range(10, 20)); - - csr_rd_check(.ptr(ral.status), .compare_value(exp_status_val), - .err_msg("status failure after OTP fatal fault error")); - end - endtask : check_sec_cm_fi_resp - - virtual function void sec_cm_fi_ctrl_svas(sec_cm_base_if_proxy if_proxy, bit enable); - case (if_proxy.sec_cm_type) - SecCmPrimCount: begin - if (!enable) begin - $assertoff(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $assertoff(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $assertoff(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $assertoff(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $assertoff(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A"); - end else begin - $asserton(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $asserton(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $asserton(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $asserton(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A"); - $asserton(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A"); - end - end - SecCmPrimSparseFsmFlop, SecCmPrimDoubleLfsr, SecCmPrimOnehot: begin - // No assertion error. - end - default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name)) - endcase - - // Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if. - if (!uvm_re_match("*.u_otp.*", if_proxy.path)) is_prim_otp = 1; - else is_prim_otp = 0; - endfunction: sec_cm_fi_ctrl_svas - -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_errs_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_errs_vseq.sv deleted file mode 100644 index c8ea43b32a6bc..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_errs_vseq.sv +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// otp_ctrl_dai_errs_vseq is developed to randomly read/write to any address within OTP: -// - A writeblank error will be triggered if write to a non-empty address -// - An access error will be triggered if write to lc partition via DAI interface, or if DAI write -// to digest addrs for non-sw partitions -class otp_ctrl_dai_errs_vseq extends otp_ctrl_dai_lock_vseq; - `uvm_object_utils(otp_ctrl_dai_errs_vseq) - - bit[31:0] exp_status; - `uvm_object_new - - // Only run one transition to avoid dut_init in the sequence. Because write-blank-error can cause - // otp_init failure. - constraint num_trans_c { - num_trans == 1; - num_dai_op inside {[100:500]}; - } - - constraint regwens_c { - check_trigger_regwen_val == 0; - } - - constraint rd_check_after_wr_c { - rand_wr == rand_rd; - } - - function void pre_randomize(); - this.dai_wr_blank_addr_c.constraint_mode(0); - this.no_access_err_c.constraint_mode(0); - this.dai_wr_digests_c.constraint_mode(0); - write_unused_addr = 0; - endfunction - - task body(); - do_apply_reset = 0; - if (do_lc_trans && !cfg.otp_ctrl_vif.alert_reqs) begin - req_lc_transition(do_lc_trans, lc_prog_blocking); - end - super.body(); - endtask - - virtual task post_start(); - expect_fatal_alerts = 1; - do_apply_reset = 1; - do_otp_ctrl_init = 1; - super.post_start(); - endtask -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv deleted file mode 100644 index c02559aded48e..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_dai_lock_vseq.sv +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -// otp_ctrl_dai_lock_vseq is developed to read/write lock DAI interface by partitions, and request -// read/write access to check if correct status and error code is triggered - -// Partition's legal range covers offset to digest addresses, dai_rd/dai_wr function will -// randomize the address based on the granularity. -`define PART_ADDR_RANGE(i) \ - {[PartInfo[``i``].offset : (PartInfo[``i``].offset + PartInfo[``i``].size - 8)]} - -class otp_ctrl_dai_lock_vseq extends otp_ctrl_smoke_vseq; - `uvm_object_utils(otp_ctrl_dai_lock_vseq) - - `uvm_object_new - - // enable access_err for each cycle - constraint no_access_err_c {access_locked_parts == 1;} - - constraint num_trans_c { - num_trans inside {[1:10]}; - num_dai_op inside {[1:50]}; - } - - // the LC partition is always the last one - constraint partition_index_c {part_idx inside {[0:LifeCycleIdx]};} - - constraint dai_wr_legal_addr_c { - if (part_idx == VendorTestIdx) { - dai_addr inside `PART_ADDR_RANGE(VendorTestIdx); - } - if (part_idx == CreatorSwCfgIdx) { - dai_addr inside `PART_ADDR_RANGE(CreatorSwCfgIdx); - } - if (part_idx == OwnerSwCfgIdx) { - dai_addr inside `PART_ADDR_RANGE(OwnerSwCfgIdx); - } - if (part_idx == RotCreatorAuthCodesignIdx) { - dai_addr inside `PART_ADDR_RANGE(RotCreatorAuthCodesignIdx); - } - if (part_idx == RotCreatorAuthStateIdx) { - dai_addr inside `PART_ADDR_RANGE(RotCreatorAuthStateIdx); - } - if (part_idx == HwCfg0Idx) { - dai_addr inside `PART_ADDR_RANGE(HwCfg0Idx); - } - if (part_idx == HwCfg1Idx) { - dai_addr inside `PART_ADDR_RANGE(HwCfg1Idx); - } - if (part_idx == Secret0Idx) { - dai_addr inside `PART_ADDR_RANGE(Secret0Idx); - } - if (part_idx == Secret1Idx) { - dai_addr inside `PART_ADDR_RANGE(Secret1Idx); - } - if (part_idx == Secret2Idx) { - dai_addr inside `PART_ADDR_RANGE(Secret2Idx); - } - if (part_idx == LifeCycleIdx) { - if (write_unused_addr) { - dai_addr inside {[PartInfo[LifeCycleIdx].offset : {OTP_ADDR_WIDTH{1'b1}}]}; - } else { - dai_addr inside `PART_ADDR_RANGE(LifeCycleIdx); - } - } - solve part_idx before dai_addr; - } - - constraint dai_wr_digests_c { - {dai_addr[TL_AW-1:2], 2'b0} dist { - { - VendorTestDigestOffset, - CreatorSwCfgDigestOffset, - OwnerSwCfgDigestOffset, - RotCreatorAuthCodesignDigestOffset, - RotCreatorAuthStateDigestOffset, - HwCfg0DigestOffset, - HwCfg1DigestOffset, - Secret0DigestOffset, - Secret1DigestOffset, - Secret2DigestOffset - } :/ 1, - [VendorTestOffset : '1] :/ 9 - }; - } - - virtual task pre_start(); - super.pre_start(); - is_valid_dai_op = 0; - endtask - - virtual task dut_init(string reset_kind = "HARD"); - super.dut_init(reset_kind); - if ($urandom_range(0, 1)) begin - cfg.otp_ctrl_vif.drive_lc_creator_seed_sw_rw_en(get_rand_lc_tx_val(.t_weight(0))); - end - if ($urandom_range(0, 1)) begin - cfg.otp_ctrl_vif.drive_lc_owner_seed_sw_rw_en(get_rand_lc_tx_val(.t_weight(0))); - end - endtask - -endclass - -`undef PART_ADDR_RANGE diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_init_fail_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_init_fail_vseq.sv deleted file mode 100644 index 6a5a2526f4ed4..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_init_fail_vseq.sv +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Otp_ctrl_init_fail_vseq is developed to check if otp_ctrl reacts correctly if initialization -// failed. -// Note that scoreboard is disabled in this test and all checks are done within this sequence. -// This test writes and reads to OTP_memory via DAI interface, then triggers digest calculations. -// Afterwards instead of issuing reset, this sequence continues to write to DAI interface. -// If any of the hardware partition is updated, then in next power cycle, the initialization will -// fail. -// If no check failure, we will random inject ECC errors to create init macro errors. -// We will also trigger sw partition ECC reg failure by forcing the ECC reg error output. -// -// This sequence will check the following items if OTP init failed with fatal error: -// - Otp_initialization failure triggers fatal alert -// - Status register reflect the correct error -// - Otp_ctrl's power init output stays 0 -// This sequence will check the following items if OTP init failed with correctable error: -// - Otp_initialtion passed with power init output changes to 1 -// - Otp status and interrupt reflect the correct error message - -class otp_ctrl_init_fail_vseq extends otp_ctrl_smoke_vseq; - `uvm_object_utils(otp_ctrl_init_fail_vseq) - - `uvm_object_new - - rand uint num_to_lock_digests; - bit [NumPart-1:0] init_chk_err; - bit part_locked; - - // If num_to_lock_digests is larger than num_dai_op, that means there won't be OTP init check - // error, so this sequence will trigger ECC error instead. - // We set 25% possibility that OTP init check fails due to writing OTP after digest is locked. - constraint lock_digest_c {num_to_lock_digests < num_dai_op * 4;} - constraint num_iterations_c {num_dai_op inside {[20:100]};} - constraint ecc_otp_err_c { - $countones(ecc_otp_err) dist {OtpNoEccErr :/ 2, - OtpEccCorrErr :/ 2, - OtpEccUncorrErr :/ 1}; - } - - virtual task pre_start(); - super.pre_start(); - num_to_lock_digests.rand_mode(0); - endtask - - task body(); - bit [TL_DW-1:0] exp_status; - `uvm_info(`gfn, $sformatf("Number of dai operation is %0d, number to lock digest is %0d", - num_dai_op, num_to_lock_digests), UVM_MEDIUM) - - for (uint i = 0; i <= num_dai_op; i++) begin - bit [TL_DW-1:0] tlul_val; - if (cfg.stop_transaction_generators()) return; - - `DV_CHECK_RANDOMIZE_FATAL(this) - `uvm_info(`gfn, $sformatf("starting dai access seq %0d/%0d with addr %0h in partition %0d", - i, num_dai_op, dai_addr, part_idx), UVM_MEDIUM) - - if (i > num_to_lock_digests && PartInfo[part_idx].hw_digest && - !used_dai_addrs.exists(dai_addr)) begin - init_chk_err[part_idx] = 1; - end - - // OTP write via DAI - dai_wr(dai_addr, wdata0, wdata1); - - // OTP read via DAI, check data in scb - dai_rd(dai_addr, wdata0, wdata1); - - // If write sw partitions, check tlul window - if (is_sw_part(dai_addr)) begin - uvm_reg_addr_t tlul_addr = cfg.ral.get_addr_from_offset(get_sw_window_offset(dai_addr)); - tl_access(.addr(tlul_addr), .write(0), .data(tlul_val), .blocking(1), .check_rsp(0)); - end - - if (i == num_to_lock_digests) begin - cal_hw_digests('1); - part_locked = 1; - end - - csr_rd(ral.status, tlul_val); - end - - do_otp_ctrl_init = 0; - do_otp_pwr_init = 0; - cfg.en_scb = 0; - dut_init(); - - if (init_chk_err) begin - `uvm_info(`gfn, $sformatf("OTP_init check failure with init error = %0h", init_chk_err), - UVM_LOW) - foreach(init_chk_err[i]) begin - if (cfg.stop_transaction_generators()) break; - if (init_chk_err[i]) exp_status |= 1'b1 << i; - end - - check_otp_fatal_err("fatal_check_error", exp_status); - - // If not check error, force ECC correctable and uncorrectable error - end else begin - bit is_fatal, is_correctable; - bit [TL_DW-1:0] addr; - - for (int i = 0; i < NumPart; i++) begin - if (cfg.stop_transaction_generators()) return; - `DV_CHECK_RANDOMIZE_FATAL(this); - - if (PartInfo[i].sw_digest) begin - // During OTP init, SW partitions only read digest value - addr = PART_OTP_DIGEST_ADDRS[i] << 2; - end else begin - // During OTP init, non SW partitions read all value - addr = $urandom_range(PartInfo[i].offset, PartInfo[i].offset + PartInfo[i].size - 1); - end - - void'(backdoor_inject_ecc_err(addr, ecc_otp_err)); - // VendorTest partition's ECC error is not fatal. - if (!is_fatal && ecc_otp_err == OtpEccUncorrErr && part_has_integrity(i)) begin - is_fatal = 1; - end else if (!is_correctable && ecc_otp_err == OtpEccCorrErr && part_has_integrity(i)) begin - is_correctable = 1; - end - if (ecc_otp_err != OtpNoEccErr && part_has_integrity(i)) exp_status[i] = 1; - end - - if (is_fatal) begin - // ECC uncorrectable error. - `uvm_info(`gfn, "OTP_init macro ECC uncorrectable failure", UVM_LOW) - check_otp_fatal_err("fatal_macro_error", exp_status); - end else if ($urandom_range(0, 1)) begin - - // Randomly force ECC reg in sw partitions to create a check failure. - // Totaly three sw partitions, and each bit indexes a partition. - bit [NumPartUnbuf-1:0] sw_check_fail = $urandom_range(1, (1'b1< 1 && do_dut_init) dut_init(); - // after otp-init done, check status - cfg.clk_rst_vif.wait_clks(1); - if (!cfg.otp_ctrl_vif.lc_esc_on) begin - csr_rd_check(.ptr(ral.status.dai_idle), .compare_value(1)); - end - end - do_otp_ctrl_init = 0; - - `DV_CHECK_RANDOMIZE_FATAL(this) - // set consistency and integrity checks - csr_wr(ral.check_regwen, check_regwen_val); - csr_wr(ral.check_trigger_regwen, check_trigger_regwen_val); - csr_wr(ral.check_timeout, check_timeout_val); - trigger_checks(.val(check_trigger_val), .wait_done(1), .ecc_err(ecc_chk_err)); - - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_rd_locks(); - - // Backdoor write mubi to values that are not true or false. - force_mubi_part_access(); - - if (do_req_keys && !cfg.otp_ctrl_vif.alert_reqs) begin - req_otbn_key(); - req_flash_addr_key(); - req_flash_data_key(); - req_all_sram_keys(); - end - if (do_lc_trans && !cfg.otp_ctrl_vif.alert_reqs) begin - req_lc_transition(do_lc_trans, lc_prog_blocking); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - for (int i = 0; i < num_dai_op; i++) begin - bit [TL_DW-1:0] rdata0, rdata1, backdoor_rd_val; - if (cfg.stop_transaction_generators()) break; - - `DV_CHECK_RANDOMIZE_FATAL(this) - // recalculate part_idx in case some test turn off constraint dai_wr_legal_addr_c - part_idx = part_idx_e'(get_part_index(dai_addr)); - `uvm_info(`gfn, $sformatf("starting dai access seq %0d/%0d with addr %0h in partition %0d", - i, num_dai_op, dai_addr, part_idx), UVM_HIGH) - - // OTP write via DAI - if (rand_wr && !digest_calculated[part_idx]) begin - dai_wr(dai_addr, wdata0, wdata1); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - // Inject ECC error. - if (ecc_otp_err != OtpNoEccErr && dai_addr < LifeCycleOffset) begin - `uvm_info(`gfn, $sformatf("Injecting ecc error %0d at 0x%x", ecc_otp_err, dai_addr), - UVM_HIGH) - backdoor_rd_val = backdoor_inject_ecc_err(dai_addr, ecc_otp_err); - end - - if (rand_rd) begin - // OTP read via DAI, check data in scb - dai_rd(dai_addr, rdata0, rdata1); - end - - // if write sw partitions, check tlul window - if (is_sw_part(dai_addr) && rd_sw_tlul_rd) begin - uvm_reg_addr_t tlul_addr = cfg.ral.get_addr_from_offset(get_sw_window_offset(dai_addr)); - // tlul error rsp is checked in scoreboard - do_otp_rd = 1; - tl_access(.addr(tlul_addr), .write(0), .data(tlul_val), .blocking(1), .check_rsp(0)); - end - - // Backdoor restore injected ECC error, but should not affect fatal alerts. - if (ecc_otp_err != OtpNoEccErr && dai_addr < LifeCycleOffset) begin - `uvm_info(`gfn, $sformatf("Injecting ecc error %0d at 0x%x", ecc_otp_err, dai_addr), - UVM_HIGH) - cfg.mem_bkdr_util_h.write32({dai_addr[TL_DW-3:2], 2'b00}, backdoor_rd_val); - // Wait for two lock cycles to make sure the local escalation error propagates to other - // patitions and err_code reg. - cfg.clk_rst_vif.wait_clks(2); - end - - // Random lock sw partitions - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_rd_locks(); - if (!$urandom_range(0, 9) && access_locked_parts) write_sw_digests(); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.direct_access_regwen), .value(tlul_val)); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.status), .value(tlul_val)); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - // Read/write test access memory - otp_test_access(); - - // lock digests - `uvm_info(`gfn, "Trigger HW digest calculation", UVM_HIGH) - cal_hw_digests(); - if ($urandom_range(0, 1)) csr_rd(.ptr(ral.status), .value(tlul_val)); - - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - - if ($urandom_range(0, 1)) rd_digests(); - if (do_dut_init) dut_init(); - - // read and check digest in scb - rd_digests(); - - // send request to the interfaces again after partitions are locked - if (do_lc_trans && !cfg.otp_ctrl_vif.alert_reqs) begin - req_lc_transition(do_lc_trans, lc_prog_blocking); - if (cfg.otp_ctrl_vif.lc_prog_req == 0) begin - for (int k = 0; k <= LciIdx; k++) begin - csr_rd(.ptr(ral.err_code[k]), .value(tlul_val)); - end - end - end - - if (do_req_keys && !cfg.otp_ctrl_vif.alert_reqs && !cfg.smoke_test) begin - req_otbn_key(); - req_flash_addr_key(); - req_flash_data_key(); - req_all_sram_keys(); - end - - end - - endtask : body - -endclass : otp_ctrl_smoke_vseq - -`undef PART_CONTENT_RANGE diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_stress_all_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_stress_all_vseq.sv deleted file mode 100644 index 031f5a15d2053..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_stress_all_vseq.sv +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Combine all otp_ctrl seqs (except below seqs) in one seq to run sequentially. -// Exception: - csr seq: requires scb to be disabled -// - regwen_vseq and parallel_lc_vseq: time sensitive thus require zero_delays -// - macro_errs_vseq and check_fail_vseq: require to write back to OTP once fatal -// error is triggered, thus does not handle random reset -// - partition_walk_vseq: assume OTP initial value is 0 -// - init_fail: requires resets in the middle of the sequence -class otp_ctrl_stress_all_vseq extends otp_ctrl_base_vseq; - `uvm_object_utils(otp_ctrl_stress_all_vseq) - - string seq_names[]; - - `uvm_object_new - - virtual function void assign_seq_names(); - seq_names = {"otp_ctrl_common_vseq", - "otp_ctrl_dai_lock_vseq", - "otp_ctrl_smoke_vseq", - "otp_ctrl_test_access_vseq", - "otp_ctrl_background_chks_vseq", - "otp_ctrl_parallel_lc_esc_vseq", - "otp_ctrl_parallel_lc_req_vseq", - "otp_ctrl_parallel_key_req_vseq", - "otp_ctrl_dai_errs_vseq", - "otp_ctrl_low_freq_read_vseq"}; - endfunction - - task body(); - assign_seq_names(); - - for (int i = 1; i <= num_trans; i++) begin - uvm_sequence seq; - otp_ctrl_base_vseq otp_ctrl_vseq; - uint seq_idx = $urandom_range(0, seq_names.size - 1); - - seq = create_seq_by_name(seq_names[seq_idx]); - `downcast(otp_ctrl_vseq, seq) - `uvm_info(`gfn, $sformatf("Starting sequence %s in stress_all", otp_ctrl_vseq.get_name()), - UVM_MEDIUM) - - // At the end of each vseq, design might enter terminal Error State, need to reset to - // recover. If upper seq disables do_apply_reset for this seq, then can't issue reset - // as upper seq may drive reset. - if (do_apply_reset) otp_ctrl_vseq.do_apply_reset = 1; - else otp_ctrl_vseq.do_apply_reset = 0; - - otp_ctrl_vseq.set_sequencer(p_sequencer); - `DV_CHECK_RANDOMIZE_FATAL(otp_ctrl_vseq) - if (seq_names[seq_idx] == "otp_ctrl_common_vseq") begin - otp_ctrl_common_vseq common_vseq; - `downcast(common_vseq, otp_ctrl_vseq); - common_vseq.common_seq_type = "intr_test"; - end - - // Pass local variables to next sequence due to randomly issued reset. - otp_ctrl_vseq.is_valid_dai_op = 0; - otp_ctrl_vseq.lc_prog_blocking = this.lc_prog_blocking; - otp_ctrl_vseq.digest_calculated = this.digest_calculated; - otp_ctrl_vseq.start(p_sequencer); - - this.lc_prog_blocking = otp_ctrl_vseq.lc_prog_blocking; - this.digest_calculated = otp_ctrl_vseq.digest_calculated; - - // This is for otp_ctrl_stress_all_with_rand_reset. - // We need to reset for each vseq, but in otp_ctrl_stress_all_with_rand_reset, reset should be - // issued in upper seq. So, wait forever until reset is issued and this vseq is killed by - // upper seq. - if (!do_apply_reset) wait(0); - - // This is only valid for stress_all sequence. - // For stress_all_with_rand_reset sequence, the logic will be gated at previous line and will - // enable scb again at `apply_resets_concurrently` task. - cfg.en_scb = 1; - end - endtask : body - -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_test_access_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_test_access_vseq.sv deleted file mode 100644 index fbdb51f23a628..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_test_access_vseq.sv +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_test_access_vseq extends otp_ctrl_dai_lock_vseq; - `uvm_object_utils(otp_ctrl_test_access_vseq) - - `uvm_object_new - - virtual task dut_init(string reset_kind = "HARD"); - super.dut_init(reset_kind); - - // Drive dft_en pins to access the test_access memory. - cfg.otp_ctrl_vif.drive_lc_dft_en(lc_ctrl_pkg::On); - - // Once turn on lc_dft_en register, will need some time to update the state register - // two clock cycles for lc_async mode, one clock cycle for driving dft_en. - if (cfg.en_dv_cdc) cfg.clk_rst_vif.wait_clks(4); - else cfg.clk_rst_vif.wait_clks(3); - endtask - - // Avoid back-to-back lc_dft_en initializations with random values since CDC can cause - // temporary On values when transitioning between arbitrary values. This is not a realistic - // attack mode since - // - The value is always driven as On or Off in hardware, - // - Mubi cannot protect against all bits being glitched, - // - getting an ON value due to CDC requires the mubi values before and after the CDC transition - // to have close enough Hamming distance to On, and is as hard or harder than glitching all - // bits to On. - virtual task rand_drive_dft_en(); - static bit phase; - super.rand_drive_dft_en(); - // 25% chance drive lc_dft_en to a random value. - if ($urandom_range(0, 3) == 3) begin - cfg.otp_ctrl_vif.drive_lc_dft_en(get_rand_lc_tx_val( - .t_weight(1), .f_weight(1), .other_weight(phase))); - phase = !phase; - // Once turn on lc_dft_en regiser, will need some time to update the state register - // two clock cycles for lc_async mode, one clock cycle for driving dft_en. - if (cfg.en_dv_cdc) cfg.clk_rst_vif.wait_clks(4); - else cfg.clk_rst_vif.wait_clks(3); - end - endtask -endclass diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv deleted file mode 100644 index 3cf96c1b52180..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -`include "otp_ctrl_callback_vseq.sv" -`include "otp_ctrl_base_vseq.sv" -`include "otp_ctrl_wake_up_vseq.sv" -`include "otp_ctrl_smoke_vseq.sv" -`include "otp_ctrl_common_vseq.sv" -`include "otp_ctrl_partition_walk_vseq.sv" -`include "otp_ctrl_low_freq_read_vseq.sv" -`include "otp_ctrl_init_fail_vseq.sv" -`include "otp_ctrl_dai_lock_vseq.sv" -`include "otp_ctrl_dai_errs_vseq.sv" -`include "otp_ctrl_macro_errs_vseq.sv" -`include "otp_ctrl_background_chks_vseq.sv" -`include "otp_ctrl_check_fail_vseq.sv" -`include "otp_ctrl_parallel_base_vseq.sv" -`include "otp_ctrl_parallel_key_req_vseq.sv" -`include "otp_ctrl_parallel_lc_req_vseq.sv" -`include "otp_ctrl_parallel_lc_esc_vseq.sv" -`include "otp_ctrl_regwen_vseq.sv" -`include "otp_ctrl_test_access_vseq.sv" -`include "otp_ctrl_stress_all_vseq.sv" diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv deleted file mode 100644 index 8a048e5e560f6..0000000000000 --- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_wake_up_vseq extends otp_ctrl_base_vseq; - `uvm_object_utils(otp_ctrl_wake_up_vseq) - - `uvm_object_new - - virtual task otp_ctrl_init(); - super.otp_ctrl_init(); - csr_wr(ral.intr_enable, en_intr); - endtask - - task body(); - bit [TL_DW-1:0] rand_addr = $urandom_range(CreatorSwCfgOffset, - CreatorSwCfgOffset + CreatorSwCfgSize); - // check status - cfg.clk_rst_vif.wait_clks(1); - - // turn on all intr_enable - csr_wr(ral.intr_enable, (1'b1 << NumOtpCtrlIntr) - 1); - csr_rd_check(.ptr(ral.status.dai_idle), .compare_value(1)); - - // write seq - csr_wr(ral.direct_access_address, rand_addr); - csr_wr(ral.direct_access_wdata[0], '1); - csr_wr(ral.direct_access_cmd, 2); - wait(cfg.intr_vif.pins[OtpOperationDone] == 1); - csr_wr(ral.intr_state, 1'b1 << OtpOperationDone); - - // read seq - csr_wr(ral.direct_access_address, rand_addr); - csr_wr(ral.direct_access_cmd, 1); - wait(cfg.intr_vif.pins[OtpOperationDone] == 1); - csr_rd_check(.ptr(ral.direct_access_rdata[0]), .compare_value('1)); - csr_wr(ral.intr_state, 1'b1 << OtpOperationDone); - - // digest sw error seq - csr_wr(ral.direct_access_address, CreatorSwCfgOffset + 2); - csr_wr(ral.direct_access_cmd, 4); - wait(cfg.intr_vif.pins[OtpOperationDone] == 1); - wait(cfg.intr_vif.pins[OtpErr] == 1); - csr_wr(ral.intr_state, (1'b1 << NumOtpCtrlIntr) - 1); - - // digest hw seq - csr_wr(ral.direct_access_address, HwCfg0DigestOffset); - csr_wr(ral.direct_access_cmd, 4); - wait(cfg.intr_vif.pins[OtpOperationDone] == 1); - csr_wr(ral.intr_state, 1'b1 << OtpOperationDone); - - // check all interrupts are cleared - csr_rd_check(.ptr(ral.intr_state), .compare_value(0)); - endtask : body - -endclass : otp_ctrl_wake_up_vseq diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim.core b/hw/ip/otp_ctrl/dv/otp_ctrl_sim.core deleted file mode 100644 index a3a0c7ba5fb66..0000000000000 --- a/hw/ip/otp_ctrl/dv/otp_ctrl_sim.core +++ /dev/null @@ -1,34 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:otp_ctrl_sim:0.1" -description: "OTP_CTRL DV sim target" -filesets: - files_rtl: - depend: - - lowrisc:ip:otp_ctrl - - files_dv: - depend: - - lowrisc:dv:mem_bkdr_util - - lowrisc:dv:otp_ctrl_test - - lowrisc:dv:otp_ctrl_sva - - lowrisc:dv:otp_ctrl_cov - files: - - tb.sv - file_type: systemVerilogSource - -targets: - default: &default_target - toplevel: tb - filesets: - - files_rtl - - files_dv - - sim: - <<: *default_target - default_tool: vcs - - lint: - <<: *default_target diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson deleted file mode 100644 index 2b2333f040dd9..0000000000000 --- a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - // Name of the sim cfg - typically same as the name of the DUT. - name: otp_ctrl - - // Top level dut name (sv module). - dut: otp_ctrl - - // Top level testbench name (sv module). - tb: tb - - // Simulator used to sign off this block - tool: vcs - - // Fusesoc core file used for building the file list. - fusesoc_core: lowrisc:dv:otp_ctrl_sim:0.1 - - // Testplan hjson file. - testplan: "{proj_root}/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson" - - // RAL spec - used to generate the RAL model. - ral_spec: "{proj_root}/hw/ip/otp_ctrl/data/otp_ctrl.hjson" - - // Import additional common sim cfg files. - import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", - // Config files to get the correct flags for crypto_dpi_prince - "{proj_root}/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson", - // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/mem_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson"] - - en_build_modes: ["{tool}_crypto_dpi_prince_build_opts"] - - build_modes: [ - // Sim mode that enables build randomization. See the `build_seed` mode - // defined in `hw/dv/tools/dvsim/common_modes.hjson` for more details. - { - name: build_seed - pre_build_cmds: ["cd {proj_root} && ./util/design/gen-otp-mmap.py --seed {seed}"] - is_sim_mode: 1 - } - ] - - // Add additional tops for simulation. - sim_tops: ["otp_ctrl_bind", "otp_ctrl_cov_bind", - "sec_cm_prim_sparse_fsm_flop_bind", - "sec_cm_prim_count_bind", - "sec_cm_prim_double_lfsr_bind", - "sec_cm_prim_onehot_check_bind"] - - // Default iterations for all tests - each test entry can override this. - reseed: 50 - - // Add OTP_CTRL specific exclusion files. - vcs_cov_excl_files: ["{proj_root}/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_unr_excl.el", - "{proj_root}/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cov_fsm_unr_excl.el"] - - overrides: [ - { - name: default_vcs_cov_cfg_file - value: "-cm_hier {dv_root}/tools/vcs/cover.cfg+{dv_root}/tools/vcs/common_cov_excl.cfg+{proj_root}/hw/ip/otp_ctrl/dv/cov/otp_ctrl_cover.cfg" - } - ] - - // Default UVM test and seq class name. - uvm_test: otp_ctrl_base_test - uvm_test_seq: otp_ctrl_base_vseq - - run_opts: ["+cdc_instrumentation_enabled=1"] - - // List of test specifications. - tests: [ - { - name: otp_ctrl_wake_up - uvm_test_seq: otp_ctrl_wake_up_vseq - run_opts: ["+en_scb=0"] - reseed: 1 - } - - { - name: otp_ctrl_smoke - uvm_test_seq: otp_ctrl_smoke_vseq - } - - { - name: otp_ctrl_partition_walk - uvm_test_seq: otp_ctrl_partition_walk_vseq - reseed: 1 - } - - { - name: otp_ctrl_low_freq_read - uvm_test_seq: otp_ctrl_low_freq_read_vseq - reseed: 1 - } - - { - name: otp_ctrl_init_fail - uvm_test_seq: otp_ctrl_init_fail_vseq - reseed: 300 - } - { - name: otp_ctrl_background_chks - uvm_test_seq: otp_ctrl_background_chks_vseq - reseed: 10 - } - - { - name: otp_ctrl_parallel_lc_req - uvm_test_seq: otp_ctrl_parallel_lc_req_vseq - run_opts: ["+zero_delays=1"] - } - - { - name: otp_ctrl_parallel_lc_esc - uvm_test_seq: otp_ctrl_parallel_lc_esc_vseq - reseed: 200 - } - - { - name: otp_ctrl_dai_lock - uvm_test_seq: otp_ctrl_dai_lock_vseq - } - - { - name: otp_ctrl_dai_errs - uvm_test_seq: otp_ctrl_dai_errs_vseq - } - - { - name: otp_ctrl_check_fail - uvm_test_seq: otp_ctrl_check_fail_vseq - } - - { - name: otp_ctrl_macro_errs - uvm_test_seq: otp_ctrl_macro_errs_vseq - } - - { - name: otp_ctrl_parallel_key_req - uvm_test_seq: otp_ctrl_parallel_key_req_vseq - } - - { - name: otp_ctrl_regwen - uvm_test_seq: otp_ctrl_regwen_vseq - // This test is to check reg programming is gated when direct_access_regwen=0 - // Thus this test is timing sensitive - run_opts: ["+zero_delays=1"] - } - - { - name: otp_ctrl_test_access - uvm_test_seq: otp_ctrl_test_access_vseq - } - - { - name: "{name}_stress_all_with_rand_reset" - reseed: 100 - } - ] - - // List of regressions. - regressions: [ - { - name: smoke - tests: ["otp_ctrl_smoke"] - } - ] -} diff --git a/hw/ip/otp_ctrl/dv/sva/otp_ctrl_bind.sv b/hw/ip/otp_ctrl/dv/sva/otp_ctrl_bind.sv deleted file mode 100644 index 833c710797e62..0000000000000 --- a/hw/ip/otp_ctrl/dv/sva/otp_ctrl_bind.sv +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -module otp_ctrl_bind; - - bind otp_ctrl tlul_assert #( - .EndpointType("Device") - ) core_tlul_assert_device ( - .clk_i, - .rst_ni, - .h2d (core_tl_i), - .d2h (core_tl_o) - ); - - bind otp_ctrl tlul_assert #( - .EndpointType("Device") - ) prim_tlul_assert_device ( - .clk_i, - .rst_ni, - .h2d (prim_tl_i), - .d2h (prim_tl_o) - ); - - bind otp_ctrl otp_ctrl_core_csr_assert_fpv otp_ctrl_core_csr_assert ( - .clk_i, - .rst_ni, - .h2d (core_tl_i), - .d2h (core_tl_o) - ); - -endmodule diff --git a/hw/ip/otp_ctrl/dv/sva/otp_ctrl_sva.core b/hw/ip/otp_ctrl/dv/sva/otp_ctrl_sva.core deleted file mode 100644 index 87f39ceac240a..0000000000000 --- a/hw/ip/otp_ctrl/dv/sva/otp_ctrl_sva.core +++ /dev/null @@ -1,38 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:otp_ctrl_sva:0.1" -description: "OTP_CTRL assertion modules and bind file." -filesets: - files_dv: - depend: - - lowrisc:tlul:headers - - lowrisc:fpv:csr_assert_gen - files: - - otp_ctrl_bind.sv - file_type: systemVerilogSource - - files_formal: - depend: - - lowrisc:ip:otp_ctrl - -generate: - csr_assert_gen: - generator: csr_assert_gen - parameters: - spec: ../../data/otp_ctrl.hjson - -targets: - default: &default_target - filesets: - - files_dv - generate: - - csr_assert_gen - - formal: - <<: *default_target - filesets: - - files_formal - - files_dv - toplevel: otp_ctrl diff --git a/hw/ip/otp_ctrl/dv/tb.sv b/hw/ip/otp_ctrl/dv/tb.sv deleted file mode 100644 index e1b2664699ee9..0000000000000 --- a/hw/ip/otp_ctrl/dv/tb.sv +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -module tb; - // dep packages - import uvm_pkg::*; - import dv_utils_pkg::*; - import otp_ctrl_env_pkg::*; - import otp_ctrl_test_pkg::*; - import otp_ctrl_reg_pkg::*; - import mem_bkdr_util_pkg::mem_bkdr_util; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // TB base test ENV_T & CFG_T specification - // - // Specify the parameters for the otp_ctrl_base_test - // This will invoke the UVM registry and link this test type to - // the name 'otp_ctrl_base_test' as a test name passed by UVM_TESTNAME - // - // This is done explicitly only for the prim_pkg::ImplGeneric implementation - // since partner base tests inherit from otp_ctrl_base_test#(CFG_T, ENV_T) and - // specify directly (CFG_T, ENV_T) via the class extension and use a different - // UVM_TESTNAME - if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_spec_base_test_params - typedef otp_ctrl_base_test #(.CFG_T(otp_ctrl_env_cfg), - .ENV_T(otp_ctrl_env)) otp_ctrl_base_test_t; - end - - wire clk, rst_n; - wire otp_ctrl_pkg::flash_otp_key_req_t flash_req; - wire otp_ctrl_pkg::flash_otp_key_rsp_t flash_rsp; - wire otp_ctrl_pkg::otbn_otp_key_req_t otbn_req; - wire otp_ctrl_pkg::otbn_otp_key_rsp_t otbn_rsp; - wire otp_ctrl_pkg::sram_otp_key_req_t[NumSramKeyReqSlots-1:0] sram_req; - wire otp_ctrl_pkg::sram_otp_key_rsp_t[NumSramKeyReqSlots-1:0] sram_rsp; - - wire [NUM_MAX_INTERRUPTS-1:0] interrupts; - wire intr_otp_operation_done, intr_otp_error; - - // Output from close-source OTP, not checked in open-source env. - wire otp_ctrl_pkg::otp_ast_req_t ast_req; - wire [7:0] otp_obs_o; - - tlul_pkg::tl_d2h_t prim_tl_o; - - // interfaces - clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n)); - pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts); - - // lc_otp interfaces - push_pull_if #(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1)) - lc_prog_if(.clk(clk), .rst_n(rst_n)); - push_pull_if #(.DeviceDataWidth(SRAM_DATA_SIZE)) - sram_if[NumSramKeyReqSlots](.clk(clk), .rst_n(rst_n)); - push_pull_if #(.DeviceDataWidth(OTBN_DATA_SIZE)) otbn_if(.clk(clk), .rst_n(rst_n)); - push_pull_if #(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_addr_if(.clk(clk), .rst_n(rst_n)); - push_pull_if #(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_data_if(.clk(clk), .rst_n(rst_n)); - - tl_if tl_if(.clk(clk), .rst_n(rst_n)); - tl_if prim_tl_if(.clk(clk), .rst_n(rst_n)); - - otp_ctrl_if otp_ctrl_if(.clk_i(clk), .rst_ni(rst_n)); - - `DV_ALERT_IF_CONNECT() - - // edn_clk, edn_rst_n and edn_if are defined and driven in below macro - `DV_EDN_IF_CONNECT - - assign otp_ctrl_if.lc_prog_req = lc_prog_if.req; - assign otp_ctrl_if.lc_prog_err = lc_prog_if.d_data; - - // Assign to otp_ctrl_if for assertion checks. - assign otp_ctrl_if.lc_prog_ack = lc_prog_if.ack; - assign otp_ctrl_if.flash_acks = flash_data_if.ack; - assign otp_ctrl_if.otbn_ack = otbn_if.ack; - - // This signal probes design's alert request to avoid additional logic for triggering alert and - // disable assertions. - // Alert checkings are done independently in otp_ctrl's scb. - // The correctness of this probed signal is checked in otp_ctrl's scb as well. - assign otp_ctrl_if.alert_reqs = dut.alerts[0] | dut.alerts[1]; - - // connected to interface - wire otp_ext_voltage_h = otp_ctrl_if.ext_voltage_h_io; - - // dut - otp_ctrl dut ( - .clk_i (clk ), - .rst_ni (rst_n ), - // edn - .clk_edn_i (edn_clk ), - .rst_edn_ni (edn_rst_n ), - .edn_o (edn_if[0].req ), - .edn_i ({edn_if[0].ack, edn_if[0].d_data}), - // bus interfaces - .core_tl_i (tl_if.h2d ), - .core_tl_o (tl_if.d2h ), - .prim_tl_i (prim_tl_if.h2d), - .prim_tl_o (prim_tl_if.d2h), - // interrupt - .intr_otp_operation_done_o (intr_otp_operation_done), - .intr_otp_error_o (intr_otp_error), - // alert - .alert_rx_i (alert_rx ), - .alert_tx_o (alert_tx ), - // ast - .obs_ctrl_i (otp_ctrl_if.obs_ctrl_i), - .otp_obs_o (otp_obs_o), - .otp_ast_pwr_seq_o (ast_req), - .otp_ast_pwr_seq_h_i (otp_ctrl_if.otp_ast_pwr_seq_h_i), - // pwrmgr - .pwr_otp_i (otp_ctrl_if.pwr_otp_init_i), - .pwr_otp_o ({otp_ctrl_if.pwr_otp_done_o, otp_ctrl_if.pwr_otp_idle_o}), - // lc - .lc_otp_vendor_test_i (otp_ctrl_if.otp_vendor_test_ctrl_i), - .lc_otp_vendor_test_o (otp_ctrl_if.otp_vendor_test_status_o), - .lc_otp_program_i ({lc_prog_if.req, lc_prog_if.h_data}), - .lc_otp_program_o ({lc_prog_if.d_data, lc_prog_if.ack}), - .lc_creator_seed_sw_rw_en_i (otp_ctrl_if.lc_creator_seed_sw_rw_en_i), - .lc_owner_seed_sw_rw_en_i (otp_ctrl_if.lc_owner_seed_sw_rw_en_i), - .lc_seed_hw_rd_en_i (otp_ctrl_if.lc_seed_hw_rd_en_i), - .lc_dft_en_i (otp_ctrl_if.lc_dft_en_i), - .lc_escalate_en_i (otp_ctrl_if.lc_escalate_en_i), - .lc_check_byp_en_i (otp_ctrl_if.lc_check_byp_en_i), - .otp_lc_data_o (otp_ctrl_if.lc_data_o), - // keymgr - .otp_keymgr_key_o (otp_ctrl_if.keymgr_key_o), - // flash - .flash_otp_key_i (flash_req), - .flash_otp_key_o (flash_rsp), - // sram - .sram_otp_key_i (sram_req), - .sram_otp_key_o (sram_rsp), - // otbn - .otbn_otp_key_i (otbn_req), - .otbn_otp_key_o (otbn_rsp), - - .otp_broadcast_o (otp_ctrl_if.otp_broadcast_o), - .otp_ext_voltage_h_io (otp_ext_voltage_h), - - //scan - .scan_en_i (otp_ctrl_if.scan_en_i), - .scan_rst_ni (otp_ctrl_if.scan_rst_ni), - .scanmode_i (otp_ctrl_if.scanmode_i), - - // Test-related GPIO output - .cio_test_o (otp_ctrl_if.cio_test_o), - .cio_test_en_o (otp_ctrl_if.cio_test_en_o) - ); - - for (genvar i = 0; i < NumSramKeyReqSlots; i++) begin : gen_sram_pull_if - assign sram_req[i] = sram_if[i].req; - assign sram_if[i].ack = sram_rsp[i].ack; - assign sram_if[i].d_data = {sram_rsp[i].key, sram_rsp[i].nonce, sram_rsp[i].seed_valid}; - assign otp_ctrl_if.sram_acks[i] = sram_rsp[i].ack; - initial begin - uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(SRAM_DATA_SIZE)))::set(null, - $sformatf("*env.m_sram_pull_agent[%0d]*", i), "vif", sram_if[i]); - end - end - assign otbn_req = otbn_if.req; - assign otbn_if.ack = otbn_rsp.ack; - assign otbn_if.d_data = {otbn_rsp.key, otbn_rsp.nonce, otbn_rsp.seed_valid}; - - assign flash_req = {flash_data_if.req, flash_addr_if.req}; - assign flash_data_if.ack = flash_rsp.data_ack; - assign flash_addr_if.ack = flash_rsp.addr_ack; - assign flash_data_if.d_data = {flash_rsp.key, flash_rsp.seed_valid}; - assign flash_addr_if.d_data = {flash_rsp.key, flash_rsp.seed_valid}; - - assign interrupts[OtpOperationDone] = intr_otp_operation_done; - assign interrupts[OtpErr] = intr_otp_error; - - // Instantitate the memory backdoor util instance only for OS implementation - // Proprietary IP will instantiate their own backdoor util - - if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_impl_generic - `define MEM_MODULE_PATH \ - tb.dut.u_otp.gen_generic.u_impl_generic.u_prim_ram_1p_adv - - `define MEM_ARRAY_PATH \ - `MEM_MODULE_PATH.u_mem.gen_generic.u_impl_generic.mem - - initial begin : mem_bkdr_util_gen - mem_bkdr_util m_mem_bkdr_util; - m_mem_bkdr_util = new(.name("mem_bkdr_util"), - .path(`DV_STRINGIFY(`MEM_ARRAY_PATH)), - .depth($size(`MEM_ARRAY_PATH)), - .n_bits($bits(`MEM_ARRAY_PATH)), - .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16)); - - uvm_config_db#(mem_bkdr_util)::set(null, "*.env", "mem_bkdr_util", m_mem_bkdr_util); - end : mem_bkdr_util_gen - - `undef MEM_ARRAY_PATH - `undef MEM_MODULE_PATH - end : gen_impl_generic - - // DV forced otp_cmd_i to reach invalid state, thus violate the assertions - for (genvar idx = 0; idx < NumPart; idx++) begin : gen_assertoff_loop - if (is_hw_part_idx(idx)) begin : gen_assertoff - initial begin - $assertoff(0, tb.dut.gen_partitions[idx].gen_buffered.u_part_buf.OtpErrorState_A); - end - end - end - - initial begin - // drive clk and rst_n from clk_if - clk_rst_if.set_active(); - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if); - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", - "clk_rst_vif_otp_ctrl_prim_reg_block", clk_rst_if); - uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_otp_ctrl_core_reg_block*", - "vif", tl_if); - uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_otp_ctrl_prim_reg_block", - "vif", prim_tl_if); - uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(OTBN_DATA_SIZE)))::set(null, - "*env.m_otbn_pull_agent*", "vif", otbn_if); - uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set(null, - "*env.m_flash_data_pull_agent*", "vif", flash_data_if); - uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set(null, - "*env.m_flash_addr_pull_agent*", "vif", flash_addr_if); - uvm_config_db#(virtual push_pull_if#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1))):: - set(null, "*env.m_lc_prog_pull_agent*", "vif", lc_prog_if); - - uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); - - uvm_config_db#(virtual otp_ctrl_if)::set(null, "*.env", "otp_ctrl_vif", otp_ctrl_if); - $timeformat(-12, 0, " ps", 12); - run_test(); - end - -endmodule diff --git a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv deleted file mode 100644 index 284c5e0cdfe72..0000000000000 --- a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class otp_ctrl_base_test #( - type CFG_T = otp_ctrl_env_cfg, - type ENV_T = otp_ctrl_env - ) extends cip_base_test #( - .CFG_T(CFG_T), - .ENV_T(ENV_T) - ); - - // A prototype for the registry to associate the parameterized base test - // with the name 'otp_ctrl_base_test' - // - // Register the name 'otp_ctrl_base_test' with the UVM factory to be associated - // with the template base test class parameterized with the default types (see - // declaration. We cannot invoke the standard UVM factory automation macro t - // (uvm_component_param_utils) to register a parameterized test class with the - // factory because the creation of the test by name (via the UVM_TESTNAME - // plusarg) does not work. We expand the contents of the automation macro - // here instead. See the following paper for details: - // https://verificationacademy-news.s3.amazonaws.com/DVCon2016/Papers/ - // dvcon-2016_paramaters-uvm-coverage-and-emulation-take-two-and-call-me-in-the-morning_paper.pdf - typedef uvm_component_registry#(otp_ctrl_base_test#(CFG_T, ENV_T), "otp_ctrl_base_test") type_id; - - // functions to support the component registry above - static function type_id get_type(); - return type_id::get(); - endfunction : get_type - - virtual function uvm_object_wrapper get_object_type(); - return type_id::get(); - endfunction : get_object_type - - const static string type_name = "otp_ctrl_base_test"; - - virtual function string get_type_name(); - return type_name; - endfunction : get_type_name - - `uvm_component_new - - // the base class dv_base_test creates the following instances: - // otp_ctrl_env_cfg: cfg - // otp_ctrl_env: env - - // the base class also looks up UVM_TEST_SEQ plusarg to create and run that seq in - // the run_phase; as such, nothing more needs to be done - -endclass : otp_ctrl_base_test diff --git a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core deleted file mode 100644 index de8cfedb557c3..0000000000000 --- a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core +++ /dev/null @@ -1,19 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:otp_ctrl_test:0.1" -description: "OTP_CTRL DV UVM test" -filesets: - files_dv: - depend: - - lowrisc:dv:otp_ctrl_env - files: - - otp_ctrl_test_pkg.sv - - otp_ctrl_base_test.sv: {is_include_file: true} - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_dv diff --git a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv deleted file mode 100644 index 3d5703d49e6e2..0000000000000 --- a/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -package otp_ctrl_test_pkg; - // dep packages - import uvm_pkg::*; - import cip_base_pkg::*; - import otp_ctrl_env_pkg::*; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // local types - - // functions - - // package sources - `include "otp_ctrl_base_test.sv" - -endpackage diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl.vbl b/hw/ip/otp_ctrl/lint/otp_ctrl.vbl deleted file mode 100644 index 33b74bcc9541c..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl.vbl +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# waiver file for OTP controller - -# waive long line violations in generated code -waive --rule=line-length --location="otp_ctrl_part_pkg.sv" diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl.vlt b/hw/ip/otp_ctrl/lint/otp_ctrl.vlt deleted file mode 100644 index 0f4180cb5e3d5..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl.vlt +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// waiver file for OTP controller - -`verilator_config - -// Some code in this block checks that an address is greater than or equal to -// the offset of a fixed part_info_t (supplied via a parameter). If that -// part_info_t happens to have a zero offset, Verilator warns that the -// comparison is always true. Waive the warning. -lint_off -rule UNSIGNED -file "*/rtl/otp_ctrl.sv" -lint_off -rule UNSIGNED -file "*/rtl/otp_ctrl_dai.sv" -lint_off -rule UNSIGNED -file "*/rtl/otp_ctrl_part_unbuf.sv" - -// In otp_ctrl_scrmbl, there are some comparisons between the "sel_i" signal -// and LastDigestSet. If the parameter NumDigestSets is a power of 2 (which it -// is at the moment), these checks will always be true, causing a Verilator -// warning. -lint_off -rule CMPCONST -file "*/rtl/otp_ctrl_scrmbl.sv" diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl.waiver b/hw/ip/otp_ctrl/lint/otp_ctrl.waiver deleted file mode 100644 index b97042a7aec33..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl.waiver +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# waiver file for OTP controller - -waive -rules {TERMINAL_STATE} -location {otp_ctrl_dai.sv \ - otp_ctrl_lci.sv \ - otp_ctrl_lfsr_timer.sv \ - otp_ctrl_part_buf.sv \ - otp_ctrl_part_unbuf.sv \ - otp_ctrl_scrmbl.sv} \ - -msg {Terminal state 'ErrorSt' is detected. Next state register 'state_d' is not assigned in this state.} \ - -comment "All these FSMs have a valid, terminal error state." - -waive -rules {INVALID_COMPARE} -location {otp_ctrl_dai.sv} -regexp {.*dai_addr_i >= PartInfo\[0\]\.offset.*} \ - -comment "This invalid compare is due to the first partition offset being zero." - -waive -rules {INVALID_COMPARE} -location {otp_ctrl.sv} -regexp {.*tlul_addr.* >= PartInfo\[0\]\.offset.*} \ - -comment "This invalid compare is due to the first partition offset being zero." - -waive -rules {LOOP_VAR_OP FOR_LOOP_BOUNDS} -location {prim_cipher_pkg.sv} -regexp {Loop.*round_cnt.*constant.*} \ - -comment "This function needs to iterate over the key schedule function in order to derive the decryption key." - -waive -rules {ASSIGN_SIGN} -location {otp_ctrl_part_buf.sv} -regexp {Unsigned target 'step_i' assigned signed value 'CntWidth'\(1\)'} \ - -comment "This is fine as long as CntWidth is greater equal 2 which is checked using an SVA." diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vbl b/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vbl deleted file mode 100644 index 01a79ec02a146..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vbl +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# waiver file for OTP controller package - -# waive long line violations in generated code -waive --rule=line-length --location="otp_ctrl_part_pkg.sv" diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vlt b/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vlt deleted file mode 100644 index 0df101fc3539d..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.vlt +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// waiver file for OTP controller package diff --git a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.waiver b/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.waiver deleted file mode 100644 index ad32fe048a4e3..0000000000000 --- a/hw/ip/otp_ctrl/lint/otp_ctrl_pkg.waiver +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# waiver file for OTP controller package - -# waive line length violations in generated code -waive -rules LINE_LENGTH -location {otp_ctrl_part_pkg.sv} \ - -comment "Waive line length violations in generated code." diff --git a/hw/ip/otp_ctrl/otp_ctrl.core b/hw/ip/otp_ctrl/otp_ctrl.core deleted file mode 100644 index 302558501b050..0000000000000 --- a/hw/ip/otp_ctrl/otp_ctrl.core +++ /dev/null @@ -1,103 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:otp_ctrl:1.0" -description: "OTP Controller" - -filesets: - files_rtl: - depend: - - lowrisc:ip:otp_ctrl_pkg - - lowrisc:ip:tlul - - lowrisc:prim:all - - lowrisc:prim:ram_1p - - lowrisc:prim:otp - - lowrisc:prim:double_lfsr - - lowrisc:prim:count - - lowrisc:prim:lc_sender - - lowrisc:prim:lc_sync - - lowrisc:prim:buf - - lowrisc:prim:flop - - lowrisc:prim:secded - - lowrisc:prim:edn_req - - lowrisc:prim:sec_anchor - - lowrisc:ip_interfaces:pwrmgr_pkg - - lowrisc:ip:edn_pkg - - lowrisc:prim:sparse_fsm - - "fileset_partner ? (partner:systems:ast_pkg)" - - "!fileset_partner ? (lowrisc:systems:ast_pkg)" - files: - - rtl/otp_ctrl_core_reg_top.sv - - rtl/otp_ctrl_ecc_reg.sv - - rtl/otp_ctrl_scrmbl.sv - - rtl/otp_ctrl_lfsr_timer.sv - - rtl/otp_ctrl_part_unbuf.sv - - rtl/otp_ctrl_part_buf.sv - - rtl/otp_ctrl_dai.sv - - rtl/otp_ctrl_kdi.sv - - rtl/otp_ctrl_lci.sv - - rtl/otp_ctrl.sv - file_type: systemVerilogSource - - files_verilator_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl.vlt - file_type: vlt - - files_ascentlint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl.waiver - file_type: waiver - - files_veriblelint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl.vbl - file_type: veribleLintWaiver - -parameters: - SYNTHESIS: - datatype: bool - paramtype: vlogdefine - - -targets: - default: &default_target - filesets: - - tool_verilator ? (files_verilator_waiver) - - tool_ascentlint ? (files_ascentlint_waiver) - - tool_veriblelint ? (files_veriblelint_waiver) - - files_rtl - toplevel: otp_ctrl - - lint: - <<: *default_target - default_tool: verilator - parameters: - - SYNTHESIS=true - tools: - verilator: - mode: lint-only - verilator_options: - - "-Wall" - - syn: - <<: *default_target - # TODO: set default to DC once - # this option is available - # olofk/edalize#89 - default_tool: icarus - parameters: - - SYNTHESIS=true diff --git a/hw/ip/otp_ctrl/otp_ctrl_pkg.core b/hw/ip/otp_ctrl/otp_ctrl_pkg.core deleted file mode 100644 index 12628f906ee2b..0000000000000 --- a/hw/ip/otp_ctrl/otp_ctrl_pkg.core +++ /dev/null @@ -1,71 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:otp_ctrl_pkg:1.0" -description: "OTP Controller Package" -filesets: - files_rtl: - depend: - - lowrisc:tlul:headers - - lowrisc:ip:lc_ctrl_pkg - - lowrisc:prim:mubi - - files: - - rtl/otp_ctrl_reg_pkg.sv - - rtl/otp_ctrl_pkg.sv - - rtl/otp_ctrl_part_pkg.sv - file_type: systemVerilogSource - - files_verilator_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl_pkg.vlt - file_type: vlt - - files_ascentlint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl_pkg.waiver - file_type: waiver - - files_veriblelint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/otp_ctrl_pkg.vbl - file_type: veribleLintWaiver - -parameters: - SYNTHESIS: - datatype: bool - paramtype: vlogdefine - - -targets: - default: &default_target - filesets: - - tool_verilator ? (files_verilator_waiver) - - tool_ascentlint ? (files_ascentlint_waiver) - - tool_veriblelint ? (files_veriblelint_waiver) - - files_rtl - toplevel: lc_ctrl - - lint: - <<: *default_target - default_tool: verilator - parameters: - - SYNTHESIS=true - tools: - verilator: - mode: lint-only - verilator_options: - - "-Wall" diff --git a/hw/ip/otp_ctrl/otp_ctrl_prim_reg_top.core b/hw/ip/otp_ctrl/otp_ctrl_prim_reg_top.core deleted file mode 100644 index 4d54817c20935..0000000000000 --- a/hw/ip/otp_ctrl/otp_ctrl_prim_reg_top.core +++ /dev/null @@ -1,26 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:otp_ctrl_prim_reg_top:1.0" -description: "Generic register top for the OTP wrapper" -filesets: - files_rtl: - depend: - - lowrisc:ip:otp_ctrl_pkg - files: - - rtl/otp_ctrl_prim_reg_top.sv - file_type: systemVerilogSource - - -parameters: - SYNTHESIS: - datatype: bool - paramtype: vlogdefine - - -targets: - default: &default_target - filesets: - - files_rtl - toplevel: lc_ctrl diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl.sv deleted file mode 100644 index 5558e2ac0960d..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv +++ /dev/null @@ -1,1570 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// OTP Controller top. -// - -`include "prim_assert.sv" - -module otp_ctrl - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -#( - // Enable asynchronous transitions on alerts. - parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, - // Compile time random constants, to be overriden by topgen. - parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, - parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, - parameter scrmbl_key_init_t RndCnstScrmblKeyInit = RndCnstScrmblKeyInitDefault, - // Hexfile file to initialize the OTP macro. - // Note that the hexdump needs to account for ECC. - parameter MemInitFile = "" -) ( - // OTP clock - input clk_i, - input rst_ni, - // EDN clock and interface - logic clk_edn_i, - logic rst_edn_ni, - output edn_pkg::edn_req_t edn_o, - input edn_pkg::edn_rsp_t edn_i, - // Bus Interface - input tlul_pkg::tl_h2d_t core_tl_i, - output tlul_pkg::tl_d2h_t core_tl_o, - input tlul_pkg::tl_h2d_t prim_tl_i, - output tlul_pkg::tl_d2h_t prim_tl_o, - // Interrupt Requests - output logic intr_otp_operation_done_o, - output logic intr_otp_error_o, - // Alerts - input prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, - output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o, - // Observability to AST - input ast_pkg::ast_obs_ctrl_t obs_ctrl_i, - output logic [7:0] otp_obs_o, - // Macro-specific power sequencing signals to/from AST. - output otp_ast_req_t otp_ast_pwr_seq_o, - input otp_ast_rsp_t otp_ast_pwr_seq_h_i, - // Power manager interface (inputs are synced to OTP clock domain) - input pwrmgr_pkg::pwr_otp_req_t pwr_otp_i, - output pwrmgr_pkg::pwr_otp_rsp_t pwr_otp_o, - // Macro-specific test registers going to lifecycle TAP - input lc_otp_vendor_test_req_t lc_otp_vendor_test_i, - output lc_otp_vendor_test_rsp_t lc_otp_vendor_test_o, - // Lifecycle transition command interface - input lc_otp_program_req_t lc_otp_program_i, - output lc_otp_program_rsp_t lc_otp_program_o, - // Lifecycle broadcast inputs - // SEC_CM: LC_CTRL.INTERSIG.MUBI - input lc_ctrl_pkg::lc_tx_t lc_creator_seed_sw_rw_en_i, - input lc_ctrl_pkg::lc_tx_t lc_owner_seed_sw_rw_en_i, - input lc_ctrl_pkg::lc_tx_t lc_seed_hw_rd_en_i, - input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, - input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, - input lc_ctrl_pkg::lc_tx_t lc_check_byp_en_i, - // OTP broadcast outputs - // SEC_CM: TOKEN_VALID.CTRL.MUBI - output otp_lc_data_t otp_lc_data_o, - output otp_keymgr_key_t otp_keymgr_key_o, - // Scrambling key requests - input flash_otp_key_req_t flash_otp_key_i, - output flash_otp_key_rsp_t flash_otp_key_o, - input sram_otp_key_req_t [NumSramKeyReqSlots-1:0] sram_otp_key_i, - output sram_otp_key_rsp_t [NumSramKeyReqSlots-1:0] sram_otp_key_o, - input otbn_otp_key_req_t otbn_otp_key_i, - output otbn_otp_key_rsp_t otbn_otp_key_o, - // Hardware config bits - output otp_broadcast_t otp_broadcast_o, - // External voltage for OTP - inout wire otp_ext_voltage_h_io, - // Scan - input scan_en_i, - input scan_rst_ni, - input prim_mubi_pkg::mubi4_t scanmode_i, - // Test-related GPIO output - output logic [OtpTestVectWidth-1:0] cio_test_o, - output logic [OtpTestVectWidth-1:0] cio_test_en_o -); - - import prim_mubi_pkg::*; - import prim_util_pkg::vbits; - - //////////////////////// - // Integration Checks // - //////////////////////// - - // This ensures that we can transfer scrambler data blocks in and out of OTP atomically. - `ASSERT_INIT(OtpIfWidth_A, OtpIfWidth == ScrmblBlockWidth) - - // These error codes need to be identical. - `ASSERT_INIT(ErrorCodeWidth_A, OtpErrWidth == prim_otp_pkg::ErrWidth) - `ASSERT_INIT(OtpErrorCode0_A, int'(NoError) == int'(prim_otp_pkg::NoError)) - `ASSERT_INIT(OtpErrorCode1_A, int'(MacroError) == int'(prim_otp_pkg::MacroError)) - `ASSERT_INIT(OtpErrorCode2_A, int'(MacroEccCorrError) == int'(prim_otp_pkg::MacroEccCorrError)) - `ASSERT_INIT(OtpErrorCode3_A, - int'(MacroEccUncorrError) == int'(prim_otp_pkg::MacroEccUncorrError)) - `ASSERT_INIT(OtpErrorCode4_A, - int'(MacroWriteBlankError) == int'(prim_otp_pkg::MacroWriteBlankError)) - - ///////////// - // Regfile // - ///////////// - - // We have one CSR node, one functional TL-UL window and a gate module for that window - logic [2:0] intg_error; - - tlul_pkg::tl_h2d_t tl_win_h2d; - tlul_pkg::tl_d2h_t tl_win_d2h; - - otp_ctrl_reg_pkg::otp_ctrl_core_reg2hw_t reg2hw; - otp_ctrl_reg_pkg::otp_ctrl_core_hw2reg_t hw2reg; - - // SEC_CM: DIRECT_ACCESS.CONFIG.REGWEN, CHECK_TRIGGER.CONFIG.REGWEN, CHECK.CONFIG.REGWEN - otp_ctrl_core_reg_top u_reg_core ( - .clk_i, - .rst_ni, - .tl_i ( core_tl_i ), - .tl_o ( core_tl_o ), - .tl_win_o ( tl_win_h2d ), - .tl_win_i ( tl_win_d2h ), - .reg2hw ( reg2hw ), - .hw2reg ( hw2reg ), - // SEC_CM: BUS.INTEGRITY - .intg_err_o( intg_error[0] ) - ); - - /////////////////////////////////////// - // Life Cycle Signal Synchronization // - /////////////////////////////////////// - - lc_ctrl_pkg::lc_tx_t lc_creator_seed_sw_rw_en, lc_owner_seed_sw_rw_en, - lc_seed_hw_rd_en, lc_check_byp_en; - lc_ctrl_pkg::lc_tx_t [2:0] lc_dft_en; - // NumAgents + lfsr timer and scrambling datapath. - lc_ctrl_pkg::lc_tx_t [NumAgentsIdx+1:0] lc_escalate_en, lc_escalate_en_synced; - // Single wire for gating assertions in arbitration and CDC primitives. - logic lc_escalate_en_any; - - prim_lc_sync #( - .NumCopies(NumAgentsIdx+2) - ) u_prim_lc_sync_escalate_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_escalate_en_i), - .lc_en_o(lc_escalate_en_synced) - ); - - prim_lc_sync #( - .NumCopies(1) - ) u_prim_lc_sync_creator_seed_sw_rw_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_creator_seed_sw_rw_en_i), - .lc_en_o({lc_creator_seed_sw_rw_en}) - ); - - prim_lc_sync #( - .NumCopies(1) - ) u_prim_lc_sync_owner_seed_sw_rw_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_owner_seed_sw_rw_en_i), - .lc_en_o({lc_owner_seed_sw_rw_en}) - ); - - prim_lc_sync #( - .NumCopies(1) - ) u_prim_lc_sync_seed_hw_rd_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_seed_hw_rd_en_i), - .lc_en_o({lc_seed_hw_rd_en}) - ); - - prim_lc_sync #( - .NumCopies(3) - ) u_prim_lc_sync_dft_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_dft_en_i), - .lc_en_o(lc_dft_en) - ); - - prim_lc_sync #( - .NumCopies(1) - ) u_prim_lc_sync_check_byp_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_check_byp_en_i), - .lc_en_o({lc_check_byp_en}) - ); - - ///////////////////////////////////// - // TL-UL SW partition select logic // - ///////////////////////////////////// - - // The SW partitions share the same TL-UL adapter. - logic tlul_req, tlul_gnt, tlul_rvalid; - logic [SwWindowAddrWidth-1:0] tlul_addr; - logic [1:0] tlul_rerror; - logic [31:0] tlul_rdata; - - import prim_mubi_pkg::MuBi4False; - tlul_adapter_sram #( - .SramAw ( SwWindowAddrWidth ), - .SramDw ( 32 ), - .Outstanding ( 1 ), - .ByteAccess ( 0 ), - .ErrOnWrite ( 1 ) // No write accesses allowed here. - ) u_tlul_adapter_sram ( - .clk_i, - .rst_ni, - .en_ifetch_i ( MuBi4False ), - .tl_i ( tl_win_h2d ), - .tl_o ( tl_win_d2h ), - .req_o ( tlul_req ), - .gnt_i ( tlul_gnt ), - .we_o ( ), // unused - .addr_o ( tlul_addr ), - .wdata_o ( ), // unused - .wmask_o ( ), // unused - // SEC_CM: BUS.INTEGRITY - .intg_error_o ( intg_error[1] ), - .user_rsvd_o ( ), - .rdata_i ( tlul_rdata ), - .rvalid_i ( tlul_rvalid ), - .rerror_i ( tlul_rerror ), - .req_type_o ( ), - .compound_txn_in_progress_o ( ), - .readback_en_i ( MuBi4False ), - .readback_error_o ( ), - .wr_collision_i ( 1'b0 ), - .write_pending_i ( 1'b0 ) - ); - - logic [NumPart-1:0] tlul_part_sel_oh; - for (genvar k = 0; k < NumPart; k++) begin : gen_part_sel - localparam logic [OtpByteAddrWidth:0] PartEnd = (OtpByteAddrWidth+1)'(PartInfo[k].offset) + - (OtpByteAddrWidth+1)'(PartInfo[k].size); - if (PartInfo[k].offset == 0) begin : gen_zero_offset - assign tlul_part_sel_oh[k] = ({1'b0, {tlul_addr, 2'b00}} < PartEnd); - end else begin : gen_nonzero_offset - assign tlul_part_sel_oh[k] = ({tlul_addr, 2'b00} >= PartInfo[k].offset) & - ({1'b0, {tlul_addr, 2'b00}} < PartEnd); - end - end - - `ASSERT(PartSelMustBeOnehot_A, $onehot0(tlul_part_sel_oh)) - - logic [NumPartWidth-1:0] tlul_part_idx; - prim_arbiter_fixed #( - .N(NumPart), - .EnDataPort(0) - ) u_part_sel_idx ( - .clk_i, - .rst_ni, - .req_i ( tlul_part_sel_oh ), - .data_i ( '{default: '0} ), - .gnt_o ( ), // unused - .idx_o ( tlul_part_idx ), - .valid_o ( ), // unused - .data_o ( ), // unused - .ready_i ( 1'b0 ) - ); - - logic tlul_oob_err_d, tlul_oob_err_q; - logic [NumPart-1:0] part_tlul_req, part_tlul_gnt, part_tlul_rvalid; - logic [SwWindowAddrWidth-1:0] part_tlul_addr; - logic [NumPart-1:0][1:0] part_tlul_rerror; - logic [NumPart-1:0][31:0] part_tlul_rdata; - - always_comb begin : p_tlul_assign - // Send request to the correct partition. - part_tlul_addr = tlul_addr; - part_tlul_req = '0; - tlul_oob_err_d = 1'b0; - if (tlul_req) begin - if (tlul_part_sel_oh != '0) begin - part_tlul_req[tlul_part_idx] = 1'b1; - end else begin - // Error out in the next cycle if address was out of bounds. - tlul_oob_err_d = 1'b1; - end - end - - // aggregate TL-UL responses - tlul_gnt = |part_tlul_gnt | tlul_oob_err_q; - tlul_rvalid = |part_tlul_rvalid | tlul_oob_err_q; - tlul_rerror = '0; - tlul_rdata = '0; - for (int k = 0; k < NumPart; k++) begin - tlul_rerror |= part_tlul_rerror[k]; - tlul_rdata |= part_tlul_rdata[k]; - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_tlul_reg - if (!rst_ni) begin - tlul_oob_err_q <= 1'b0; - end else begin - tlul_oob_err_q <= tlul_oob_err_d; - end - end - - ////////////////////////////// - // Access Defaults and CSRs // - ////////////////////////////// - - // SEC_CM: ACCESS.CTRL.MUBI - part_access_t [NumPart-1:0] part_access_pre, part_access; - always_comb begin : p_access_control - // Assigns default and extracts named CSR read enables for SW_CFG partitions. - // SEC_CM: PART.MEM.REGREN - part_access_pre = named_part_access_pre(reg2hw); - - // Permanently lock DAI write and read access to the life cycle partition. - // The LC partition can only be read from and written to via the LC controller. - // SEC_CM: LC_PART.MEM.SW_NOACCESS - part_access_pre[LifeCycleIdx].write_lock = MuBi8True; - part_access_pre[LifeCycleIdx].read_lock = MuBi8True; - - // Special partitions for keymgr material only become writable when - // provisioning is enabled. - if (lc_ctrl_pkg::lc_tx_test_false_loose(lc_creator_seed_sw_rw_en)) begin - for (int k = 0; k < NumPart; k++) begin - if (PartInfo[k].iskeymgr_creator) begin - part_access_pre[k] = {2{prim_mubi_pkg::MuBi8True}}; - end - end - end - if (lc_ctrl_pkg::lc_tx_test_false_loose(lc_owner_seed_sw_rw_en)) begin - for (int k = 0; k < NumPart; k++) begin - if (PartInfo[k].iskeymgr_owner) begin - part_access_pre[k] = {2{prim_mubi_pkg::MuBi8True}}; - end - end - end - end - - // This prevents the synthesis tool from optimizing the multibit signals. - for (genvar k = 0; k < NumPart; k++) begin : gen_bufs - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_write_lock ( - .clk_i, - .rst_ni, - .mubi_i(part_access_pre[k].write_lock), - .mubi_o(part_access[k].write_lock) - ); - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_read_lock ( - .clk_i, - .rst_ni, - .mubi_i(part_access_pre[k].read_lock), - .mubi_o(part_access[k].read_lock) - ); - end - - ////////////////////// - // DAI-related CSRs // - ////////////////////// - - logic dai_idle; - logic dai_req; - dai_cmd_e dai_cmd; - logic [OtpByteAddrWidth-1:0] dai_addr; - logic [NumDaiWords-1:0][31:0] dai_wdata, dai_rdata; - logic direct_access_regwen_d, direct_access_regwen_q; - - // This is the HWEXT implementation of a RW0C regwen bit. - assign direct_access_regwen_d = (reg2hw.direct_access_regwen.qe && - !reg2hw.direct_access_regwen.q) ? 1'b0 : direct_access_regwen_q; - - // Any write to this register triggers a DAI command. - assign dai_req = reg2hw.direct_access_cmd.digest.qe | - reg2hw.direct_access_cmd.wr.qe | - reg2hw.direct_access_cmd.rd.qe; - - assign dai_cmd = dai_cmd_e'({reg2hw.direct_access_cmd.digest.q, - reg2hw.direct_access_cmd.wr.q, - reg2hw.direct_access_cmd.rd.q}); - - assign dai_addr = reg2hw.direct_access_address.q; - assign dai_wdata = reg2hw.direct_access_wdata; - - // The DAI and the LCI can initiate write transactions, which - // are critical and we must not power down if such transactions - // are pending. Hence, we signal the LCI/DAI idle state to the - // power manager. This signal is flopped here as it has to - // cross a clock boundary to the power manager. - logic dai_prog_idle, lci_prog_idle, otp_idle_d, otp_idle_q; - assign otp_idle_d = lci_prog_idle & dai_prog_idle; - assign pwr_otp_o.otp_idle = otp_idle_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_idle_regwen_regs - if (!rst_ni) begin - otp_idle_q <= 1'b0; - // The regwen bit has to reset to 1 so that CSR accesses are enabled by default. - direct_access_regwen_q <= 1'b1; - end else begin - otp_idle_q <= otp_idle_d; - direct_access_regwen_q <= direct_access_regwen_d; - end - end - - ////////////////////////////////////// - // Ctrl/Status CSRs, Errors, Alerts // - ////////////////////////////////////// - - // Status and error reporting CSRs, error interrupt generation and alerts. - otp_err_e [NumPart+1:0] part_error; - logic [NumAgents-1:0] part_fsm_err; - logic [NumPart+1:0] part_errors_reduced; - logic otp_operation_done, otp_error; - logic fatal_macro_error_d, fatal_macro_error_q; - logic fatal_check_error_d, fatal_check_error_q; - logic fatal_bus_integ_error_d, fatal_bus_integ_error_q; - logic chk_pending, chk_timeout; - logic lfsr_fsm_err, scrmbl_fsm_err; - always_comb begin : p_errors_alerts - // Note: since these are all fatal alert events, we latch them and keep on sending - // alert events via the alert senders. These regs can only be cleared via a system reset. - fatal_macro_error_d = fatal_macro_error_q; - fatal_check_error_d = fatal_check_error_q; - fatal_bus_integ_error_d = fatal_bus_integ_error_q | (|intg_error); - // These are the per-partition buffered escalation inputs - lc_escalate_en = lc_escalate_en_synced; - // Need a single wire for gating assertions in arbitration and CDC primitives. - lc_escalate_en_any = 1'b0; - - // Aggregate all the macro alerts from the partitions - for (int k = 0; k < NumPart; k++) begin - // Filter for critical error codes that should not occur in the field. - fatal_macro_error_d |= part_error[k] == MacroError; - // While uncorrectable ECC errors are always reported, they do not trigger a fatal alert - // event in some partitions like the VENDOR_TEST partition. - if (PartInfo[k].integrity) begin - fatal_macro_error_d |= part_error[k] == MacroEccUncorrError; - end - end - // Aggregate all the macro alerts from the DAI/LCI - for (int k = NumPart; k < NumPart+2; k++) begin - // Filter for critical error codes that should not occur in the field. - fatal_macro_error_d |= part_error[k] inside {MacroError, MacroEccUncorrError}; - end - - // Aggregate all the remaining errors / alerts from the partitions and the DAI/LCI - for (int k = 0; k < NumPart+2; k++) begin - // Set the error bit if the error status of the corresponding partition is nonzero. - // Need to reverse the order here since the field enumeration in hw2reg.status is reversed. - part_errors_reduced[NumPart+1-k] = |part_error[k]; - // Filter for integrity and consistency check failures. - fatal_check_error_d |= part_error[k] inside {CheckFailError, FsmStateError}; - - // If a fatal alert has been observed in any of the partitions/FSMs, - // we locally trigger escalation within OTP, which moves all FSMs - // to a terminal error state. - if (fatal_macro_error_q || fatal_check_error_q) begin - lc_escalate_en[k] = lc_ctrl_pkg::On; - end - if (lc_ctrl_pkg::lc_tx_test_true_strict(lc_escalate_en[k])) begin - lc_escalate_en_any = 1'b1; - end - end - - // Errors from other non-partition FSMs. - fatal_check_error_d |= chk_timeout | - lfsr_fsm_err | - scrmbl_fsm_err | - (|part_fsm_err); - end - - // If we got an error, we trigger an interrupt. - logic [$bits(part_errors_reduced)+4-1:0] interrupt_triggers_d, interrupt_triggers_q; - - // This makes sure that interrupts are not sticky. - assign interrupt_triggers_d = { - part_errors_reduced, - chk_timeout, - lfsr_fsm_err, - scrmbl_fsm_err, - |part_fsm_err - }; - - assign otp_error = |(interrupt_triggers_d & ~interrupt_triggers_q); - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_alert_regs - if (!rst_ni) begin - fatal_macro_error_q <= '0; - fatal_check_error_q <= '0; - fatal_bus_integ_error_q <= '0; - interrupt_triggers_q <= '0; - end else begin - fatal_macro_error_q <= fatal_macro_error_d; - fatal_check_error_q <= fatal_check_error_d; - fatal_bus_integ_error_q <= fatal_bus_integ_error_d; - interrupt_triggers_q <= interrupt_triggers_d; - end - end - - // CSR assignments are done in one combo process so that we can use - // the parameterized digest_assign task below without multiple driver issues. - logic unused_part_digest; - logic [NumPart-1:0][ScrmblBlockWidth-1:0] part_digest; - logic intr_state_otp_operation_done_d, intr_state_otp_operation_done_de; - logic intr_state_otp_error_d, intr_state_otp_error_de; - always_comb begin : p_csr_assign - // Not all partition digests are consumed, and assigning them to an unused_* signal in the - // function below does not seem to work for some linters. - unused_part_digest = ^part_digest; - // Assign named CSRs (like digests). - hw2reg = named_reg_assign(part_digest); - // DAI related CSRs - hw2reg.direct_access_rdata = dai_rdata; - // ANDing this state with dai_idle write-protects all DAI regs during pending operations. - hw2reg.direct_access_regwen.d = direct_access_regwen_q & dai_idle; - // Assign these to the status register. - hw2reg.status = {part_errors_reduced, - chk_timeout, - lfsr_fsm_err, - scrmbl_fsm_err, - part_fsm_err[KdiIdx], - fatal_bus_integ_error_q, - dai_idle, - chk_pending}; - // Error code registers. - hw2reg.err_code = part_error; - // Interrupt signals - hw2reg.intr_state.otp_operation_done.de = intr_state_otp_operation_done_de; - hw2reg.intr_state.otp_operation_done.d = intr_state_otp_operation_done_d; - hw2reg.intr_state.otp_error.de = intr_state_otp_error_de; - hw2reg.intr_state.otp_error.d = intr_state_otp_error_d; -end - - - ////////////////////////////////// - // Interrupts and Alert Senders // - ////////////////////////////////// - - prim_intr_hw #( - .Width(1) - ) u_intr_operation_done ( - .clk_i, - .rst_ni, - .event_intr_i ( otp_operation_done ), - .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.otp_operation_done.q ), - .reg2hw_intr_test_q_i ( reg2hw.intr_test.otp_operation_done.q ), - .reg2hw_intr_test_qe_i ( reg2hw.intr_test.otp_operation_done.qe ), - .reg2hw_intr_state_q_i ( reg2hw.intr_state.otp_operation_done.q ), - .hw2reg_intr_state_de_o ( intr_state_otp_operation_done_de ), - .hw2reg_intr_state_d_o ( intr_state_otp_operation_done_d ), - .intr_o ( intr_otp_operation_done_o ) - ); - - prim_intr_hw #( - .Width(1) - ) u_intr_error ( - .clk_i, - .rst_ni, - .event_intr_i ( otp_error ), - .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.otp_error.q ), - .reg2hw_intr_test_q_i ( reg2hw.intr_test.otp_error.q ), - .reg2hw_intr_test_qe_i ( reg2hw.intr_test.otp_error.qe ), - .reg2hw_intr_state_q_i ( reg2hw.intr_state.otp_error.q ), - .hw2reg_intr_state_de_o ( intr_state_otp_error_de ), - .hw2reg_intr_state_d_o ( intr_state_otp_error_d ), - .intr_o ( intr_otp_error_o ) - ); - - logic [NumAlerts-1:0] alerts; - logic [NumAlerts-1:0] alert_test; - logic fatal_prim_otp_alert, recov_prim_otp_alert; - - assign alerts = { - recov_prim_otp_alert, - fatal_prim_otp_alert, - fatal_bus_integ_error_q, - fatal_check_error_q, - fatal_macro_error_q - }; - - assign alert_test = { - reg2hw.alert_test.recov_prim_otp_alert.q & - reg2hw.alert_test.recov_prim_otp_alert.qe, - reg2hw.alert_test.fatal_prim_otp_alert.q & - reg2hw.alert_test.fatal_prim_otp_alert.qe, - reg2hw.alert_test.fatal_bus_integ_error.q & - reg2hw.alert_test.fatal_bus_integ_error.qe, - reg2hw.alert_test.fatal_check_error.q & - reg2hw.alert_test.fatal_check_error.qe, - reg2hw.alert_test.fatal_macro_error.q & - reg2hw.alert_test.fatal_macro_error.qe - }; - - localparam logic [NumAlerts-1:0] AlertIsFatal = { - 1'b0, // recov_prim_otp_alert - 1'b1, // fatal_prim_otp_alert - 1'b1, // fatal_bus_integ_error_q - 1'b1, // fatal_check_error_q - 1'b1 // fatal_macro_error_q - }; - - for (genvar k = 0; k < NumAlerts; k++) begin : gen_alert_tx - prim_alert_sender #( - .AsyncOn(AlertAsyncOn[k]), - .IsFatal(AlertIsFatal[k]) - ) u_prim_alert_sender ( - .clk_i, - .rst_ni, - .alert_test_i ( alert_test[k] ), - .alert_req_i ( alerts[k] ), - .alert_ack_o ( ), - .alert_state_o ( ), - .alert_rx_i ( alert_rx_i[k] ), - .alert_tx_o ( alert_tx_o[k] ) - ); - end - - //////////////////////////////// - // LFSR Timer and CSR mapping // - //////////////////////////////// - - logic integ_chk_trig, cnsty_chk_trig; - logic [NumPart-1:0] integ_chk_req, integ_chk_ack; - logic [NumPart-1:0] cnsty_chk_req, cnsty_chk_ack; - logic lfsr_edn_req, lfsr_edn_ack; - logic [EdnDataWidth-1:0] edn_data; - - assign integ_chk_trig = reg2hw.check_trigger.integrity.q & - reg2hw.check_trigger.integrity.qe; - assign cnsty_chk_trig = reg2hw.check_trigger.consistency.q & - reg2hw.check_trigger.consistency.qe; - - // SEC_CM: PART.DATA_REG.BKGN_CHK - otp_ctrl_lfsr_timer #( - .RndCnstLfsrSeed(RndCnstLfsrSeed), - .RndCnstLfsrPerm(RndCnstLfsrPerm) - ) u_otp_ctrl_lfsr_timer ( - .clk_i, - .rst_ni, - .edn_req_o ( lfsr_edn_req ), - .edn_ack_i ( lfsr_edn_ack ), - .edn_data_i ( edn_data ), - // We can enable the timer once OTP has initialized. - // Note that this is only the initial release that gets - // the timer FSM into an operational state. - // Whether or not the timers / background checks are - // activated depends on the CSR configuration (by default - // they are switched off). - .timer_en_i ( pwr_otp_o.otp_done ), - // This idle signal is the same that is output to the power - // manager, and indicates whether there is an ongoing OTP programming - // operation. It is used to pause the consistency check timeout - // counter in order to prevent spurious timeouts (OTP programming - // operations are very slow compared to readout operations and can - // hence interfere with the timeout mechanism). - .otp_prog_busy_i ( ~otp_idle_d ), - .integ_chk_trig_i ( integ_chk_trig ), - .cnsty_chk_trig_i ( cnsty_chk_trig ), - .chk_pending_o ( chk_pending ), - .timeout_i ( reg2hw.check_timeout.q ), - .integ_period_msk_i ( reg2hw.integrity_check_period.q ), - .cnsty_period_msk_i ( reg2hw.consistency_check_period.q ), - .integ_chk_req_o ( integ_chk_req ), - .cnsty_chk_req_o ( cnsty_chk_req ), - .integ_chk_ack_i ( integ_chk_ack ), - .cnsty_chk_ack_i ( cnsty_chk_ack ), - .escalate_en_i ( lc_escalate_en[NumAgents] ), - .chk_timeout_o ( chk_timeout ), - .fsm_err_o ( lfsr_fsm_err ) - ); - - /////////////////////////////////////// - // EDN Arbitration, Request and Sync // - /////////////////////////////////////// - - // Both the key derivation and LFSR reseeding are low bandwidth, - // hence they can share the same EDN interface. - logic edn_req, edn_ack; - logic key_edn_req, key_edn_ack; - prim_arbiter_tree #( - .N(2), - .EnDataPort(0) - ) u_edn_arb ( - .clk_i, - .rst_ni, - .req_chk_i ( ~lc_escalate_en_any ), - .req_i ( {lfsr_edn_req, key_edn_req} ), - .data_i ( '{default: '0} ), - .gnt_o ( {lfsr_edn_ack, key_edn_ack} ), - .idx_o ( ), // unused - .valid_o ( edn_req ), - .data_o ( ), // unused - .ready_i ( edn_ack ) - ); - - // This synchronizes the data coming from EDN and stacks the - // 32bit EDN words to achieve an internal entropy width of 64bit. - prim_edn_req #( - .OutWidth(EdnDataWidth) - ) u_prim_edn_req ( - .clk_i, - .rst_ni, - .req_chk_i ( ~lc_escalate_en_any ), - .req_i ( edn_req ), - .ack_o ( edn_ack ), - .data_o ( edn_data ), - .fips_o ( ), // unused - .err_o ( ), // unused - .clk_edn_i, - .rst_edn_ni, - .edn_o, - .edn_i - ); - - /////////////////////////////// - // OTP Macro and Arbitration // - /////////////////////////////// - - typedef struct packed { - prim_otp_pkg::cmd_e cmd; - logic [OtpSizeWidth-1:0] size; // Number of native words to write. - logic [OtpIfWidth-1:0] wdata; - logic [OtpAddrWidth-1:0] addr; // Halfword address. - } otp_bundle_t; - - logic [NumAgents-1:0] part_otp_arb_req, part_otp_arb_gnt; - otp_bundle_t part_otp_arb_bundle [NumAgents]; - logic otp_arb_valid, otp_arb_ready; - logic otp_prim_valid, otp_prim_ready; - logic otp_rsp_fifo_valid, otp_rsp_fifo_ready; - logic [vbits(NumAgents)-1:0] otp_arb_idx; - otp_bundle_t otp_arb_bundle; - - // The OTP interface is arbitrated on a per-cycle basis, meaning that back-to-back - // transactions can be completely independent. - prim_arbiter_tree #( - .N(NumAgents), - .DW($bits(otp_bundle_t)) - ) u_otp_arb ( - .clk_i, - .rst_ni, - .req_chk_i ( ~lc_escalate_en_any ), - .req_i ( part_otp_arb_req ), - .data_i ( part_otp_arb_bundle ), - .gnt_o ( part_otp_arb_gnt ), - .idx_o ( otp_arb_idx ), - .valid_o ( otp_arb_valid ), - .data_o ( otp_arb_bundle ), - .ready_i ( otp_arb_ready ) - ); - - // Don't issue more transactions than what the rsp_fifo can keep track of. - assign otp_arb_ready = otp_prim_ready & otp_rsp_fifo_ready; - assign otp_prim_valid = otp_arb_valid & otp_rsp_fifo_ready; - assign otp_rsp_fifo_valid = otp_prim_ready & otp_prim_valid; - - prim_otp_pkg::err_e part_otp_err; - logic [OtpIfWidth-1:0] part_otp_rdata; - logic otp_rvalid; - tlul_pkg::tl_h2d_t prim_tl_h2d_gated; - tlul_pkg::tl_d2h_t prim_tl_d2h_gated; - - // Life cycle qualification of TL-UL test interface. - // SEC_CM: TEST.BUS.LC_GATED - // SEC_CM: TEST_TL_LC_GATE.FSM.SPARSE - tlul_lc_gate #( - .NumGatesPerDirection(2) - ) u_tlul_lc_gate ( - .clk_i, - .rst_ni, - .tl_h2d_i(prim_tl_i), - .tl_d2h_o(prim_tl_o), - .tl_h2d_o(prim_tl_h2d_gated), - .tl_d2h_i(prim_tl_d2h_gated), - .lc_en_i (lc_dft_en[0]), - .flush_req_i('0), - .flush_ack_o(), - .resp_pending_o(), - .err_o (intg_error[2]) - ); - - // Test-related GPIOs. - // SEC_CM: TEST.BUS.LC_GATED - logic [OtpTestVectWidth-1:0] otp_test_vect; - assign cio_test_o = (lc_ctrl_pkg::lc_tx_test_true_strict(lc_dft_en[1])) ? - otp_test_vect : '0; - assign cio_test_en_o = (lc_ctrl_pkg::lc_tx_test_true_strict(lc_dft_en[2])) ? - {OtpTestVectWidth{1'b1}} : '0; - - // SEC_CM: MACRO.MEM.CM, MACRO.MEM.INTEGRITY - prim_otp #( - .Width ( OtpWidth ), - .Depth ( OtpDepth ), - .SizeWidth ( OtpSizeWidth ), - .PwrSeqWidth ( OtpPwrSeqWidth ), - .TestCtrlWidth ( OtpTestCtrlWidth ), - .TestStatusWidth ( OtpTestStatusWidth ), - .TestVectWidth ( OtpTestVectWidth ), - .MemInitFile ( MemInitFile ), - .VendorTestOffset ( VendorTestOffset ), - .VendorTestSize ( VendorTestSize ) - ) u_otp ( - .clk_i, - .rst_ni, - // Observability controls to/from AST - .obs_ctrl_i, - .otp_obs_o, - // Power sequencing signals to/from AST - .pwr_seq_o ( otp_ast_pwr_seq_o.pwr_seq ), - .pwr_seq_h_i ( otp_ast_pwr_seq_h_i.pwr_seq_h ), - .ext_voltage_io ( otp_ext_voltage_h_io ), - // Test interface - .test_ctrl_i ( lc_otp_vendor_test_i.ctrl ), - .test_status_o ( lc_otp_vendor_test_o.status ), - .test_vect_o ( otp_test_vect ), - .test_tl_i ( prim_tl_h2d_gated ), - .test_tl_o ( prim_tl_d2h_gated ), - // Other DFT signals - .scan_en_i, - .scan_rst_ni, - .scanmode_i, - // Alerts - .fatal_alert_o ( fatal_prim_otp_alert ), - .recov_alert_o ( recov_prim_otp_alert ), - // Read / Write command interface - .ready_o ( otp_prim_ready ), - .valid_i ( otp_prim_valid ), - .cmd_i ( otp_arb_bundle.cmd ), - .size_i ( otp_arb_bundle.size ), - .addr_i ( otp_arb_bundle.addr ), - .wdata_i ( otp_arb_bundle.wdata ), - // Read data out - .valid_o ( otp_rvalid ), - .rdata_o ( part_otp_rdata ), - .err_o ( part_otp_err ) - ); - - logic otp_fifo_valid; - logic [vbits(NumAgents)-1:0] otp_part_idx; - logic [NumAgents-1:0] part_otp_rvalid; - - // We can have up to two OTP commands in flight, hence we size this to be 2 deep. - // The partitions can unconditionally sink requested data. - prim_fifo_sync #( - .Width(vbits(NumAgents)), - .Depth(2) - ) u_otp_rsp_fifo ( - .clk_i, - .rst_ni, - .clr_i ( 1'b0 ), - .wvalid_i ( otp_rsp_fifo_valid ), - .wready_o ( otp_rsp_fifo_ready ), - .wdata_i ( otp_arb_idx ), - .rvalid_o ( otp_fifo_valid ), - .rready_i ( otp_rvalid ), - .rdata_o ( otp_part_idx ), - .depth_o ( ), - .full_o ( ), - .err_o ( ) - ); - - // Steer response back to the partition where this request originated. - always_comb begin : p_rvalid - part_otp_rvalid = '0; - part_otp_rvalid[otp_part_idx] = otp_rvalid & otp_fifo_valid; - end - - // Note that this must be true by construction. - `ASSERT(OtpRespFifoUnderflow_A, otp_rvalid |-> otp_fifo_valid) - - ///////////////////////////////////////// - // Scrambling Datapath and Arbitration // - ///////////////////////////////////////// - - // Note: as opposed to the OTP arbitration above, we do not perform cycle-wise arbitration, but - // transaction-wise arbitration. This is implemented using a RR arbiter that acts as a mutex. - // I.e., each agent (e.g. the DAI or a partition) can request a lock on the mutex. Once granted, - // the partition can keep the lock as long as needed for the transaction to complete. The - // partition must yield its lock by deasserting the request signal for the arbiter to proceed. - // Since this scheme does not have built-in preemtion, it must be ensured that the agents - // eventually release their locks for this to be fair. - // - // See also https://docs.opentitan.org/hw/ip/otp_ctrl/doc/index.html#block-diagram for details. - typedef struct packed { - otp_scrmbl_cmd_e cmd; - digest_mode_e mode; - logic [ConstSelWidth-1:0] sel; - logic [ScrmblBlockWidth-1:0] data; - logic valid; - } scrmbl_bundle_t; - - logic [NumAgents-1:0] part_scrmbl_mtx_req, part_scrmbl_mtx_gnt; - scrmbl_bundle_t part_scrmbl_req_bundle [NumAgents]; - scrmbl_bundle_t scrmbl_req_bundle; - logic [vbits(NumAgents)-1:0] scrmbl_mtx_idx; - logic scrmbl_mtx_valid; - - // Note that arbiter decisions do not change when backpressured. - // Hence, the idx_o signal is guaranteed to remain stable until ack'ed. - prim_arbiter_tree #( - .N(NumAgents), - .DW($bits(scrmbl_bundle_t)) - ) u_scrmbl_mtx ( - .clk_i, - .rst_ni, - .req_chk_i ( 1'b0 ), // REQ is allowed to go low again without ACK even - // during normal operation. - .req_i ( part_scrmbl_mtx_req ), - .data_i ( part_scrmbl_req_bundle ), - .gnt_o ( ), - .idx_o ( scrmbl_mtx_idx ), - .valid_o ( scrmbl_mtx_valid ), - .data_o ( scrmbl_req_bundle ), - .ready_i ( 1'b0 ) - ); - - // Since the ready_i signal of the arbiter is statically set to 1'b0 above, we are always in a - // "backpressure" situation, where the RR arbiter will automatically advance the internal RR state - // to give the current winner max priority in subsequent cycles in order to keep the decision - // stable. Rearbitration occurs once the winning agent deasserts its request. - always_comb begin : p_mutex - part_scrmbl_mtx_gnt = '0; - part_scrmbl_mtx_gnt[scrmbl_mtx_idx] = scrmbl_mtx_valid; - end - - logic [ScrmblBlockWidth-1:0] part_scrmbl_rsp_data; - logic scrmbl_arb_req_ready, scrmbl_arb_rsp_valid; - logic [NumAgents-1:0] part_scrmbl_req_ready, part_scrmbl_rsp_valid; - - // SEC_CM: SECRET.MEM.SCRAMBLE - // SEC_CM: PART.MEM.DIGEST - otp_ctrl_scrmbl u_otp_ctrl_scrmbl ( - .clk_i, - .rst_ni, - .cmd_i ( scrmbl_req_bundle.cmd ), - .mode_i ( scrmbl_req_bundle.mode ), - .sel_i ( scrmbl_req_bundle.sel ), - .data_i ( scrmbl_req_bundle.data ), - .valid_i ( scrmbl_req_bundle.valid ), - .ready_o ( scrmbl_arb_req_ready ), - .data_o ( part_scrmbl_rsp_data ), - .valid_o ( scrmbl_arb_rsp_valid ), - .escalate_en_i ( lc_escalate_en[NumAgents+1] ), - .fsm_err_o ( scrmbl_fsm_err ) - ); - - // steer back responses - always_comb begin : p_scmrbl_resp - part_scrmbl_req_ready = '0; - part_scrmbl_rsp_valid = '0; - part_scrmbl_req_ready[scrmbl_mtx_idx] = scrmbl_arb_req_ready; - part_scrmbl_rsp_valid[scrmbl_mtx_idx] = scrmbl_arb_rsp_valid; - end - - ///////////////////////////// - // Direct Access Interface // - ///////////////////////////// - - logic part_init_req; - logic [NumPart-1:0] part_init_done; - part_access_t [NumPart-1:0] part_access_dai; - - // The init request comes from the power manager, which lives in the AON clock domain. - logic pwr_otp_req_synced; - prim_flop_2sync #( - .Width(1) - ) u_otp_init_sync ( - .clk_i, - .rst_ni, - .d_i ( pwr_otp_i.otp_init ), - .q_o ( pwr_otp_req_synced ) - ); - - // Register this signal as it has to cross a clock boundary. - logic pwr_otp_rsp_d, pwr_otp_rsp_q; - assign pwr_otp_o.otp_done = pwr_otp_rsp_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_init_reg - if (!rst_ni) begin - pwr_otp_rsp_q <= 1'b0; - end else begin - pwr_otp_rsp_q <= pwr_otp_rsp_d; - end - end - - otp_ctrl_dai u_otp_ctrl_dai ( - .clk_i, - .rst_ni, - .init_req_i ( pwr_otp_req_synced ), - .init_done_o ( pwr_otp_rsp_d ), - .part_init_req_o ( part_init_req ), - .part_init_done_i ( part_init_done ), - .escalate_en_i ( lc_escalate_en[DaiIdx] ), - .error_o ( part_error[DaiIdx] ), - .fsm_err_o ( part_fsm_err[DaiIdx] ), - .part_access_i ( part_access_dai ), - .dai_addr_i ( dai_addr ), - .dai_cmd_i ( dai_cmd ), - .dai_req_i ( dai_req ), - .dai_wdata_i ( dai_wdata ), - .dai_idle_o ( dai_idle ), - .dai_prog_idle_o ( dai_prog_idle ), - .dai_cmd_done_o ( otp_operation_done ), - .dai_rdata_o ( dai_rdata ), - .otp_req_o ( part_otp_arb_req[DaiIdx] ), - .otp_cmd_o ( part_otp_arb_bundle[DaiIdx].cmd ), - .otp_size_o ( part_otp_arb_bundle[DaiIdx].size ), - .otp_wdata_o ( part_otp_arb_bundle[DaiIdx].wdata ), - .otp_addr_o ( part_otp_arb_bundle[DaiIdx].addr ), - .otp_gnt_i ( part_otp_arb_gnt[DaiIdx] ), - .otp_rvalid_i ( part_otp_rvalid[DaiIdx] ), - .otp_rdata_i ( part_otp_rdata ), - .otp_err_i ( part_otp_err ), - .scrmbl_mtx_req_o ( part_scrmbl_mtx_req[DaiIdx] ), - .scrmbl_mtx_gnt_i ( part_scrmbl_mtx_gnt[DaiIdx] ), - .scrmbl_cmd_o ( part_scrmbl_req_bundle[DaiIdx].cmd ), - .scrmbl_mode_o ( part_scrmbl_req_bundle[DaiIdx].mode ), - .scrmbl_sel_o ( part_scrmbl_req_bundle[DaiIdx].sel ), - .scrmbl_data_o ( part_scrmbl_req_bundle[DaiIdx].data ), - .scrmbl_valid_o ( part_scrmbl_req_bundle[DaiIdx].valid ), - .scrmbl_ready_i ( part_scrmbl_req_ready[DaiIdx] ), - .scrmbl_valid_i ( part_scrmbl_rsp_valid[DaiIdx] ), - .scrmbl_data_i ( part_scrmbl_rsp_data ) - ); - - //////////////////////////////////// - // Lifecycle Transition Interface // - //////////////////////////////////// - - logic [PartInfo[LifeCycleIdx].size-1:0][7:0] lc_otp_program_data; - assign lc_otp_program_data[LcStateOffset-LifeCycleOffset +: LcStateSize] = - lc_otp_program_i.state; - assign lc_otp_program_data[LcTransitionCntOffset-LifeCycleOffset +: LcTransitionCntSize] = - lc_otp_program_i.count; - - otp_ctrl_lci #( - .Info(PartInfo[LifeCycleIdx]) - ) u_otp_ctrl_lci ( - .clk_i, - .rst_ni, - .lci_en_i ( pwr_otp_o.otp_done ), - .escalate_en_i ( lc_escalate_en[LciIdx] ), - .error_o ( part_error[LciIdx] ), - .fsm_err_o ( part_fsm_err[LciIdx] ), - .lci_prog_idle_o ( lci_prog_idle ), - .lc_req_i ( lc_otp_program_i.req ), - .lc_data_i ( lc_otp_program_data ), - .lc_ack_o ( lc_otp_program_o.ack ), - .lc_err_o ( lc_otp_program_o.err ), - .otp_req_o ( part_otp_arb_req[LciIdx] ), - .otp_cmd_o ( part_otp_arb_bundle[LciIdx].cmd ), - .otp_size_o ( part_otp_arb_bundle[LciIdx].size ), - .otp_wdata_o ( part_otp_arb_bundle[LciIdx].wdata ), - .otp_addr_o ( part_otp_arb_bundle[LciIdx].addr ), - .otp_gnt_i ( part_otp_arb_gnt[LciIdx] ), - .otp_rvalid_i ( part_otp_rvalid[LciIdx] ), - .otp_rdata_i ( part_otp_rdata ), - .otp_err_i ( part_otp_err ) - ); - - // Tie off unused connections. - assign part_scrmbl_mtx_req[LciIdx] = '0; - assign part_scrmbl_req_bundle[LciIdx] = '0; - - // This stops lint from complaining about unused signals. - logic unused_lci_scrmbl_sigs; - assign unused_lci_scrmbl_sigs = ^{part_scrmbl_mtx_gnt[LciIdx], - part_scrmbl_req_ready[LciIdx], - part_scrmbl_rsp_valid[LciIdx]}; - - //////////////////////////////////// - // Key Derivation Interface (KDI) // - //////////////////////////////////// - - logic scrmbl_key_seed_valid; - logic [SramKeySeedWidth-1:0] sram_data_key_seed; - logic [FlashKeySeedWidth-1:0] flash_data_key_seed, flash_addr_key_seed; - - otp_ctrl_kdi #( - .RndCnstScrmblKeyInit(RndCnstScrmblKeyInit) - ) u_otp_ctrl_kdi ( - .clk_i, - .rst_ni, - .kdi_en_i ( pwr_otp_o.otp_done ), - .escalate_en_i ( lc_escalate_en[KdiIdx] ), - .fsm_err_o ( part_fsm_err[KdiIdx] ), - .scrmbl_key_seed_valid_i ( scrmbl_key_seed_valid ), - .flash_data_key_seed_i ( flash_data_key_seed ), - .flash_addr_key_seed_i ( flash_addr_key_seed ), - .sram_data_key_seed_i ( sram_data_key_seed ), - .edn_req_o ( key_edn_req ), - .edn_ack_i ( key_edn_ack ), - .edn_data_i ( edn_data ), - .flash_otp_key_i, - .flash_otp_key_o, - .sram_otp_key_i, - .sram_otp_key_o, - .otbn_otp_key_i, - .otbn_otp_key_o, - .scrmbl_mtx_req_o ( part_scrmbl_mtx_req[KdiIdx] ), - .scrmbl_mtx_gnt_i ( part_scrmbl_mtx_gnt[KdiIdx] ), - .scrmbl_cmd_o ( part_scrmbl_req_bundle[KdiIdx].cmd ), - .scrmbl_mode_o ( part_scrmbl_req_bundle[KdiIdx].mode ), - .scrmbl_sel_o ( part_scrmbl_req_bundle[KdiIdx].sel ), - .scrmbl_data_o ( part_scrmbl_req_bundle[KdiIdx].data ), - .scrmbl_valid_o ( part_scrmbl_req_bundle[KdiIdx].valid ), - .scrmbl_ready_i ( part_scrmbl_req_ready[KdiIdx] ), - .scrmbl_valid_i ( part_scrmbl_rsp_valid[KdiIdx] ), - .scrmbl_data_i ( part_scrmbl_rsp_data ) - ); - - // Tie off OTP bus access, since this is not needed. - assign part_otp_arb_req[KdiIdx] = 1'b0; - assign part_otp_arb_bundle[KdiIdx] = '0; - - // This stops lint from complaining about unused signals. - logic unused_kdi_otp_sigs; - assign unused_kdi_otp_sigs = ^{part_otp_arb_gnt[KdiIdx], - part_otp_rvalid[KdiIdx]}; - - ///////////////////////// - // Partition Instances // - ///////////////////////// - - logic [$bits(PartInvDefault)/8-1:0][7:0] part_buf_data; - - for (genvar k = 0; k < NumPart; k ++) begin : gen_partitions - //////////////////////////////////////////////////////////////////////////////////////////////// - if (PartInfo[k].variant == Unbuffered) begin : gen_unbuffered - otp_ctrl_part_unbuf #( - .Info(PartInfo[k]) - ) u_part_unbuf ( - .clk_i, - .rst_ni, - .init_req_i ( part_init_req ), - .init_done_o ( part_init_done[k] ), - .escalate_en_i ( lc_escalate_en[k] ), - .error_o ( part_error[k] ), - .fsm_err_o ( part_fsm_err[k] ), - .access_i ( part_access[k] ), - .access_o ( part_access_dai[k] ), - .digest_o ( part_digest[k] ), - .tlul_req_i ( part_tlul_req[k] ), - .tlul_gnt_o ( part_tlul_gnt[k] ), - .tlul_addr_i ( part_tlul_addr ), - .tlul_rerror_o ( part_tlul_rerror[k] ), - .tlul_rvalid_o ( part_tlul_rvalid[k] ), - .tlul_rdata_o ( part_tlul_rdata[k] ), - .otp_req_o ( part_otp_arb_req[k] ), - .otp_cmd_o ( part_otp_arb_bundle[k].cmd ), - .otp_size_o ( part_otp_arb_bundle[k].size ), - .otp_wdata_o ( part_otp_arb_bundle[k].wdata ), - .otp_addr_o ( part_otp_arb_bundle[k].addr ), - .otp_gnt_i ( part_otp_arb_gnt[k] ), - .otp_rvalid_i ( part_otp_rvalid[k] ), - .otp_rdata_i ( part_otp_rdata ), - .otp_err_i ( part_otp_err ) - ); - - // Tie off unused connections. - assign part_scrmbl_mtx_req[k] = '0; - assign part_scrmbl_req_bundle[k] = '0; - // These checks do not exist in this partition type, - // so we always acknowledge the request. - assign integ_chk_ack[k] = 1'b1; - assign cnsty_chk_ack[k] = 1'b1; - - // No buffered data to expose. - assign part_buf_data[PartInfo[k].offset +: PartInfo[k].size] = '0; - - // This stops lint from complaining about unused signals. - logic unused_part_scrmbl_sigs; - assign unused_part_scrmbl_sigs = ^{part_scrmbl_mtx_gnt[k], - part_scrmbl_req_ready[k], - part_scrmbl_rsp_valid[k], - integ_chk_req[k], - cnsty_chk_req[k]}; - - // Alert assertion for sparse FSM. - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlPartUnbufFsmCheck_A, - u_part_unbuf.u_state_regs, alert_tx_o[1]) - //////////////////////////////////////////////////////////////////////////////////////////////// - end else if (PartInfo[k].variant == Buffered) begin : gen_buffered - otp_ctrl_part_buf #( - .Info(PartInfo[k]), - .DataDefault(PartInvDefault[PartInfo[k].offset*8 +: PartInfo[k].size*8]) - ) u_part_buf ( - .clk_i, - .rst_ni, - .init_req_i ( part_init_req ), - .init_done_o ( part_init_done[k] ), - .integ_chk_req_i ( integ_chk_req[k] ), - .integ_chk_ack_o ( integ_chk_ack[k] ), - .cnsty_chk_req_i ( cnsty_chk_req[k] ), - .cnsty_chk_ack_o ( cnsty_chk_ack[k] ), - .escalate_en_i ( lc_escalate_en[k] ), - // Only supported by life cycle partition (see further below). - .check_byp_en_i ( lc_ctrl_pkg::Off ), - .error_o ( part_error[k] ), - .fsm_err_o ( part_fsm_err[k] ), - .access_i ( part_access[k] ), - .access_o ( part_access_dai[k] ), - .digest_o ( part_digest[k] ), - .data_o ( part_buf_data[PartInfo[k].offset +: PartInfo[k].size] ), - .otp_req_o ( part_otp_arb_req[k] ), - .otp_cmd_o ( part_otp_arb_bundle[k].cmd ), - .otp_size_o ( part_otp_arb_bundle[k].size ), - .otp_wdata_o ( part_otp_arb_bundle[k].wdata ), - .otp_addr_o ( part_otp_arb_bundle[k].addr ), - .otp_gnt_i ( part_otp_arb_gnt[k] ), - .otp_rvalid_i ( part_otp_rvalid[k] ), - .otp_rdata_i ( part_otp_rdata ), - .otp_err_i ( part_otp_err ), - .scrmbl_mtx_req_o ( part_scrmbl_mtx_req[k] ), - .scrmbl_mtx_gnt_i ( part_scrmbl_mtx_gnt[k] ), - .scrmbl_cmd_o ( part_scrmbl_req_bundle[k].cmd ), - .scrmbl_mode_o ( part_scrmbl_req_bundle[k].mode ), - .scrmbl_sel_o ( part_scrmbl_req_bundle[k].sel ), - .scrmbl_data_o ( part_scrmbl_req_bundle[k].data ), - .scrmbl_valid_o ( part_scrmbl_req_bundle[k].valid ), - .scrmbl_ready_i ( part_scrmbl_req_ready[k] ), - .scrmbl_valid_i ( part_scrmbl_rsp_valid[k] ), - .scrmbl_data_i ( part_scrmbl_rsp_data ) - ); - - // Buffered partitions are not accessible via the TL-UL window. - logic unused_part_tlul_sigs; - assign unused_part_tlul_sigs = ^part_tlul_req[k]; - assign part_tlul_gnt[k] = 1'b0; - assign part_tlul_rerror[k] = '0; - assign part_tlul_rvalid[k] = 1'b0; - assign part_tlul_rdata[k] = '0; - - // Alert assertion for sparse FSM. - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlPartBufFsmCheck_A, - u_part_buf.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntPartBufCheck_A, - u_part_buf.u_prim_count, alert_tx_o[1]) - //////////////////////////////////////////////////////////////////////////////////////////////// - end else if (PartInfo[k].variant == LifeCycle) begin : gen_lifecycle - otp_ctrl_part_buf #( - .Info(PartInfo[k]), - .DataDefault(PartInvDefault[PartInfo[k].offset*8 +: PartInfo[k].size*8]) - ) u_part_buf ( - .clk_i, - .rst_ni, - .init_req_i ( part_init_req ), - .init_done_o ( part_init_done[k] ), - .integ_chk_req_i ( integ_chk_req[k] ), - .integ_chk_ack_o ( integ_chk_ack[k] ), - .cnsty_chk_req_i ( cnsty_chk_req[k] ), - .cnsty_chk_ack_o ( cnsty_chk_ack[k] ), - .escalate_en_i ( lc_escalate_en[k] ), - // This is only supported by the life cycle partition. We need to prevent this partition - // from escalating once the life cycle state in memory is being updated (and hence not - // consistent with the values in the buffer regs anymore). - .check_byp_en_i ( lc_check_byp_en ), - .error_o ( part_error[k] ), - .fsm_err_o ( part_fsm_err[k] ), - .access_i ( part_access[k] ), - .access_o ( part_access_dai[k] ), - .digest_o ( part_digest[k] ), - .data_o ( part_buf_data[PartInfo[k].offset +: PartInfo[k].size] ), - .otp_req_o ( part_otp_arb_req[k] ), - .otp_cmd_o ( part_otp_arb_bundle[k].cmd ), - .otp_size_o ( part_otp_arb_bundle[k].size ), - .otp_wdata_o ( part_otp_arb_bundle[k].wdata ), - .otp_addr_o ( part_otp_arb_bundle[k].addr ), - .otp_gnt_i ( part_otp_arb_gnt[k] ), - .otp_rvalid_i ( part_otp_rvalid[k] ), - .otp_rdata_i ( part_otp_rdata ), - .otp_err_i ( part_otp_err ), - // The LC partition does not need any scrambling features. - .scrmbl_mtx_req_o ( ), - .scrmbl_mtx_gnt_i ( 1'b0 ), - .scrmbl_cmd_o ( ), - .scrmbl_mode_o ( ), - .scrmbl_sel_o ( ), - .scrmbl_data_o ( ), - .scrmbl_valid_o ( ), - .scrmbl_ready_i ( 1'b0 ), - .scrmbl_valid_i ( 1'b0 ), - .scrmbl_data_i ( '0 ) - ); - - // Buffered partitions are not accessible via the TL-UL window. - logic unused_part_tlul_sigs; - assign unused_part_tlul_sigs = ^part_tlul_req[k]; - assign part_tlul_gnt[k] = 1'b0; - assign part_tlul_rerror[k] = '0; - assign part_tlul_rvalid[k] = 1'b0; - assign part_tlul_rdata[k] = '0; - - // Tie off unused connections. - assign part_scrmbl_mtx_req[k] = '0; - assign part_scrmbl_req_bundle[k] = '0; - - // This stops lint from complaining about unused signals. - logic unused_part_scrmbl_sigs; - assign unused_part_scrmbl_sigs = ^{part_scrmbl_mtx_gnt[k], - part_scrmbl_req_ready[k], - part_scrmbl_rsp_valid[k]}; - // Alert assertion for sparse FSM. - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlPartLcFsmCheck_A, - u_part_buf.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntPartLcCheck_A, - u_part_buf.u_prim_count, alert_tx_o[1]) - //////////////////////////////////////////////////////////////////////////////////////////////// - end else begin : gen_invalid - // This is invalid and should break elaboration - assert_static_in_generate_invalid assert_static_in_generate_invalid(); - end - //////////////////////////////////////////////////////////////////////////////////////////////// - end - - ////////////////////////////////// - // Buffered Data Output Mapping // - ////////////////////////////////// - - // Output complete hardware config partition. - // Actual mapping to other IPs is done via the intersignal topgen feature, - // selection of fields can be done using the otp_hw_cfg_t struct fields. - otp_broadcast_t otp_broadcast; - assign otp_broadcast = named_broadcast_assign(part_init_done, part_buf_data); - - // Make sure the broadcast valid is flopped before sending it out. - lc_ctrl_pkg::lc_tx_t otp_broadcast_valid_q; - prim_lc_sender u_prim_lc_sender_otp_broadcast_valid ( - .clk_i, - .rst_ni, - .lc_en_i(otp_broadcast.valid), - .lc_en_o(otp_broadcast_valid_q) - ); - - always_comb begin : p_otp_broadcast_valid - otp_broadcast_o = otp_broadcast; - otp_broadcast_o.valid = otp_broadcast_valid_q; - end - - // Root keys and seeds. - // This uses a generated function to assign all collateral that is marked with "iskeymgr" in - // the memory map. Note that in this case the type is static and represents a superset of all - // options so that we can maintain a stable interface with keymgr (otherwise keymgr will have - // to be templated as well. Unused key material will be tied off to '0. The keymgr has to be - // parameterized accordingly (via SV parameters) to consume the correct key material. - // - // The key material valid signals are set to true if the corresponding digest is nonzero and the - // partition is initialized. On top of that, the entire output is gated by lc_seed_hw_rd_en. - otp_keymgr_key_t otp_keymgr_key; - assign otp_keymgr_key = named_keymgr_key_assign(part_digest, - part_buf_data, - lc_seed_hw_rd_en); - - // Note regarding these breakouts: named_keymgr_key_assign will tie off unused key material / - // valid signals to '0. This is the case for instance in system configurations that keep the seed - // material in the flash instead of OTP. - logic creator_root_key_share0_valid_d, creator_root_key_share0_valid_q; - logic creator_root_key_share1_valid_d, creator_root_key_share1_valid_q; - logic creator_seed_valid_d, creator_seed_valid_q; - logic owner_seed_valid_d, owner_seed_valid_q; - prim_flop #( - .Width(4) - ) u_keygmr_key_valid ( - .clk_i, - .rst_ni, - .d_i ({creator_root_key_share0_valid_d, - creator_root_key_share1_valid_d, - creator_seed_valid_d, - owner_seed_valid_d}), - .q_o ({creator_root_key_share0_valid_q, - creator_root_key_share1_valid_q, - creator_seed_valid_q, - owner_seed_valid_q}) - ); - - always_comb begin : p_otp_keymgr_key_valid - // Valid reg inputs - creator_root_key_share0_valid_d = otp_keymgr_key.creator_root_key_share0_valid; - creator_root_key_share1_valid_d = otp_keymgr_key.creator_root_key_share1_valid; - creator_seed_valid_d = otp_keymgr_key.creator_seed_valid; - owner_seed_valid_d = otp_keymgr_key.owner_seed_valid; - // Output to keymgr - otp_keymgr_key_o = otp_keymgr_key; - otp_keymgr_key_o.creator_root_key_share0_valid = creator_root_key_share0_valid_q; - otp_keymgr_key_o.creator_root_key_share1_valid = creator_root_key_share1_valid_q; - otp_keymgr_key_o.creator_seed_valid = creator_seed_valid_q; - otp_keymgr_key_o.owner_seed_valid = owner_seed_valid_q; - end - - // Check that the lc_seed_hw_rd_en remains stable, once the key material is valid. - `ASSERT(LcSeedHwRdEnStable0_A, - $rose(creator_root_key_share0_valid_q) |=> $stable(lc_seed_hw_rd_en) [*1:$], - clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i) // Disable if escalating - ) - `ASSERT(LcSeedHwRdEnStable1_A, - $rose(creator_root_key_share1_valid_q) |=> $stable(lc_seed_hw_rd_en) [*1:$], - clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i) // Disable if escalating - ) - `ASSERT(LcSeedHwRdEnStable2_A, - $rose(creator_seed_valid_q) |=> $stable(lc_seed_hw_rd_en) [*1:$], - clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i) // Disable if escalating - ) - `ASSERT(LcSeedHwRdEnStable3_A, - $rose(owner_seed_valid_q) |=> $stable(lc_seed_hw_rd_en) [*1:$], - clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i) // Disable if escalating - ) - - // Scrambling Keys - assign scrmbl_key_seed_valid = part_digest[Secret1Idx] != '0; - assign sram_data_key_seed = part_buf_data[SramDataKeySeedOffset +: - SramDataKeySeedSize]; - assign flash_data_key_seed = part_buf_data[FlashDataKeySeedOffset +: - FlashDataKeySeedSize]; - assign flash_addr_key_seed = part_buf_data[FlashAddrKeySeedOffset +: - FlashAddrKeySeedSize]; - - // Test unlock and exit tokens and RMA token - assign otp_lc_data_o.test_exit_token = part_buf_data[TestExitTokenOffset +: - TestExitTokenSize]; - assign otp_lc_data_o.test_unlock_token = part_buf_data[TestUnlockTokenOffset +: - TestUnlockTokenSize]; - assign otp_lc_data_o.rma_token = part_buf_data[RmaTokenOffset +: - RmaTokenSize]; - - lc_ctrl_pkg::lc_tx_t test_tokens_valid, rma_token_valid, secrets_valid; - // The test tokens have been provisioned. - assign test_tokens_valid = (part_digest[Secret0Idx] != '0) ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; - // The rma token has been provisioned. - assign rma_token_valid = (part_digest[Secret2Idx] != '0) ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; - // The device is personalized if the root key has been provisioned and locked. - assign secrets_valid = (part_digest[Secret2Idx] != '0) ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; - - // Buffer these constants in order to ensure that synthesis does not try to optimize the encoding. - // SEC_CM: TOKEN_VALID.CTRL.MUBI - prim_lc_sender #( - .AsyncOn(0) - ) u_prim_lc_sender_test_tokens_valid ( - .clk_i, - .rst_ni, - .lc_en_i(test_tokens_valid), - .lc_en_o(otp_lc_data_o.test_tokens_valid) - ); - - prim_lc_sender #( - .AsyncOn(0) - ) u_prim_lc_sender_rma_token_valid ( - .clk_i, - .rst_ni, - .lc_en_i(rma_token_valid), - .lc_en_o(otp_lc_data_o.rma_token_valid) - ); - - prim_lc_sender #( - .AsyncOn(0) - ) u_prim_lc_sender_secrets_valid ( - .clk_i, - .rst_ni, - .lc_en_i(secrets_valid), - .lc_en_o(otp_lc_data_o.secrets_valid) - ); - - // Lifecycle state - assign otp_lc_data_o.state = lc_ctrl_state_pkg::lc_state_e'(part_buf_data[LcStateOffset +: - LcStateSize]); - assign otp_lc_data_o.count = lc_ctrl_state_pkg::lc_cnt_e'(part_buf_data[LcTransitionCntOffset +: - LcTransitionCntSize]); - - // Assert life cycle state valid signal only when all partitions have initialized. - assign otp_lc_data_o.valid = &part_init_done; - // Signal whether there are any errors in the life cycle partition (both correctable and - // uncorrectable ones). This bit is made available via the JTAG TAP, which is useful for - // production testing in RAW life cycle state where the OTP regs are not accessible. - assign otp_lc_data_o.error = |part_error[LifeCycleIdx]; - - // Not all bits of part_buf_data are used here. - logic unused_buf_data; - assign unused_buf_data = ^part_buf_data; - - //////////////// - // Assertions // - //////////////// - - `ASSERT_INIT(CreatorRootKeyShare0Size_A, KeyMgrKeyWidth == CreatorRootKeyShare0Size * 8) - `ASSERT_INIT(CreatorRootKeyShare1Size_A, KeyMgrKeyWidth == CreatorRootKeyShare1Size * 8) - `ASSERT_INIT(FlashDataKeySeedSize_A, FlashKeySeedWidth == FlashDataKeySeedSize * 8) - `ASSERT_INIT(FlashAddrKeySeedSize_A, FlashKeySeedWidth == FlashAddrKeySeedSize * 8) - `ASSERT_INIT(SramDataKeySeedSize_A, SramKeySeedWidth == SramDataKeySeedSize * 8) - - `ASSERT_INIT(RmaTokenSize_A, lc_ctrl_state_pkg::LcTokenWidth == RmaTokenSize * 8) - `ASSERT_INIT(TestUnlockTokenSize_A, lc_ctrl_state_pkg::LcTokenWidth == TestUnlockTokenSize * 8) - `ASSERT_INIT(TestExitTokenSize_A, lc_ctrl_state_pkg::LcTokenWidth == TestExitTokenSize * 8) - `ASSERT_INIT(LcStateSize_A, lc_ctrl_state_pkg::LcStateWidth == LcStateSize * 8) - `ASSERT_INIT(LcTransitionCntSize_A, lc_ctrl_state_pkg::LcCountWidth == LcTransitionCntSize * 8) - - `ASSERT_KNOWN(OtpAstPwrSeqKnown_A, otp_ast_pwr_seq_o) - `ASSERT_KNOWN(CoreTlOutKnown_A, core_tl_o) - `ASSERT_KNOWN(PrimTlOutKnown_A, prim_tl_o) - `ASSERT_KNOWN(IntrOtpOperationDoneKnown_A, intr_otp_operation_done_o) - `ASSERT_KNOWN(IntrOtpErrorKnown_A, intr_otp_error_o) - `ASSERT_KNOWN(AlertTxKnown_A, alert_tx_o) - `ASSERT_KNOWN(PwrOtpInitRspKnown_A, pwr_otp_o) - `ASSERT_KNOWN(LcOtpProgramRspKnown_A, lc_otp_program_o) - `ASSERT_KNOWN(OtpLcDataKnown_A, otp_lc_data_o) - `ASSERT_KNOWN(OtpKeymgrKeyKnown_A, otp_keymgr_key_o) - `ASSERT_KNOWN(FlashOtpKeyRspKnown_A, flash_otp_key_o) - `ASSERT_KNOWN(OtpSramKeyKnown_A, sram_otp_key_o) - `ASSERT_KNOWN(OtpOtgnKeyKnown_A, otbn_otp_key_o) - `ASSERT_KNOWN(OtpBroadcastKnown_A, otp_broadcast_o) - - // Alert assertions for sparse FSMs. - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlDaiFsmCheck_A, - u_otp_ctrl_dai.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlKdiFsmCheck_A, - u_otp_ctrl_kdi.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlLciFsmCheck_A, - u_otp_ctrl_lci.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlLfsrTimerFsmCheck_A, - u_otp_ctrl_lfsr_timer.u_state_regs, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(CtrlScrambleFsmCheck_A, - u_otp_ctrl_scrmbl.u_state_regs, alert_tx_o[1]) - - // Alert assertions for redundant counters. - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntIntegCheck_A, - u_otp_ctrl_lfsr_timer.u_prim_count_integ, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntCnstyCheck_A, - u_otp_ctrl_lfsr_timer.u_prim_count_cnsty, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntDaiCheck_A, - u_otp_ctrl_dai.u_prim_count, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntKdiSeedCheck_A, - u_otp_ctrl_kdi.u_prim_count_seed, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntKdiEntropyCheck_A, - u_otp_ctrl_kdi.u_prim_count_entropy, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntLciCheck_A, - u_otp_ctrl_lci.u_prim_count, alert_tx_o[1]) - `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(CntScrmblCheck_A, - u_otp_ctrl_scrmbl.u_prim_count, alert_tx_o[1]) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(TlLcGateFsm_A, - u_tlul_lc_gate.u_state_regs, alert_tx_o[2]) - - // Alert assertions for double LFSR. - `ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ALERT(DoubleLfsrCheck_A, - u_otp_ctrl_lfsr_timer.u_prim_double_lfsr, alert_tx_o[1]) - - // Alert assertions for reg_we onehot check - `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg_core, alert_tx_o[2]) - - // Assertions for countermeasures inside prim_otp - `ifndef PRIM_DEFAULT_IMPL - `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric - `endif - if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_reg_we_assert_generic - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(PrimFsmCheck_A, - u_otp.gen_generic.u_impl_generic.u_state_regs, alert_tx_o[3]) - `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(PrimRegWeOnehotCheck_A, - u_otp.gen_generic.u_impl_generic.u_reg_top, alert_tx_o[3]) - end -endmodule : otp_ctrl diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv deleted file mode 100644 index 0c4d37ea9d63d..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv +++ /dev/null @@ -1,2579 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - -`include "prim_assert.sv" - -module otp_ctrl_core_reg_top ( - input clk_i, - input rst_ni, - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, - - // Output port for window - output tlul_pkg::tl_h2d_t tl_win_o, - input tlul_pkg::tl_d2h_t tl_win_i, - - // To HW - output otp_ctrl_reg_pkg::otp_ctrl_core_reg2hw_t reg2hw, // Write - input otp_ctrl_reg_pkg::otp_ctrl_core_hw2reg_t hw2reg, // Read - - // Integrity check errors - output logic intg_err_o -); - - import otp_ctrl_reg_pkg::* ; - - localparam int AW = 12; - localparam int DW = 32; - localparam int DBW = DW/8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [AW-1:0] reg_addr; - logic [DW-1:0] reg_wdata; - logic [DBW-1:0] reg_be; - logic [DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - logic reg_busy; - - tlul_pkg::tl_h2d_t tl_reg_h2d; - tlul_pkg::tl_d2h_t tl_reg_d2h; - - - // incoming payload check - logic intg_err; - tlul_cmd_intg_chk u_chk ( - .tl_i(tl_i), - .err_o(intg_err) - ); - - // also check for spurious write enables - logic reg_we_err; - logic [55:0] reg_we_check; - prim_reg_we_check #( - .OneHotWidth(56) - ) u_prim_reg_we_check ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .oh_i (reg_we_check), - .en_i (reg_we && !addrmiss), - .err_o (reg_we_err) - ); - - logic err_q; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - err_q <= '0; - end else if (intg_err || reg_we_err) begin - err_q <= 1'b1; - end - end - - // integrity error output is permanent and should be used for alert generation - // register errors are transactional - assign intg_err_o = err_q | intg_err | reg_we_err; - - // outgoing integrity generation - tlul_pkg::tl_d2h_t tl_o_pre; - tlul_rsp_intg_gen #( - .EnableRspIntgGen(1), - .EnableDataIntgGen(1) - ) u_rsp_intg_gen ( - .tl_i(tl_o_pre), - .tl_o(tl_o) - ); - - tlul_pkg::tl_h2d_t tl_socket_h2d [2]; - tlul_pkg::tl_d2h_t tl_socket_d2h [2]; - - logic [0:0] reg_steer; - - // socket_1n connection - assign tl_reg_h2d = tl_socket_h2d[1]; - assign tl_socket_d2h[1] = tl_reg_d2h; - - assign tl_win_o = tl_socket_h2d[0]; - assign tl_socket_d2h[0] = tl_win_i; - - // Create Socket_1n - tlul_socket_1n #( - .N (2), - .HReqPass (1'b1), - .HRspPass (1'b1), - .DReqPass ({2{1'b1}}), - .DRspPass ({2{1'b1}}), - .HReqDepth (4'h0), - .HRspDepth (4'h0), - .DReqDepth ({2{4'h0}}), - .DRspDepth ({2{4'h0}}), - .ExplicitErrs (1'b0) - ) u_socket ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .tl_h_i (tl_i), - .tl_h_o (tl_o_pre), - .tl_d_o (tl_socket_h2d), - .tl_d_i (tl_socket_d2h), - .dev_select_i (reg_steer) - ); - - // Create steering logic - always_comb begin - reg_steer = - tl_i.a_address[AW-1:0] inside {[2048:4095]} ? 1'd0 : - // Default set to register - 1'd1; - - // Override this in case of an integrity error - if (intg_err) begin - reg_steer = 1'd1; - end - end - - tlul_adapter_reg #( - .RegAw(AW), - .RegDw(DW), - .EnableDataIntgGen(0) - ) u_reg_if ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - .tl_i (tl_reg_h2d), - .tl_o (tl_reg_d2h), - - .en_ifetch_i(prim_mubi_pkg::MuBi4False), - .intg_error_o(), - - .we_o (reg_we), - .re_o (reg_re), - .addr_o (reg_addr), - .wdata_o (reg_wdata), - .be_o (reg_be), - .busy_i (reg_busy), - .rdata_i (reg_rdata), - .error_i (reg_error) - ); - - // cdc oversampling signals - - assign reg_rdata = reg_rdata_next ; - assign reg_error = addrmiss | wr_err | intg_err; - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic intr_state_we; - logic intr_state_otp_operation_done_qs; - logic intr_state_otp_operation_done_wd; - logic intr_state_otp_error_qs; - logic intr_state_otp_error_wd; - logic intr_enable_we; - logic intr_enable_otp_operation_done_qs; - logic intr_enable_otp_operation_done_wd; - logic intr_enable_otp_error_qs; - logic intr_enable_otp_error_wd; - logic intr_test_we; - logic intr_test_otp_operation_done_wd; - logic intr_test_otp_error_wd; - logic alert_test_we; - logic alert_test_fatal_macro_error_wd; - logic alert_test_fatal_check_error_wd; - logic alert_test_fatal_bus_integ_error_wd; - logic alert_test_fatal_prim_otp_alert_wd; - logic alert_test_recov_prim_otp_alert_wd; - logic status_re; - logic status_vendor_test_error_qs; - logic status_creator_sw_cfg_error_qs; - logic status_owner_sw_cfg_error_qs; - logic status_rot_creator_auth_codesign_error_qs; - logic status_rot_creator_auth_state_error_qs; - logic status_hw_cfg0_error_qs; - logic status_hw_cfg1_error_qs; - logic status_secret0_error_qs; - logic status_secret1_error_qs; - logic status_secret2_error_qs; - logic status_life_cycle_error_qs; - logic status_dai_error_qs; - logic status_lci_error_qs; - logic status_timeout_error_qs; - logic status_lfsr_fsm_error_qs; - logic status_scrambling_fsm_error_qs; - logic status_key_deriv_fsm_error_qs; - logic status_bus_integ_error_qs; - logic status_dai_idle_qs; - logic status_check_pending_qs; - logic err_code_0_re; - logic [2:0] err_code_0_qs; - logic err_code_1_re; - logic [2:0] err_code_1_qs; - logic err_code_2_re; - logic [2:0] err_code_2_qs; - logic err_code_3_re; - logic [2:0] err_code_3_qs; - logic err_code_4_re; - logic [2:0] err_code_4_qs; - logic err_code_5_re; - logic [2:0] err_code_5_qs; - logic err_code_6_re; - logic [2:0] err_code_6_qs; - logic err_code_7_re; - logic [2:0] err_code_7_qs; - logic err_code_8_re; - logic [2:0] err_code_8_qs; - logic err_code_9_re; - logic [2:0] err_code_9_qs; - logic err_code_10_re; - logic [2:0] err_code_10_qs; - logic err_code_11_re; - logic [2:0] err_code_11_qs; - logic err_code_12_re; - logic [2:0] err_code_12_qs; - logic direct_access_regwen_re; - logic direct_access_regwen_we; - logic direct_access_regwen_qs; - logic direct_access_regwen_wd; - logic direct_access_cmd_we; - logic direct_access_cmd_rd_wd; - logic direct_access_cmd_wr_wd; - logic direct_access_cmd_digest_wd; - logic direct_access_address_we; - logic [10:0] direct_access_address_qs; - logic [10:0] direct_access_address_wd; - logic direct_access_wdata_0_we; - logic [31:0] direct_access_wdata_0_qs; - logic [31:0] direct_access_wdata_0_wd; - logic direct_access_wdata_1_we; - logic [31:0] direct_access_wdata_1_qs; - logic [31:0] direct_access_wdata_1_wd; - logic direct_access_rdata_0_re; - logic [31:0] direct_access_rdata_0_qs; - logic direct_access_rdata_1_re; - logic [31:0] direct_access_rdata_1_qs; - logic check_trigger_regwen_we; - logic check_trigger_regwen_qs; - logic check_trigger_regwen_wd; - logic check_trigger_we; - logic check_trigger_integrity_wd; - logic check_trigger_consistency_wd; - logic check_regwen_we; - logic check_regwen_qs; - logic check_regwen_wd; - logic check_timeout_we; - logic [31:0] check_timeout_qs; - logic [31:0] check_timeout_wd; - logic integrity_check_period_we; - logic [31:0] integrity_check_period_qs; - logic [31:0] integrity_check_period_wd; - logic consistency_check_period_we; - logic [31:0] consistency_check_period_qs; - logic [31:0] consistency_check_period_wd; - logic vendor_test_read_lock_we; - logic vendor_test_read_lock_qs; - logic vendor_test_read_lock_wd; - logic creator_sw_cfg_read_lock_we; - logic creator_sw_cfg_read_lock_qs; - logic creator_sw_cfg_read_lock_wd; - logic owner_sw_cfg_read_lock_we; - logic owner_sw_cfg_read_lock_qs; - logic owner_sw_cfg_read_lock_wd; - logic rot_creator_auth_codesign_read_lock_we; - logic rot_creator_auth_codesign_read_lock_qs; - logic rot_creator_auth_codesign_read_lock_wd; - logic rot_creator_auth_state_read_lock_we; - logic rot_creator_auth_state_read_lock_qs; - logic rot_creator_auth_state_read_lock_wd; - logic vendor_test_digest_0_re; - logic [31:0] vendor_test_digest_0_qs; - logic vendor_test_digest_1_re; - logic [31:0] vendor_test_digest_1_qs; - logic creator_sw_cfg_digest_0_re; - logic [31:0] creator_sw_cfg_digest_0_qs; - logic creator_sw_cfg_digest_1_re; - logic [31:0] creator_sw_cfg_digest_1_qs; - logic owner_sw_cfg_digest_0_re; - logic [31:0] owner_sw_cfg_digest_0_qs; - logic owner_sw_cfg_digest_1_re; - logic [31:0] owner_sw_cfg_digest_1_qs; - logic rot_creator_auth_codesign_digest_0_re; - logic [31:0] rot_creator_auth_codesign_digest_0_qs; - logic rot_creator_auth_codesign_digest_1_re; - logic [31:0] rot_creator_auth_codesign_digest_1_qs; - logic rot_creator_auth_state_digest_0_re; - logic [31:0] rot_creator_auth_state_digest_0_qs; - logic rot_creator_auth_state_digest_1_re; - logic [31:0] rot_creator_auth_state_digest_1_qs; - logic hw_cfg0_digest_0_re; - logic [31:0] hw_cfg0_digest_0_qs; - logic hw_cfg0_digest_1_re; - logic [31:0] hw_cfg0_digest_1_qs; - logic hw_cfg1_digest_0_re; - logic [31:0] hw_cfg1_digest_0_qs; - logic hw_cfg1_digest_1_re; - logic [31:0] hw_cfg1_digest_1_qs; - logic secret0_digest_0_re; - logic [31:0] secret0_digest_0_qs; - logic secret0_digest_1_re; - logic [31:0] secret0_digest_1_qs; - logic secret1_digest_0_re; - logic [31:0] secret1_digest_0_qs; - logic secret1_digest_1_re; - logic [31:0] secret1_digest_1_qs; - logic secret2_digest_0_re; - logic [31:0] secret2_digest_0_qs; - logic secret2_digest_1_re; - logic [31:0] secret2_digest_1_qs; - - // Register instances - // R[intr_state]: V(False) - // F[otp_operation_done]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_otp_operation_done ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_otp_operation_done_wd), - - // from internal hardware - .de (hw2reg.intr_state.otp_operation_done.de), - .d (hw2reg.intr_state.otp_operation_done.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.otp_operation_done.q), - .ds (), - - // to register interface (read) - .qs (intr_state_otp_operation_done_qs) - ); - - // F[otp_error]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state_otp_error ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_otp_error_wd), - - // from internal hardware - .de (hw2reg.intr_state.otp_error.de), - .d (hw2reg.intr_state.otp_error.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.otp_error.q), - .ds (), - - // to register interface (read) - .qs (intr_state_otp_error_qs) - ); - - - // R[intr_enable]: V(False) - // F[otp_operation_done]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_otp_operation_done ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_otp_operation_done_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.otp_operation_done.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_otp_operation_done_qs) - ); - - // F[otp_error]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable_otp_error ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_otp_error_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.otp_error.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_otp_error_qs) - ); - - - // R[intr_test]: V(True) - logic intr_test_qe; - logic [1:0] intr_test_flds_we; - assign intr_test_qe = &intr_test_flds_we; - // F[otp_operation_done]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_otp_operation_done ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_otp_operation_done_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[0]), - .q (reg2hw.intr_test.otp_operation_done.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.otp_operation_done.qe = intr_test_qe; - - // F[otp_error]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_intr_test_otp_error ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_otp_error_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[1]), - .q (reg2hw.intr_test.otp_error.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.otp_error.qe = intr_test_qe; - - - // R[alert_test]: V(True) - logic alert_test_qe; - logic [4:0] alert_test_flds_we; - assign alert_test_qe = &alert_test_flds_we; - // F[fatal_macro_error]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_alert_test_fatal_macro_error ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_fatal_macro_error_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[0]), - .q (reg2hw.alert_test.fatal_macro_error.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.fatal_macro_error.qe = alert_test_qe; - - // F[fatal_check_error]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_alert_test_fatal_check_error ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_fatal_check_error_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[1]), - .q (reg2hw.alert_test.fatal_check_error.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.fatal_check_error.qe = alert_test_qe; - - // F[fatal_bus_integ_error]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_alert_test_fatal_bus_integ_error ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_fatal_bus_integ_error_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[2]), - .q (reg2hw.alert_test.fatal_bus_integ_error.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.fatal_bus_integ_error.qe = alert_test_qe; - - // F[fatal_prim_otp_alert]: 3:3 - prim_subreg_ext #( - .DW (1) - ) u_alert_test_fatal_prim_otp_alert ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_fatal_prim_otp_alert_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[3]), - .q (reg2hw.alert_test.fatal_prim_otp_alert.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.fatal_prim_otp_alert.qe = alert_test_qe; - - // F[recov_prim_otp_alert]: 4:4 - prim_subreg_ext #( - .DW (1) - ) u_alert_test_recov_prim_otp_alert ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_recov_prim_otp_alert_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[4]), - .q (reg2hw.alert_test.recov_prim_otp_alert.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.recov_prim_otp_alert.qe = alert_test_qe; - - - // R[status]: V(True) - // F[vendor_test_error]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_status_vendor_test_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.vendor_test_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_vendor_test_error_qs) - ); - - // F[creator_sw_cfg_error]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_status_creator_sw_cfg_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.creator_sw_cfg_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_creator_sw_cfg_error_qs) - ); - - // F[owner_sw_cfg_error]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_status_owner_sw_cfg_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.owner_sw_cfg_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_owner_sw_cfg_error_qs) - ); - - // F[rot_creator_auth_codesign_error]: 3:3 - prim_subreg_ext #( - .DW (1) - ) u_status_rot_creator_auth_codesign_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.rot_creator_auth_codesign_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_rot_creator_auth_codesign_error_qs) - ); - - // F[rot_creator_auth_state_error]: 4:4 - prim_subreg_ext #( - .DW (1) - ) u_status_rot_creator_auth_state_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.rot_creator_auth_state_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_rot_creator_auth_state_error_qs) - ); - - // F[hw_cfg0_error]: 5:5 - prim_subreg_ext #( - .DW (1) - ) u_status_hw_cfg0_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.hw_cfg0_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_hw_cfg0_error_qs) - ); - - // F[hw_cfg1_error]: 6:6 - prim_subreg_ext #( - .DW (1) - ) u_status_hw_cfg1_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.hw_cfg1_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_hw_cfg1_error_qs) - ); - - // F[secret0_error]: 7:7 - prim_subreg_ext #( - .DW (1) - ) u_status_secret0_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.secret0_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_secret0_error_qs) - ); - - // F[secret1_error]: 8:8 - prim_subreg_ext #( - .DW (1) - ) u_status_secret1_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.secret1_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_secret1_error_qs) - ); - - // F[secret2_error]: 9:9 - prim_subreg_ext #( - .DW (1) - ) u_status_secret2_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.secret2_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_secret2_error_qs) - ); - - // F[life_cycle_error]: 10:10 - prim_subreg_ext #( - .DW (1) - ) u_status_life_cycle_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.life_cycle_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_life_cycle_error_qs) - ); - - // F[dai_error]: 11:11 - prim_subreg_ext #( - .DW (1) - ) u_status_dai_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.dai_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_dai_error_qs) - ); - - // F[lci_error]: 12:12 - prim_subreg_ext #( - .DW (1) - ) u_status_lci_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.lci_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_lci_error_qs) - ); - - // F[timeout_error]: 13:13 - prim_subreg_ext #( - .DW (1) - ) u_status_timeout_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.timeout_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_timeout_error_qs) - ); - - // F[lfsr_fsm_error]: 14:14 - prim_subreg_ext #( - .DW (1) - ) u_status_lfsr_fsm_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.lfsr_fsm_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_lfsr_fsm_error_qs) - ); - - // F[scrambling_fsm_error]: 15:15 - prim_subreg_ext #( - .DW (1) - ) u_status_scrambling_fsm_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.scrambling_fsm_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_scrambling_fsm_error_qs) - ); - - // F[key_deriv_fsm_error]: 16:16 - prim_subreg_ext #( - .DW (1) - ) u_status_key_deriv_fsm_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.key_deriv_fsm_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_key_deriv_fsm_error_qs) - ); - - // F[bus_integ_error]: 17:17 - prim_subreg_ext #( - .DW (1) - ) u_status_bus_integ_error ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.bus_integ_error.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_bus_integ_error_qs) - ); - - // F[dai_idle]: 18:18 - prim_subreg_ext #( - .DW (1) - ) u_status_dai_idle ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.dai_idle.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_dai_idle_qs) - ); - - // F[check_pending]: 19:19 - prim_subreg_ext #( - .DW (1) - ) u_status_check_pending ( - .re (status_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.status.check_pending.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (status_check_pending_qs) - ); - - - // Subregister 0 of Multireg err_code - // R[err_code_0]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_0 ( - .re (err_code_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_0_qs) - ); - - - // Subregister 1 of Multireg err_code - // R[err_code_1]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_1 ( - .re (err_code_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_1_qs) - ); - - - // Subregister 2 of Multireg err_code - // R[err_code_2]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_2 ( - .re (err_code_2_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[2].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_2_qs) - ); - - - // Subregister 3 of Multireg err_code - // R[err_code_3]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_3 ( - .re (err_code_3_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[3].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_3_qs) - ); - - - // Subregister 4 of Multireg err_code - // R[err_code_4]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_4 ( - .re (err_code_4_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[4].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_4_qs) - ); - - - // Subregister 5 of Multireg err_code - // R[err_code_5]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_5 ( - .re (err_code_5_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[5].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_5_qs) - ); - - - // Subregister 6 of Multireg err_code - // R[err_code_6]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_6 ( - .re (err_code_6_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[6].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_6_qs) - ); - - - // Subregister 7 of Multireg err_code - // R[err_code_7]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_7 ( - .re (err_code_7_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[7].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_7_qs) - ); - - - // Subregister 8 of Multireg err_code - // R[err_code_8]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_8 ( - .re (err_code_8_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[8].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_8_qs) - ); - - - // Subregister 9 of Multireg err_code - // R[err_code_9]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_9 ( - .re (err_code_9_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[9].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_9_qs) - ); - - - // Subregister 10 of Multireg err_code - // R[err_code_10]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_10 ( - .re (err_code_10_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[10].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_10_qs) - ); - - - // Subregister 11 of Multireg err_code - // R[err_code_11]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_11 ( - .re (err_code_11_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[11].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_11_qs) - ); - - - // Subregister 12 of Multireg err_code - // R[err_code_12]: V(True) - prim_subreg_ext #( - .DW (3) - ) u_err_code_12 ( - .re (err_code_12_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.err_code[12].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (err_code_12_qs) - ); - - - // R[direct_access_regwen]: V(True) - logic direct_access_regwen_qe; - logic [0:0] direct_access_regwen_flds_we; - assign direct_access_regwen_qe = &direct_access_regwen_flds_we; - prim_subreg_ext #( - .DW (1) - ) u_direct_access_regwen ( - .re (direct_access_regwen_re), - .we (direct_access_regwen_we), - .wd (direct_access_regwen_wd), - .d (hw2reg.direct_access_regwen.d), - .qre (), - .qe (direct_access_regwen_flds_we[0]), - .q (reg2hw.direct_access_regwen.q), - .ds (), - .qs (direct_access_regwen_qs) - ); - assign reg2hw.direct_access_regwen.qe = direct_access_regwen_qe; - - - // R[direct_access_cmd]: V(True) - logic direct_access_cmd_qe; - logic [2:0] direct_access_cmd_flds_we; - assign direct_access_cmd_qe = &direct_access_cmd_flds_we; - // Create REGWEN-gated WE signal - logic direct_access_cmd_gated_we; - assign direct_access_cmd_gated_we = direct_access_cmd_we & direct_access_regwen_qs; - // F[rd]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_direct_access_cmd_rd ( - .re (1'b0), - .we (direct_access_cmd_gated_we), - .wd (direct_access_cmd_rd_wd), - .d ('0), - .qre (), - .qe (direct_access_cmd_flds_we[0]), - .q (reg2hw.direct_access_cmd.rd.q), - .ds (), - .qs () - ); - assign reg2hw.direct_access_cmd.rd.qe = direct_access_cmd_qe; - - // F[wr]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_direct_access_cmd_wr ( - .re (1'b0), - .we (direct_access_cmd_gated_we), - .wd (direct_access_cmd_wr_wd), - .d ('0), - .qre (), - .qe (direct_access_cmd_flds_we[1]), - .q (reg2hw.direct_access_cmd.wr.q), - .ds (), - .qs () - ); - assign reg2hw.direct_access_cmd.wr.qe = direct_access_cmd_qe; - - // F[digest]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_direct_access_cmd_digest ( - .re (1'b0), - .we (direct_access_cmd_gated_we), - .wd (direct_access_cmd_digest_wd), - .d ('0), - .qre (), - .qe (direct_access_cmd_flds_we[2]), - .q (reg2hw.direct_access_cmd.digest.q), - .ds (), - .qs () - ); - assign reg2hw.direct_access_cmd.digest.qe = direct_access_cmd_qe; - - - // R[direct_access_address]: V(False) - // Create REGWEN-gated WE signal - logic direct_access_address_gated_we; - assign direct_access_address_gated_we = direct_access_address_we & direct_access_regwen_qs; - prim_subreg #( - .DW (11), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (11'h0), - .Mubi (1'b0) - ) u_direct_access_address ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (direct_access_address_gated_we), - .wd (direct_access_address_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.direct_access_address.q), - .ds (), - - // to register interface (read) - .qs (direct_access_address_qs) - ); - - - // Subregister 0 of Multireg direct_access_wdata - // R[direct_access_wdata_0]: V(False) - // Create REGWEN-gated WE signal - logic direct_access_wdata_0_gated_we; - assign direct_access_wdata_0_gated_we = direct_access_wdata_0_we & direct_access_regwen_qs; - prim_subreg #( - .DW (32), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (32'h0), - .Mubi (1'b0) - ) u_direct_access_wdata_0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (direct_access_wdata_0_gated_we), - .wd (direct_access_wdata_0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.direct_access_wdata[0].q), - .ds (), - - // to register interface (read) - .qs (direct_access_wdata_0_qs) - ); - - - // Subregister 1 of Multireg direct_access_wdata - // R[direct_access_wdata_1]: V(False) - // Create REGWEN-gated WE signal - logic direct_access_wdata_1_gated_we; - assign direct_access_wdata_1_gated_we = direct_access_wdata_1_we & direct_access_regwen_qs; - prim_subreg #( - .DW (32), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (32'h0), - .Mubi (1'b0) - ) u_direct_access_wdata_1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (direct_access_wdata_1_gated_we), - .wd (direct_access_wdata_1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.direct_access_wdata[1].q), - .ds (), - - // to register interface (read) - .qs (direct_access_wdata_1_qs) - ); - - - // Subregister 0 of Multireg direct_access_rdata - // R[direct_access_rdata_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_direct_access_rdata_0 ( - .re (direct_access_rdata_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.direct_access_rdata[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (direct_access_rdata_0_qs) - ); - - - // Subregister 1 of Multireg direct_access_rdata - // R[direct_access_rdata_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_direct_access_rdata_1 ( - .re (direct_access_rdata_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.direct_access_rdata[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (direct_access_rdata_1_qs) - ); - - - // R[check_trigger_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_check_trigger_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (check_trigger_regwen_we), - .wd (check_trigger_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (check_trigger_regwen_qs) - ); - - - // R[check_trigger]: V(True) - logic check_trigger_qe; - logic [1:0] check_trigger_flds_we; - assign check_trigger_qe = &check_trigger_flds_we; - // Create REGWEN-gated WE signal - logic check_trigger_gated_we; - assign check_trigger_gated_we = check_trigger_we & check_trigger_regwen_qs; - // F[integrity]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_check_trigger_integrity ( - .re (1'b0), - .we (check_trigger_gated_we), - .wd (check_trigger_integrity_wd), - .d ('0), - .qre (), - .qe (check_trigger_flds_we[0]), - .q (reg2hw.check_trigger.integrity.q), - .ds (), - .qs () - ); - assign reg2hw.check_trigger.integrity.qe = check_trigger_qe; - - // F[consistency]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_check_trigger_consistency ( - .re (1'b0), - .we (check_trigger_gated_we), - .wd (check_trigger_consistency_wd), - .d ('0), - .qre (), - .qe (check_trigger_flds_we[1]), - .q (reg2hw.check_trigger.consistency.q), - .ds (), - .qs () - ); - assign reg2hw.check_trigger.consistency.qe = check_trigger_qe; - - - // R[check_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_check_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (check_regwen_we), - .wd (check_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (check_regwen_qs) - ); - - - // R[check_timeout]: V(False) - // Create REGWEN-gated WE signal - logic check_timeout_gated_we; - assign check_timeout_gated_we = check_timeout_we & check_regwen_qs; - prim_subreg #( - .DW (32), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (32'h0), - .Mubi (1'b0) - ) u_check_timeout ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (check_timeout_gated_we), - .wd (check_timeout_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.check_timeout.q), - .ds (), - - // to register interface (read) - .qs (check_timeout_qs) - ); - - - // R[integrity_check_period]: V(False) - // Create REGWEN-gated WE signal - logic integrity_check_period_gated_we; - assign integrity_check_period_gated_we = integrity_check_period_we & check_regwen_qs; - prim_subreg #( - .DW (32), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (32'h0), - .Mubi (1'b0) - ) u_integrity_check_period ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (integrity_check_period_gated_we), - .wd (integrity_check_period_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.integrity_check_period.q), - .ds (), - - // to register interface (read) - .qs (integrity_check_period_qs) - ); - - - // R[consistency_check_period]: V(False) - // Create REGWEN-gated WE signal - logic consistency_check_period_gated_we; - assign consistency_check_period_gated_we = consistency_check_period_we & check_regwen_qs; - prim_subreg #( - .DW (32), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (32'h0), - .Mubi (1'b0) - ) u_consistency_check_period ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (consistency_check_period_gated_we), - .wd (consistency_check_period_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.consistency_check_period.q), - .ds (), - - // to register interface (read) - .qs (consistency_check_period_qs) - ); - - - // R[vendor_test_read_lock]: V(False) - // Create REGWEN-gated WE signal - logic vendor_test_read_lock_gated_we; - assign vendor_test_read_lock_gated_we = vendor_test_read_lock_we & direct_access_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_vendor_test_read_lock ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (vendor_test_read_lock_gated_we), - .wd (vendor_test_read_lock_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.vendor_test_read_lock.q), - .ds (), - - // to register interface (read) - .qs (vendor_test_read_lock_qs) - ); - - - // R[creator_sw_cfg_read_lock]: V(False) - // Create REGWEN-gated WE signal - logic creator_sw_cfg_read_lock_gated_we; - assign creator_sw_cfg_read_lock_gated_we = creator_sw_cfg_read_lock_we & direct_access_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_creator_sw_cfg_read_lock ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (creator_sw_cfg_read_lock_gated_we), - .wd (creator_sw_cfg_read_lock_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.creator_sw_cfg_read_lock.q), - .ds (), - - // to register interface (read) - .qs (creator_sw_cfg_read_lock_qs) - ); - - - // R[owner_sw_cfg_read_lock]: V(False) - // Create REGWEN-gated WE signal - logic owner_sw_cfg_read_lock_gated_we; - assign owner_sw_cfg_read_lock_gated_we = owner_sw_cfg_read_lock_we & direct_access_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_owner_sw_cfg_read_lock ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (owner_sw_cfg_read_lock_gated_we), - .wd (owner_sw_cfg_read_lock_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.owner_sw_cfg_read_lock.q), - .ds (), - - // to register interface (read) - .qs (owner_sw_cfg_read_lock_qs) - ); - - - // R[rot_creator_auth_codesign_read_lock]: V(False) - // Create REGWEN-gated WE signal - logic rot_creator_auth_codesign_read_lock_gated_we; - assign rot_creator_auth_codesign_read_lock_gated_we = - rot_creator_auth_codesign_read_lock_we & direct_access_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_rot_creator_auth_codesign_read_lock ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (rot_creator_auth_codesign_read_lock_gated_we), - .wd (rot_creator_auth_codesign_read_lock_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.rot_creator_auth_codesign_read_lock.q), - .ds (), - - // to register interface (read) - .qs (rot_creator_auth_codesign_read_lock_qs) - ); - - - // R[rot_creator_auth_state_read_lock]: V(False) - // Create REGWEN-gated WE signal - logic rot_creator_auth_state_read_lock_gated_we; - assign rot_creator_auth_state_read_lock_gated_we = - rot_creator_auth_state_read_lock_we & direct_access_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_rot_creator_auth_state_read_lock ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (rot_creator_auth_state_read_lock_gated_we), - .wd (rot_creator_auth_state_read_lock_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.rot_creator_auth_state_read_lock.q), - .ds (), - - // to register interface (read) - .qs (rot_creator_auth_state_read_lock_qs) - ); - - - // Subregister 0 of Multireg vendor_test_digest - // R[vendor_test_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_vendor_test_digest_0 ( - .re (vendor_test_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.vendor_test_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (vendor_test_digest_0_qs) - ); - - - // Subregister 1 of Multireg vendor_test_digest - // R[vendor_test_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_vendor_test_digest_1 ( - .re (vendor_test_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.vendor_test_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (vendor_test_digest_1_qs) - ); - - - // Subregister 0 of Multireg creator_sw_cfg_digest - // R[creator_sw_cfg_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_creator_sw_cfg_digest_0 ( - .re (creator_sw_cfg_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.creator_sw_cfg_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (creator_sw_cfg_digest_0_qs) - ); - - - // Subregister 1 of Multireg creator_sw_cfg_digest - // R[creator_sw_cfg_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_creator_sw_cfg_digest_1 ( - .re (creator_sw_cfg_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.creator_sw_cfg_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (creator_sw_cfg_digest_1_qs) - ); - - - // Subregister 0 of Multireg owner_sw_cfg_digest - // R[owner_sw_cfg_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_owner_sw_cfg_digest_0 ( - .re (owner_sw_cfg_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.owner_sw_cfg_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (owner_sw_cfg_digest_0_qs) - ); - - - // Subregister 1 of Multireg owner_sw_cfg_digest - // R[owner_sw_cfg_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_owner_sw_cfg_digest_1 ( - .re (owner_sw_cfg_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.owner_sw_cfg_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (owner_sw_cfg_digest_1_qs) - ); - - - // Subregister 0 of Multireg rot_creator_auth_codesign_digest - // R[rot_creator_auth_codesign_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_rot_creator_auth_codesign_digest_0 ( - .re (rot_creator_auth_codesign_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.rot_creator_auth_codesign_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (rot_creator_auth_codesign_digest_0_qs) - ); - - - // Subregister 1 of Multireg rot_creator_auth_codesign_digest - // R[rot_creator_auth_codesign_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_rot_creator_auth_codesign_digest_1 ( - .re (rot_creator_auth_codesign_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.rot_creator_auth_codesign_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (rot_creator_auth_codesign_digest_1_qs) - ); - - - // Subregister 0 of Multireg rot_creator_auth_state_digest - // R[rot_creator_auth_state_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_rot_creator_auth_state_digest_0 ( - .re (rot_creator_auth_state_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.rot_creator_auth_state_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (rot_creator_auth_state_digest_0_qs) - ); - - - // Subregister 1 of Multireg rot_creator_auth_state_digest - // R[rot_creator_auth_state_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_rot_creator_auth_state_digest_1 ( - .re (rot_creator_auth_state_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.rot_creator_auth_state_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (rot_creator_auth_state_digest_1_qs) - ); - - - // Subregister 0 of Multireg hw_cfg0_digest - // R[hw_cfg0_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_hw_cfg0_digest_0 ( - .re (hw_cfg0_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.hw_cfg0_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (hw_cfg0_digest_0_qs) - ); - - - // Subregister 1 of Multireg hw_cfg0_digest - // R[hw_cfg0_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_hw_cfg0_digest_1 ( - .re (hw_cfg0_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.hw_cfg0_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (hw_cfg0_digest_1_qs) - ); - - - // Subregister 0 of Multireg hw_cfg1_digest - // R[hw_cfg1_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_hw_cfg1_digest_0 ( - .re (hw_cfg1_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.hw_cfg1_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (hw_cfg1_digest_0_qs) - ); - - - // Subregister 1 of Multireg hw_cfg1_digest - // R[hw_cfg1_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_hw_cfg1_digest_1 ( - .re (hw_cfg1_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.hw_cfg1_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (hw_cfg1_digest_1_qs) - ); - - - // Subregister 0 of Multireg secret0_digest - // R[secret0_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret0_digest_0 ( - .re (secret0_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret0_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret0_digest_0_qs) - ); - - - // Subregister 1 of Multireg secret0_digest - // R[secret0_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret0_digest_1 ( - .re (secret0_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret0_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret0_digest_1_qs) - ); - - - // Subregister 0 of Multireg secret1_digest - // R[secret1_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret1_digest_0 ( - .re (secret1_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret1_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret1_digest_0_qs) - ); - - - // Subregister 1 of Multireg secret1_digest - // R[secret1_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret1_digest_1 ( - .re (secret1_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret1_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret1_digest_1_qs) - ); - - - // Subregister 0 of Multireg secret2_digest - // R[secret2_digest_0]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret2_digest_0 ( - .re (secret2_digest_0_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret2_digest[0].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret2_digest_0_qs) - ); - - - // Subregister 1 of Multireg secret2_digest - // R[secret2_digest_1]: V(True) - prim_subreg_ext #( - .DW (32) - ) u_secret2_digest_1 ( - .re (secret2_digest_1_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.secret2_digest[1].d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (secret2_digest_1_qs) - ); - - - - logic [55:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[ 0] = (reg_addr == OTP_CTRL_INTR_STATE_OFFSET); - addr_hit[ 1] = (reg_addr == OTP_CTRL_INTR_ENABLE_OFFSET); - addr_hit[ 2] = (reg_addr == OTP_CTRL_INTR_TEST_OFFSET); - addr_hit[ 3] = (reg_addr == OTP_CTRL_ALERT_TEST_OFFSET); - addr_hit[ 4] = (reg_addr == OTP_CTRL_STATUS_OFFSET); - addr_hit[ 5] = (reg_addr == OTP_CTRL_ERR_CODE_0_OFFSET); - addr_hit[ 6] = (reg_addr == OTP_CTRL_ERR_CODE_1_OFFSET); - addr_hit[ 7] = (reg_addr == OTP_CTRL_ERR_CODE_2_OFFSET); - addr_hit[ 8] = (reg_addr == OTP_CTRL_ERR_CODE_3_OFFSET); - addr_hit[ 9] = (reg_addr == OTP_CTRL_ERR_CODE_4_OFFSET); - addr_hit[10] = (reg_addr == OTP_CTRL_ERR_CODE_5_OFFSET); - addr_hit[11] = (reg_addr == OTP_CTRL_ERR_CODE_6_OFFSET); - addr_hit[12] = (reg_addr == OTP_CTRL_ERR_CODE_7_OFFSET); - addr_hit[13] = (reg_addr == OTP_CTRL_ERR_CODE_8_OFFSET); - addr_hit[14] = (reg_addr == OTP_CTRL_ERR_CODE_9_OFFSET); - addr_hit[15] = (reg_addr == OTP_CTRL_ERR_CODE_10_OFFSET); - addr_hit[16] = (reg_addr == OTP_CTRL_ERR_CODE_11_OFFSET); - addr_hit[17] = (reg_addr == OTP_CTRL_ERR_CODE_12_OFFSET); - addr_hit[18] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_REGWEN_OFFSET); - addr_hit[19] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_CMD_OFFSET); - addr_hit[20] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_ADDRESS_OFFSET); - addr_hit[21] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_WDATA_0_OFFSET); - addr_hit[22] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_WDATA_1_OFFSET); - addr_hit[23] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_RDATA_0_OFFSET); - addr_hit[24] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_RDATA_1_OFFSET); - addr_hit[25] = (reg_addr == OTP_CTRL_CHECK_TRIGGER_REGWEN_OFFSET); - addr_hit[26] = (reg_addr == OTP_CTRL_CHECK_TRIGGER_OFFSET); - addr_hit[27] = (reg_addr == OTP_CTRL_CHECK_REGWEN_OFFSET); - addr_hit[28] = (reg_addr == OTP_CTRL_CHECK_TIMEOUT_OFFSET); - addr_hit[29] = (reg_addr == OTP_CTRL_INTEGRITY_CHECK_PERIOD_OFFSET); - addr_hit[30] = (reg_addr == OTP_CTRL_CONSISTENCY_CHECK_PERIOD_OFFSET); - addr_hit[31] = (reg_addr == OTP_CTRL_VENDOR_TEST_READ_LOCK_OFFSET); - addr_hit[32] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_OFFSET); - addr_hit[33] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OFFSET); - addr_hit[34] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_OFFSET); - addr_hit[35] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_OFFSET); - addr_hit[36] = (reg_addr == OTP_CTRL_VENDOR_TEST_DIGEST_0_OFFSET); - addr_hit[37] = (reg_addr == OTP_CTRL_VENDOR_TEST_DIGEST_1_OFFSET); - addr_hit[38] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_OFFSET); - addr_hit[39] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_OFFSET); - addr_hit[40] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_DIGEST_0_OFFSET); - addr_hit[41] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_DIGEST_1_OFFSET); - addr_hit[42] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_OFFSET); - addr_hit[43] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_OFFSET); - addr_hit[44] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_OFFSET); - addr_hit[45] = (reg_addr == OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_OFFSET); - addr_hit[46] = (reg_addr == OTP_CTRL_HW_CFG0_DIGEST_0_OFFSET); - addr_hit[47] = (reg_addr == OTP_CTRL_HW_CFG0_DIGEST_1_OFFSET); - addr_hit[48] = (reg_addr == OTP_CTRL_HW_CFG1_DIGEST_0_OFFSET); - addr_hit[49] = (reg_addr == OTP_CTRL_HW_CFG1_DIGEST_1_OFFSET); - addr_hit[50] = (reg_addr == OTP_CTRL_SECRET0_DIGEST_0_OFFSET); - addr_hit[51] = (reg_addr == OTP_CTRL_SECRET0_DIGEST_1_OFFSET); - addr_hit[52] = (reg_addr == OTP_CTRL_SECRET1_DIGEST_0_OFFSET); - addr_hit[53] = (reg_addr == OTP_CTRL_SECRET1_DIGEST_1_OFFSET); - addr_hit[54] = (reg_addr == OTP_CTRL_SECRET2_DIGEST_0_OFFSET); - addr_hit[55] = (reg_addr == OTP_CTRL_SECRET2_DIGEST_1_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|(OTP_CTRL_CORE_PERMIT[ 0] & ~reg_be))) | - (addr_hit[ 1] & (|(OTP_CTRL_CORE_PERMIT[ 1] & ~reg_be))) | - (addr_hit[ 2] & (|(OTP_CTRL_CORE_PERMIT[ 2] & ~reg_be))) | - (addr_hit[ 3] & (|(OTP_CTRL_CORE_PERMIT[ 3] & ~reg_be))) | - (addr_hit[ 4] & (|(OTP_CTRL_CORE_PERMIT[ 4] & ~reg_be))) | - (addr_hit[ 5] & (|(OTP_CTRL_CORE_PERMIT[ 5] & ~reg_be))) | - (addr_hit[ 6] & (|(OTP_CTRL_CORE_PERMIT[ 6] & ~reg_be))) | - (addr_hit[ 7] & (|(OTP_CTRL_CORE_PERMIT[ 7] & ~reg_be))) | - (addr_hit[ 8] & (|(OTP_CTRL_CORE_PERMIT[ 8] & ~reg_be))) | - (addr_hit[ 9] & (|(OTP_CTRL_CORE_PERMIT[ 9] & ~reg_be))) | - (addr_hit[10] & (|(OTP_CTRL_CORE_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(OTP_CTRL_CORE_PERMIT[11] & ~reg_be))) | - (addr_hit[12] & (|(OTP_CTRL_CORE_PERMIT[12] & ~reg_be))) | - (addr_hit[13] & (|(OTP_CTRL_CORE_PERMIT[13] & ~reg_be))) | - (addr_hit[14] & (|(OTP_CTRL_CORE_PERMIT[14] & ~reg_be))) | - (addr_hit[15] & (|(OTP_CTRL_CORE_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(OTP_CTRL_CORE_PERMIT[16] & ~reg_be))) | - (addr_hit[17] & (|(OTP_CTRL_CORE_PERMIT[17] & ~reg_be))) | - (addr_hit[18] & (|(OTP_CTRL_CORE_PERMIT[18] & ~reg_be))) | - (addr_hit[19] & (|(OTP_CTRL_CORE_PERMIT[19] & ~reg_be))) | - (addr_hit[20] & (|(OTP_CTRL_CORE_PERMIT[20] & ~reg_be))) | - (addr_hit[21] & (|(OTP_CTRL_CORE_PERMIT[21] & ~reg_be))) | - (addr_hit[22] & (|(OTP_CTRL_CORE_PERMIT[22] & ~reg_be))) | - (addr_hit[23] & (|(OTP_CTRL_CORE_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(OTP_CTRL_CORE_PERMIT[24] & ~reg_be))) | - (addr_hit[25] & (|(OTP_CTRL_CORE_PERMIT[25] & ~reg_be))) | - (addr_hit[26] & (|(OTP_CTRL_CORE_PERMIT[26] & ~reg_be))) | - (addr_hit[27] & (|(OTP_CTRL_CORE_PERMIT[27] & ~reg_be))) | - (addr_hit[28] & (|(OTP_CTRL_CORE_PERMIT[28] & ~reg_be))) | - (addr_hit[29] & (|(OTP_CTRL_CORE_PERMIT[29] & ~reg_be))) | - (addr_hit[30] & (|(OTP_CTRL_CORE_PERMIT[30] & ~reg_be))) | - (addr_hit[31] & (|(OTP_CTRL_CORE_PERMIT[31] & ~reg_be))) | - (addr_hit[32] & (|(OTP_CTRL_CORE_PERMIT[32] & ~reg_be))) | - (addr_hit[33] & (|(OTP_CTRL_CORE_PERMIT[33] & ~reg_be))) | - (addr_hit[34] & (|(OTP_CTRL_CORE_PERMIT[34] & ~reg_be))) | - (addr_hit[35] & (|(OTP_CTRL_CORE_PERMIT[35] & ~reg_be))) | - (addr_hit[36] & (|(OTP_CTRL_CORE_PERMIT[36] & ~reg_be))) | - (addr_hit[37] & (|(OTP_CTRL_CORE_PERMIT[37] & ~reg_be))) | - (addr_hit[38] & (|(OTP_CTRL_CORE_PERMIT[38] & ~reg_be))) | - (addr_hit[39] & (|(OTP_CTRL_CORE_PERMIT[39] & ~reg_be))) | - (addr_hit[40] & (|(OTP_CTRL_CORE_PERMIT[40] & ~reg_be))) | - (addr_hit[41] & (|(OTP_CTRL_CORE_PERMIT[41] & ~reg_be))) | - (addr_hit[42] & (|(OTP_CTRL_CORE_PERMIT[42] & ~reg_be))) | - (addr_hit[43] & (|(OTP_CTRL_CORE_PERMIT[43] & ~reg_be))) | - (addr_hit[44] & (|(OTP_CTRL_CORE_PERMIT[44] & ~reg_be))) | - (addr_hit[45] & (|(OTP_CTRL_CORE_PERMIT[45] & ~reg_be))) | - (addr_hit[46] & (|(OTP_CTRL_CORE_PERMIT[46] & ~reg_be))) | - (addr_hit[47] & (|(OTP_CTRL_CORE_PERMIT[47] & ~reg_be))) | - (addr_hit[48] & (|(OTP_CTRL_CORE_PERMIT[48] & ~reg_be))) | - (addr_hit[49] & (|(OTP_CTRL_CORE_PERMIT[49] & ~reg_be))) | - (addr_hit[50] & (|(OTP_CTRL_CORE_PERMIT[50] & ~reg_be))) | - (addr_hit[51] & (|(OTP_CTRL_CORE_PERMIT[51] & ~reg_be))) | - (addr_hit[52] & (|(OTP_CTRL_CORE_PERMIT[52] & ~reg_be))) | - (addr_hit[53] & (|(OTP_CTRL_CORE_PERMIT[53] & ~reg_be))) | - (addr_hit[54] & (|(OTP_CTRL_CORE_PERMIT[54] & ~reg_be))) | - (addr_hit[55] & (|(OTP_CTRL_CORE_PERMIT[55] & ~reg_be))))); - end - - // Generate write-enables - assign intr_state_we = addr_hit[0] & reg_we & !reg_error; - - assign intr_state_otp_operation_done_wd = reg_wdata[0]; - - assign intr_state_otp_error_wd = reg_wdata[1]; - assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; - - assign intr_enable_otp_operation_done_wd = reg_wdata[0]; - - assign intr_enable_otp_error_wd = reg_wdata[1]; - assign intr_test_we = addr_hit[2] & reg_we & !reg_error; - - assign intr_test_otp_operation_done_wd = reg_wdata[0]; - - assign intr_test_otp_error_wd = reg_wdata[1]; - assign alert_test_we = addr_hit[3] & reg_we & !reg_error; - - assign alert_test_fatal_macro_error_wd = reg_wdata[0]; - - assign alert_test_fatal_check_error_wd = reg_wdata[1]; - - assign alert_test_fatal_bus_integ_error_wd = reg_wdata[2]; - - assign alert_test_fatal_prim_otp_alert_wd = reg_wdata[3]; - - assign alert_test_recov_prim_otp_alert_wd = reg_wdata[4]; - assign status_re = addr_hit[4] & reg_re & !reg_error; - assign err_code_0_re = addr_hit[5] & reg_re & !reg_error; - assign err_code_1_re = addr_hit[6] & reg_re & !reg_error; - assign err_code_2_re = addr_hit[7] & reg_re & !reg_error; - assign err_code_3_re = addr_hit[8] & reg_re & !reg_error; - assign err_code_4_re = addr_hit[9] & reg_re & !reg_error; - assign err_code_5_re = addr_hit[10] & reg_re & !reg_error; - assign err_code_6_re = addr_hit[11] & reg_re & !reg_error; - assign err_code_7_re = addr_hit[12] & reg_re & !reg_error; - assign err_code_8_re = addr_hit[13] & reg_re & !reg_error; - assign err_code_9_re = addr_hit[14] & reg_re & !reg_error; - assign err_code_10_re = addr_hit[15] & reg_re & !reg_error; - assign err_code_11_re = addr_hit[16] & reg_re & !reg_error; - assign err_code_12_re = addr_hit[17] & reg_re & !reg_error; - assign direct_access_regwen_re = addr_hit[18] & reg_re & !reg_error; - assign direct_access_regwen_we = addr_hit[18] & reg_we & !reg_error; - - assign direct_access_regwen_wd = reg_wdata[0]; - assign direct_access_cmd_we = addr_hit[19] & reg_we & !reg_error; - - assign direct_access_cmd_rd_wd = reg_wdata[0]; - - assign direct_access_cmd_wr_wd = reg_wdata[1]; - - assign direct_access_cmd_digest_wd = reg_wdata[2]; - assign direct_access_address_we = addr_hit[20] & reg_we & !reg_error; - - assign direct_access_address_wd = reg_wdata[10:0]; - assign direct_access_wdata_0_we = addr_hit[21] & reg_we & !reg_error; - - assign direct_access_wdata_0_wd = reg_wdata[31:0]; - assign direct_access_wdata_1_we = addr_hit[22] & reg_we & !reg_error; - - assign direct_access_wdata_1_wd = reg_wdata[31:0]; - assign direct_access_rdata_0_re = addr_hit[23] & reg_re & !reg_error; - assign direct_access_rdata_1_re = addr_hit[24] & reg_re & !reg_error; - assign check_trigger_regwen_we = addr_hit[25] & reg_we & !reg_error; - - assign check_trigger_regwen_wd = reg_wdata[0]; - assign check_trigger_we = addr_hit[26] & reg_we & !reg_error; - - assign check_trigger_integrity_wd = reg_wdata[0]; - - assign check_trigger_consistency_wd = reg_wdata[1]; - assign check_regwen_we = addr_hit[27] & reg_we & !reg_error; - - assign check_regwen_wd = reg_wdata[0]; - assign check_timeout_we = addr_hit[28] & reg_we & !reg_error; - - assign check_timeout_wd = reg_wdata[31:0]; - assign integrity_check_period_we = addr_hit[29] & reg_we & !reg_error; - - assign integrity_check_period_wd = reg_wdata[31:0]; - assign consistency_check_period_we = addr_hit[30] & reg_we & !reg_error; - - assign consistency_check_period_wd = reg_wdata[31:0]; - assign vendor_test_read_lock_we = addr_hit[31] & reg_we & !reg_error; - - assign vendor_test_read_lock_wd = reg_wdata[0]; - assign creator_sw_cfg_read_lock_we = addr_hit[32] & reg_we & !reg_error; - - assign creator_sw_cfg_read_lock_wd = reg_wdata[0]; - assign owner_sw_cfg_read_lock_we = addr_hit[33] & reg_we & !reg_error; - - assign owner_sw_cfg_read_lock_wd = reg_wdata[0]; - assign rot_creator_auth_codesign_read_lock_we = addr_hit[34] & reg_we & !reg_error; - - assign rot_creator_auth_codesign_read_lock_wd = reg_wdata[0]; - assign rot_creator_auth_state_read_lock_we = addr_hit[35] & reg_we & !reg_error; - - assign rot_creator_auth_state_read_lock_wd = reg_wdata[0]; - assign vendor_test_digest_0_re = addr_hit[36] & reg_re & !reg_error; - assign vendor_test_digest_1_re = addr_hit[37] & reg_re & !reg_error; - assign creator_sw_cfg_digest_0_re = addr_hit[38] & reg_re & !reg_error; - assign creator_sw_cfg_digest_1_re = addr_hit[39] & reg_re & !reg_error; - assign owner_sw_cfg_digest_0_re = addr_hit[40] & reg_re & !reg_error; - assign owner_sw_cfg_digest_1_re = addr_hit[41] & reg_re & !reg_error; - assign rot_creator_auth_codesign_digest_0_re = addr_hit[42] & reg_re & !reg_error; - assign rot_creator_auth_codesign_digest_1_re = addr_hit[43] & reg_re & !reg_error; - assign rot_creator_auth_state_digest_0_re = addr_hit[44] & reg_re & !reg_error; - assign rot_creator_auth_state_digest_1_re = addr_hit[45] & reg_re & !reg_error; - assign hw_cfg0_digest_0_re = addr_hit[46] & reg_re & !reg_error; - assign hw_cfg0_digest_1_re = addr_hit[47] & reg_re & !reg_error; - assign hw_cfg1_digest_0_re = addr_hit[48] & reg_re & !reg_error; - assign hw_cfg1_digest_1_re = addr_hit[49] & reg_re & !reg_error; - assign secret0_digest_0_re = addr_hit[50] & reg_re & !reg_error; - assign secret0_digest_1_re = addr_hit[51] & reg_re & !reg_error; - assign secret1_digest_0_re = addr_hit[52] & reg_re & !reg_error; - assign secret1_digest_1_re = addr_hit[53] & reg_re & !reg_error; - assign secret2_digest_0_re = addr_hit[54] & reg_re & !reg_error; - assign secret2_digest_1_re = addr_hit[55] & reg_re & !reg_error; - - // Assign write-enables to checker logic vector. - always_comb begin - reg_we_check = '0; - reg_we_check[0] = intr_state_we; - reg_we_check[1] = intr_enable_we; - reg_we_check[2] = intr_test_we; - reg_we_check[3] = alert_test_we; - reg_we_check[4] = 1'b0; - reg_we_check[5] = 1'b0; - reg_we_check[6] = 1'b0; - reg_we_check[7] = 1'b0; - reg_we_check[8] = 1'b0; - reg_we_check[9] = 1'b0; - reg_we_check[10] = 1'b0; - reg_we_check[11] = 1'b0; - reg_we_check[12] = 1'b0; - reg_we_check[13] = 1'b0; - reg_we_check[14] = 1'b0; - reg_we_check[15] = 1'b0; - reg_we_check[16] = 1'b0; - reg_we_check[17] = 1'b0; - reg_we_check[18] = direct_access_regwen_we; - reg_we_check[19] = direct_access_cmd_gated_we; - reg_we_check[20] = direct_access_address_gated_we; - reg_we_check[21] = direct_access_wdata_0_gated_we; - reg_we_check[22] = direct_access_wdata_1_gated_we; - reg_we_check[23] = 1'b0; - reg_we_check[24] = 1'b0; - reg_we_check[25] = check_trigger_regwen_we; - reg_we_check[26] = check_trigger_gated_we; - reg_we_check[27] = check_regwen_we; - reg_we_check[28] = check_timeout_gated_we; - reg_we_check[29] = integrity_check_period_gated_we; - reg_we_check[30] = consistency_check_period_gated_we; - reg_we_check[31] = vendor_test_read_lock_gated_we; - reg_we_check[32] = creator_sw_cfg_read_lock_gated_we; - reg_we_check[33] = owner_sw_cfg_read_lock_gated_we; - reg_we_check[34] = rot_creator_auth_codesign_read_lock_gated_we; - reg_we_check[35] = rot_creator_auth_state_read_lock_gated_we; - reg_we_check[36] = 1'b0; - reg_we_check[37] = 1'b0; - reg_we_check[38] = 1'b0; - reg_we_check[39] = 1'b0; - reg_we_check[40] = 1'b0; - reg_we_check[41] = 1'b0; - reg_we_check[42] = 1'b0; - reg_we_check[43] = 1'b0; - reg_we_check[44] = 1'b0; - reg_we_check[45] = 1'b0; - reg_we_check[46] = 1'b0; - reg_we_check[47] = 1'b0; - reg_we_check[48] = 1'b0; - reg_we_check[49] = 1'b0; - reg_we_check[50] = 1'b0; - reg_we_check[51] = 1'b0; - reg_we_check[52] = 1'b0; - reg_we_check[53] = 1'b0; - reg_we_check[54] = 1'b0; - reg_we_check[55] = 1'b0; - end - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[0] = intr_state_otp_operation_done_qs; - reg_rdata_next[1] = intr_state_otp_error_qs; - end - - addr_hit[1]: begin - reg_rdata_next[0] = intr_enable_otp_operation_done_qs; - reg_rdata_next[1] = intr_enable_otp_error_qs; - end - - addr_hit[2]: begin - reg_rdata_next[0] = '0; - reg_rdata_next[1] = '0; - end - - addr_hit[3]: begin - reg_rdata_next[0] = '0; - reg_rdata_next[1] = '0; - reg_rdata_next[2] = '0; - reg_rdata_next[3] = '0; - reg_rdata_next[4] = '0; - end - - addr_hit[4]: begin - reg_rdata_next[0] = status_vendor_test_error_qs; - reg_rdata_next[1] = status_creator_sw_cfg_error_qs; - reg_rdata_next[2] = status_owner_sw_cfg_error_qs; - reg_rdata_next[3] = status_rot_creator_auth_codesign_error_qs; - reg_rdata_next[4] = status_rot_creator_auth_state_error_qs; - reg_rdata_next[5] = status_hw_cfg0_error_qs; - reg_rdata_next[6] = status_hw_cfg1_error_qs; - reg_rdata_next[7] = status_secret0_error_qs; - reg_rdata_next[8] = status_secret1_error_qs; - reg_rdata_next[9] = status_secret2_error_qs; - reg_rdata_next[10] = status_life_cycle_error_qs; - reg_rdata_next[11] = status_dai_error_qs; - reg_rdata_next[12] = status_lci_error_qs; - reg_rdata_next[13] = status_timeout_error_qs; - reg_rdata_next[14] = status_lfsr_fsm_error_qs; - reg_rdata_next[15] = status_scrambling_fsm_error_qs; - reg_rdata_next[16] = status_key_deriv_fsm_error_qs; - reg_rdata_next[17] = status_bus_integ_error_qs; - reg_rdata_next[18] = status_dai_idle_qs; - reg_rdata_next[19] = status_check_pending_qs; - end - - addr_hit[5]: begin - reg_rdata_next[2:0] = err_code_0_qs; - end - - addr_hit[6]: begin - reg_rdata_next[2:0] = err_code_1_qs; - end - - addr_hit[7]: begin - reg_rdata_next[2:0] = err_code_2_qs; - end - - addr_hit[8]: begin - reg_rdata_next[2:0] = err_code_3_qs; - end - - addr_hit[9]: begin - reg_rdata_next[2:0] = err_code_4_qs; - end - - addr_hit[10]: begin - reg_rdata_next[2:0] = err_code_5_qs; - end - - addr_hit[11]: begin - reg_rdata_next[2:0] = err_code_6_qs; - end - - addr_hit[12]: begin - reg_rdata_next[2:0] = err_code_7_qs; - end - - addr_hit[13]: begin - reg_rdata_next[2:0] = err_code_8_qs; - end - - addr_hit[14]: begin - reg_rdata_next[2:0] = err_code_9_qs; - end - - addr_hit[15]: begin - reg_rdata_next[2:0] = err_code_10_qs; - end - - addr_hit[16]: begin - reg_rdata_next[2:0] = err_code_11_qs; - end - - addr_hit[17]: begin - reg_rdata_next[2:0] = err_code_12_qs; - end - - addr_hit[18]: begin - reg_rdata_next[0] = direct_access_regwen_qs; - end - - addr_hit[19]: begin - reg_rdata_next[0] = '0; - reg_rdata_next[1] = '0; - reg_rdata_next[2] = '0; - end - - addr_hit[20]: begin - reg_rdata_next[10:0] = direct_access_address_qs; - end - - addr_hit[21]: begin - reg_rdata_next[31:0] = direct_access_wdata_0_qs; - end - - addr_hit[22]: begin - reg_rdata_next[31:0] = direct_access_wdata_1_qs; - end - - addr_hit[23]: begin - reg_rdata_next[31:0] = direct_access_rdata_0_qs; - end - - addr_hit[24]: begin - reg_rdata_next[31:0] = direct_access_rdata_1_qs; - end - - addr_hit[25]: begin - reg_rdata_next[0] = check_trigger_regwen_qs; - end - - addr_hit[26]: begin - reg_rdata_next[0] = '0; - reg_rdata_next[1] = '0; - end - - addr_hit[27]: begin - reg_rdata_next[0] = check_regwen_qs; - end - - addr_hit[28]: begin - reg_rdata_next[31:0] = check_timeout_qs; - end - - addr_hit[29]: begin - reg_rdata_next[31:0] = integrity_check_period_qs; - end - - addr_hit[30]: begin - reg_rdata_next[31:0] = consistency_check_period_qs; - end - - addr_hit[31]: begin - reg_rdata_next[0] = vendor_test_read_lock_qs; - end - - addr_hit[32]: begin - reg_rdata_next[0] = creator_sw_cfg_read_lock_qs; - end - - addr_hit[33]: begin - reg_rdata_next[0] = owner_sw_cfg_read_lock_qs; - end - - addr_hit[34]: begin - reg_rdata_next[0] = rot_creator_auth_codesign_read_lock_qs; - end - - addr_hit[35]: begin - reg_rdata_next[0] = rot_creator_auth_state_read_lock_qs; - end - - addr_hit[36]: begin - reg_rdata_next[31:0] = vendor_test_digest_0_qs; - end - - addr_hit[37]: begin - reg_rdata_next[31:0] = vendor_test_digest_1_qs; - end - - addr_hit[38]: begin - reg_rdata_next[31:0] = creator_sw_cfg_digest_0_qs; - end - - addr_hit[39]: begin - reg_rdata_next[31:0] = creator_sw_cfg_digest_1_qs; - end - - addr_hit[40]: begin - reg_rdata_next[31:0] = owner_sw_cfg_digest_0_qs; - end - - addr_hit[41]: begin - reg_rdata_next[31:0] = owner_sw_cfg_digest_1_qs; - end - - addr_hit[42]: begin - reg_rdata_next[31:0] = rot_creator_auth_codesign_digest_0_qs; - end - - addr_hit[43]: begin - reg_rdata_next[31:0] = rot_creator_auth_codesign_digest_1_qs; - end - - addr_hit[44]: begin - reg_rdata_next[31:0] = rot_creator_auth_state_digest_0_qs; - end - - addr_hit[45]: begin - reg_rdata_next[31:0] = rot_creator_auth_state_digest_1_qs; - end - - addr_hit[46]: begin - reg_rdata_next[31:0] = hw_cfg0_digest_0_qs; - end - - addr_hit[47]: begin - reg_rdata_next[31:0] = hw_cfg0_digest_1_qs; - end - - addr_hit[48]: begin - reg_rdata_next[31:0] = hw_cfg1_digest_0_qs; - end - - addr_hit[49]: begin - reg_rdata_next[31:0] = hw_cfg1_digest_1_qs; - end - - addr_hit[50]: begin - reg_rdata_next[31:0] = secret0_digest_0_qs; - end - - addr_hit[51]: begin - reg_rdata_next[31:0] = secret0_digest_1_qs; - end - - addr_hit[52]: begin - reg_rdata_next[31:0] = secret1_digest_0_qs; - end - - addr_hit[53]: begin - reg_rdata_next[31:0] = secret1_digest_1_qs; - end - - addr_hit[54]: begin - reg_rdata_next[31:0] = secret2_digest_0_qs; - end - - addr_hit[55]: begin - reg_rdata_next[31:0] = secret2_digest_1_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // shadow busy - logic shadow_busy; - assign shadow_busy = 1'b0; - - // register busy - assign reg_busy = shadow_busy; - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) - `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) - - `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) - - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) - - // this is formulated as an assumption such that the FPV testbenches do disprove this - // property by mistake - //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis) - -endmodule diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv deleted file mode 100644 index 820eaafed3757..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv +++ /dev/null @@ -1,858 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Direct access interface for OTP controller. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_dai - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -( - input clk_i, - input rst_ni, - // Init reqest from power manager - input init_req_i, - output logic init_done_o, - // Init request going to partitions - output logic part_init_req_o, - input [NumPart-1:0] part_init_done_i, - // Escalation input. This moves the FSM into a terminal state and locks down - // the DAI. - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - // Output error state of DAI, to be consumed by OTP error/alert logic. - // Note that most errors are not recoverable and move the DAI FSM into - // a terminal error state. - output otp_err_e error_o, - // This error signal is pulsed high if the FSM has been glitched into an invalid state. - // Although it is somewhat redundant with the error code in error_o above, it is - // meant to cover cases where we already latched an error code while the FSM is - // glitched into an invalid state (since in that case, the error code will not be - // overridden with the FSM error code so that the original error code is still - // discoverable). - output logic fsm_err_o, - // Access/lock status from partitions - // SEC_CM: ACCESS.CTRL.MUBI - input part_access_t [NumPart-1:0] part_access_i, - // CSR interface - input [OtpByteAddrWidth-1:0] dai_addr_i, - input dai_cmd_e dai_cmd_i, - input logic dai_req_i, - input [NumDaiWords-1:0][31:0] dai_wdata_i, - output logic dai_idle_o, // wired to the status CSRs - output logic dai_prog_idle_o, // wired to lfsr timer and pwrmgr - output logic dai_cmd_done_o, // this is used to raise an IRQ - output logic [NumDaiWords-1:0][31:0] dai_rdata_o, - // OTP interface - output logic otp_req_o, - output prim_otp_pkg::cmd_e otp_cmd_o, - output logic [OtpSizeWidth-1:0] otp_size_o, - output logic [OtpIfWidth-1:0] otp_wdata_o, - output logic [OtpAddrWidth-1:0] otp_addr_o, - input otp_gnt_i, - input otp_rvalid_i, - input [ScrmblBlockWidth-1:0] otp_rdata_i, - input prim_otp_pkg::err_e otp_err_i, - // Scrambling mutex request - output logic scrmbl_mtx_req_o, - input scrmbl_mtx_gnt_i, - // Scrambling datapath interface - output otp_scrmbl_cmd_e scrmbl_cmd_o, - output digest_mode_e scrmbl_mode_o, - output logic [ConstSelWidth-1:0] scrmbl_sel_o, - output logic [ScrmblBlockWidth-1:0] scrmbl_data_o, - output logic scrmbl_valid_o, - input logic scrmbl_ready_i, - input logic scrmbl_valid_i, - input logic [ScrmblBlockWidth-1:0] scrmbl_data_i -); - - //////////////////////// - // Integration Checks // - //////////////////////// - - import prim_mubi_pkg::*; - import prim_util_pkg::vbits; - - localparam int CntWidth = OtpByteAddrWidth - $clog2(ScrmblBlockWidth/8); - - // Integration checks for parameters. - `ASSERT_INIT(CheckNativeOtpWidth0_A, (ScrmblBlockWidth % OtpWidth) == 0) - `ASSERT_INIT(CheckNativeOtpWidth1_A, (32 % OtpWidth) == 0) - - ///////////////////// - // DAI Control FSM // - ///////////////////// - - // SEC_CM: DAI.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 20 -n 12 \ - // -s 3011551511 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||| (31.05%) - // 6: |||||||||||||||||||| (36.84%) - // 7: |||||||| (15.26%) - // 8: |||| (8.95%) - // 9: || (5.26%) - // 10: (1.58%) - // 11: (1.05%) - // 12: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 11 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 9 - // - localparam int StateWidth = 12; - typedef enum logic [StateWidth-1:0] { - ResetSt = 12'b101111010100, - InitOtpSt = 12'b110000110010, - InitPartSt = 12'b000111111001, - IdleSt = 12'b111010000011, - ErrorSt = 12'b100010001110, - ReadSt = 12'b100101100110, - ReadWaitSt = 12'b001100000000, - DescrSt = 12'b011000101111, - DescrWaitSt = 12'b110101011111, - WriteSt = 12'b110111001000, - WriteWaitSt = 12'b111001111100, - ScrSt = 12'b000000010101, - ScrWaitSt = 12'b010110110100, - DigClrSt = 12'b001111001111, - DigReadSt = 12'b001001110011, - DigReadWaitSt = 12'b101110111010, - DigSt = 12'b011111100010, - DigPadSt = 12'b011010011000, - DigFinSt = 12'b110011100101, - DigWaitSt = 12'b100000101001 - } state_e; - - typedef enum logic [1:0] { - OtpData = 2'b00, - DaiData = 2'b01, - ScrmblData = 2'b10 - } data_sel_e; - - - typedef enum logic { - PartOffset = 1'b0, - DaiOffset = 1'b1 - } addr_sel_e; - - state_e state_d, state_q; - logic [CntWidth-1:0] cnt; - logic cnt_en, cnt_clr, cnt_err; - otp_err_e error_d, error_q; - logic data_en, data_clr; - data_sel_e data_sel; - addr_sel_e base_sel_d, base_sel_q; - logic [ScrmblBlockWidth-1:0] data_q; - logic [NumPartWidth-1:0] part_idx; - logic [NumPart-1:0][OtpAddrWidth-1:0] digest_addr_lut; - logic part_sel_valid; - - // Depending on the partition configuration, the wrapper is instructed to ignore integrity - // calculations and checks. To be on the safe side, the partition filters error responses at this - // point and does not report any integrity errors if integrity is disabled. - otp_err_e otp_err; - always_comb begin - otp_err = otp_err_e'(otp_err_i); - if (!PartInfo[part_idx].integrity && - otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin - otp_err = NoError; - end - end - - // Output partition error state. - assign error_o = error_q; - // Working register is connected to data outputs. - assign otp_wdata_o = data_q; - assign scrmbl_data_o = data_q; - // Only expose this working register in IdleSt. - // The FSM below makes sure to clear this register - // after digest and write ops. - assign dai_rdata_o = (state_q == IdleSt) ? data_q : '0; - - always_comb begin : p_fsm - state_d = state_q; - - // Init signals - init_done_o = 1'b1; - part_init_req_o = 1'b0; - - // DAI signals - dai_idle_o = 1'b0; - dai_prog_idle_o = 1'b1; - dai_cmd_done_o = 1'b0; - - // OTP signals - otp_req_o = 1'b0; - otp_cmd_o = prim_otp_pkg::Init; - - // Scrambling mutex - scrmbl_mtx_req_o = 1'b0; - - // Scrambling datapath - scrmbl_cmd_o = LoadShadow; - scrmbl_sel_o = CnstyDigest; - scrmbl_mode_o = StandardMode; - scrmbl_valid_o = 1'b0; - - // Counter - cnt_en = 1'b0; - cnt_clr = 1'b0; - base_sel_d = base_sel_q; - - // Temporary data register - data_en = 1'b0; - data_clr = 1'b0; - data_sel = OtpData; - - // Error Register - error_d = error_q; - fsm_err_o = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // We get here after reset and wait until the power manager - // requests OTP initialization. If initialization is requested, - // an init command is written to the OTP macro, and we move on - // to the InitOtpSt waiting state. - ResetSt: begin - init_done_o = 1'b0; - dai_prog_idle_o = 1'b0; - data_clr = 1'b1; - if (init_req_i) begin - otp_req_o = 1'b1; - if (otp_gnt_i) begin - state_d = InitOtpSt; - end - end - end - /////////////////////////////////////////////////////////////////// - // We wait here unitl the OTP macro has initialized without - // error. If an error occurred during this stage, we latch that - // error and move into a terminal error state. - InitOtpSt: begin - init_done_o = 1'b0; - dai_prog_idle_o = 1'b0; - if (otp_rvalid_i) begin - if ((!(otp_err inside {NoError, MacroEccCorrError}))) begin - state_d = ErrorSt; - error_d = otp_err; - end else begin - state_d = InitPartSt; - end - end - end - /////////////////////////////////////////////////////////////////// - // Since the OTP macro is now functional, we can send out an - // initialization request to all partitions and wait until they - // all have initialized. - InitPartSt: begin - init_done_o = 1'b0; - dai_prog_idle_o = 1'b0; - part_init_req_o = 1'b1; - if (part_init_done_i == {NumPart{1'b1}}) begin - state_d = IdleSt; - end - end - /////////////////////////////////////////////////////////////////// - // Idle state where we wait for incoming commands. - // Invalid commands trigger a CmdInvErr, which is recoverable. - IdleSt: begin - dai_idle_o = 1'b1; - if (dai_req_i) begin - // This clears previous (recoverable) and reset the counter. - error_d = NoError; - cnt_clr = 1'b1; - unique case (dai_cmd_i) - DaiRead: begin - state_d = ReadSt; - // Clear the temporary data register. - data_clr = 1'b1; - base_sel_d = DaiOffset; - end - DaiWrite: begin - data_sel = DaiData; - // Fetch data block. - data_en = 1'b1; - base_sel_d = DaiOffset; - // If this partition is scrambled, directly go to write scrambling first. - if (PartInfo[part_idx].secret) begin - state_d = ScrSt; - end else begin - state_d = WriteSt; - end - end - DaiDigest: begin - state_d = DigClrSt; - scrmbl_mtx_req_o = 1'b1; - base_sel_d = PartOffset; - end - default: ; // Ignore invalid commands - endcase // dai_cmd_i - end // dai_req_i - end - /////////////////////////////////////////////////////////////////// - // Each time we request a block of data from OTP, we re-check - // whether read access has been locked for this partition. If - // that is the case, we immediately bail out. Otherwise, we - // request a block of data from OTP. - ReadSt: begin - if (part_sel_valid && (mubi8_test_false_strict(part_access_i[part_idx].read_lock) || - // HW digests always remain readable. - PartInfo[part_idx].hw_digest && otp_addr_o == - digest_addr_lut[part_idx])) begin - otp_req_o = 1'b1; - // Depending on the partition configuration, - // the wrapper is instructed to ignore integrity errors. - if (PartInfo[part_idx].integrity) begin - otp_cmd_o = prim_otp_pkg::Read; - end else begin - otp_cmd_o = prim_otp_pkg::ReadRaw; - end - if (otp_gnt_i) begin - state_d = ReadWaitSt; - end - end else begin - state_d = IdleSt; - error_d = AccessError; // Signal this error, but do not go into terminal error state. - dai_cmd_done_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and write to readout register. Check - // whether descrambling is required or not. In case an OTP - // transaction fails, latch the OTP error code, and jump to - // terminal error state. - ReadWaitSt: begin - // Continuously check read access and bail out if this is not consistent. - if (part_sel_valid && (mubi8_test_false_strict(part_access_i[part_idx].read_lock) || - // HW digests always remain readable. - PartInfo[part_idx].hw_digest && otp_addr_o == - digest_addr_lut[part_idx])) begin - if (otp_rvalid_i) begin - // Check OTP return code. - if (otp_err inside {NoError, MacroEccCorrError}) begin - data_en = 1'b1; - // We do not need to descramble the digest values. - if (PartInfo[part_idx].secret && otp_addr_o != digest_addr_lut[part_idx]) begin - state_d = DescrSt; - end else begin - state_d = IdleSt; - dai_cmd_done_o = 1'b1; - end - // At this point the only error that we could have gotten are correctable ECC errors. - if (otp_err != NoError) begin - error_d = MacroEccCorrError; - end - end else begin - state_d = ErrorSt; - error_d = otp_err; - end - end - // At this point, this check MUST succeed - otherwise this means that - // there was a tampering attempt. Hence we go into a terminal error state - // when this check fails. - end else begin - state_d = ErrorSt; - error_d = FsmStateError; - end - end - /////////////////////////////////////////////////////////////////// - // Descrambling state. This first acquires the scrambling - // datapath mutex. Note that once the mutex is acquired, we have - // exclusive access to the scrambling datapath until we release - // the mutex by deasserting scrmbl_mtx_req_o. - // SEC_CM: SECRET.MEM.SCRAMBLE - DescrSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Decrypt; - scrmbl_sel_o = PartInfo[part_idx].key_sel; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = DescrWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the descrambled data to return. Note that we release - // the mutex lock upon leaving this state. - // SEC_CM: SECRET.MEM.SCRAMBLE - DescrWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_sel_o = PartInfo[part_idx].key_sel; - data_sel = ScrmblData; - if (scrmbl_valid_i) begin - state_d = IdleSt; - data_en = 1'b1; - dai_cmd_done_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // First, check whether write accesses are allowed to this - // partition, and error out otherwise. Note that for buffered - // partitions, we do not allow DAI writes to the digest offset. - // Unbuffered partitions have SW managed digests, hence that - // check is not needed in that case. The LC partition is - // permanently write locked and can hence not be written via the DAI. - WriteSt: begin - dai_prog_idle_o = 1'b0; - if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) && - // If this is a HW digest write to a buffered partition. - ((PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest && - base_sel_q == PartOffset && otp_addr_o == digest_addr_lut[part_idx]) || - // If this is a non HW digest write to a buffered partition. - (PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest && - base_sel_q == DaiOffset && otp_addr_o < digest_addr_lut[part_idx]) || - // If this is a write to an unbuffered partition - (PartInfo[part_idx].variant != Buffered && base_sel_q == DaiOffset))) begin - otp_req_o = 1'b1; - // Depending on the partition configuration, - // the wrapper is instructed to ignore integrity errors. - if (PartInfo[part_idx].integrity) begin - otp_cmd_o = prim_otp_pkg::Write; - end else begin - otp_cmd_o = prim_otp_pkg::WriteRaw; - end - if (otp_gnt_i) begin - state_d = WriteWaitSt; - end - end else begin - // Clear working register state. - data_clr = 1'b1; - state_d = IdleSt; - error_d = AccessError; // Signal this error, but do not go into terminal error state. - dai_cmd_done_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response, and then go back to idle. In case an - // OTP transaction fails, latch the OTP error code, and jump to - // terminal error state. - WriteWaitSt: begin - dai_prog_idle_o = 1'b0; - // Continuously check write access and bail out if this is not consistent. - if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) && - // If this is a HW digest write to a buffered partition. - ((PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest && - base_sel_q == PartOffset && otp_addr_o == digest_addr_lut[part_idx]) || - // If this is a non HW digest write to a buffered partition. - (PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].hw_digest && - base_sel_q == DaiOffset && otp_addr_o < digest_addr_lut[part_idx]) || - // If this is a write to an unbuffered partition - (PartInfo[part_idx].variant != Buffered && base_sel_q == DaiOffset))) begin - - if (otp_rvalid_i) begin - // Check OTP return code. Note that non-blank errors are recoverable. - if ((!(otp_err inside {NoError, MacroWriteBlankError}))) begin - state_d = ErrorSt; - error_d = otp_err; - end else begin - // Clear working register state. - data_clr = 1'b1; - state_d = IdleSt; - dai_cmd_done_o = 1'b1; - // Signal non-blank state, but do not go to terminal error state. - if (otp_err == MacroWriteBlankError) begin - error_d = otp_err; - end - end - end - // At this point, this check MUST succeed - otherwise this means that - // there was a tampering attempt. Hence we go into a terminal error state - // when this check fails. - end else begin - state_d = ErrorSt; - error_d = FsmStateError; - end - end - /////////////////////////////////////////////////////////////////// - // Scrambling state. This first acquires the scrambling - // datapath mutex. Note that once the mutex is acquired, we have - // exclusive access to the scrambling datapath until we release - // the mutex by deasserting scrmbl_mtx_req_o. - // SEC_CM: SECRET.MEM.SCRAMBLE - ScrSt: begin - scrmbl_mtx_req_o = 1'b1; - // Check write access and bail out if this is not consistent. - if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) && - // If this is a non HW digest write to a buffered partition. - (PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].secret && - PartInfo[part_idx].hw_digest && base_sel_q == DaiOffset && - otp_addr_o < digest_addr_lut[part_idx])) begin - - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Encrypt; - scrmbl_sel_o = PartInfo[part_idx].key_sel; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = ScrWaitSt; - end - end else begin - state_d = IdleSt; - error_d = AccessError; // Signal this error, but do not go into terminal error state. - dai_cmd_done_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the scrambled data to return. Note that we release - // the mutex lock upon leaving this state. - // SEC_CM: SECRET.MEM.SCRAMBLE - ScrWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - // Continously check write access and bail out if this is not consistent. - if (part_sel_valid && mubi8_test_false_strict(part_access_i[part_idx].write_lock) && - // If this is a non HW digest write to a buffered partition. - (PartInfo[part_idx].variant == Buffered && PartInfo[part_idx].secret && - PartInfo[part_idx].hw_digest && base_sel_q == DaiOffset && - otp_addr_o < digest_addr_lut[part_idx])) begin - data_sel = ScrmblData; - if (scrmbl_valid_i) begin - state_d = WriteSt; - data_en = 1'b1; - end - // At this point, this check MUST succeed - otherwise this means that - // there was a tampering attempt. Hence we go into a terminal error state - // when this check fails. - end else begin - state_d = ErrorSt; - error_d = FsmStateError; - end - end - /////////////////////////////////////////////////////////////////// - // First, acquire the mutex for the digest and clear the digest state. - // SEC_CM: PART.MEM.DIGEST - DigClrSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - // Need to reset the digest state and set digest mode to "standard". - scrmbl_cmd_o = DigestInit; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = DigReadSt; - end - end - /////////////////////////////////////////////////////////////////// - // This requests a 64bit block to be pushed into the digest datapath. - // We also check here whether the partition has been write locked. - // SEC_CM: PART.MEM.DIGEST - DigReadSt: begin - scrmbl_mtx_req_o = 1'b1; - if (part_sel_valid && - mubi8_test_false_strict(part_access_i[part_idx].read_lock) && - mubi8_test_false_strict(part_access_i[part_idx].write_lock)) begin - otp_req_o = 1'b1; - // Depending on the partition configuration, - // the wrapper is instructed to ignore integrity errors. - if (PartInfo[part_idx].integrity) begin - otp_cmd_o = prim_otp_pkg::Read; - end else begin - otp_cmd_o = prim_otp_pkg::ReadRaw; - end - if (otp_gnt_i) begin - state_d = DigReadWaitSt; - end - end else begin - state_d = IdleSt; - error_d = AccessError; // Signal this error, but do not go into terminal error state. - dai_cmd_done_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and write to readout register. Check - // whether descrambling is required or not. In case an OTP - // transaction fails, latch the OTP error code, and jump to - // terminal error state. - // SEC_CM: PART.MEM.DIGEST - DigReadWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - if (otp_rvalid_i) begin - cnt_en = 1'b1; - // Check OTP return code. - if ((!(otp_err inside {NoError, MacroEccCorrError}))) begin - state_d = ErrorSt; - error_d = otp_err; - end else begin - data_en = 1'b1; - state_d = DigSt; - // Signal soft ECC errors, but do not go into terminal error state. - if (otp_err == MacroEccCorrError) begin - error_d = otp_err; - end - end - end - end - /////////////////////////////////////////////////////////////////// - // Push the word read into the scrambling datapath. The last - // block is repeated in case the number blocks in this partition - // is odd. - // SEC_CM: PART.MEM.DIGEST - DigSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - // No need to digest the digest value itself - if (otp_addr_o == digest_addr_lut[part_idx]) begin - // Trigger digest round in case this is the second block in a row. - if (!cnt[0]) begin - scrmbl_cmd_o = Digest; - if (scrmbl_ready_i) begin - state_d = DigFinSt; - end - // Otherwise, just load low word and go to padding state. - end else if (scrmbl_ready_i) begin - state_d = DigPadSt; - end - end else begin - // Trigger digest round in case this is the second block in a row. - if (!cnt[0]) begin - scrmbl_cmd_o = Digest; - end - // Go back and fetch more data blocks. - if (scrmbl_ready_i) begin - state_d = DigReadSt; - end - end - end - /////////////////////////////////////////////////////////////////// - // Padding state, just repeat the last block and go to digest - // finalization. - // SEC_CM: PART.MEM.DIGEST - DigPadSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Digest; - if (scrmbl_ready_i) begin - state_d = DigFinSt; - end - end - /////////////////////////////////////////////////////////////////// - // Trigger digest finalization and go wait for the result. - // SEC_CM: PART.MEM.DIGEST - DigFinSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = DigestFinalize; - if (scrmbl_ready_i) begin - state_d = DigWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the digest to return, and write the result to OTP. - // Note that the write address will be correct in this state, - // since the counter has been stepped to the correct address as - // part of the readout sequence, and the correct size for this - // access has been loaded before. - // SEC_CM: PART.MEM.DIGEST - DigWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - data_sel = ScrmblData; - if (scrmbl_valid_i) begin - state_d = WriteSt; - data_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Terminal Error State. This locks access to the DAI. Make sure - // an FsmStateError error code is assigned here, in case no error code has - // been assigned yet. - ErrorSt: begin - if (error_q == NoError) begin - error_d = FsmStateError; - end - end - /////////////////////////////////////////////////////////////////// - // We should never get here. If we do (e.g. via a malicious - // glitch), error out immediately. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of escalation. - // SEC_CM: DAI.FSM.LOCAL_ESC, DAI.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - if (state_q != ErrorSt) begin - error_d = FsmStateError; - end - end - end - - //////////////////////////// - // Partition Select Logic // - //////////////////////////// - - // This checks which partition the address belongs to by comparing - // the incoming address to the partition address ranges. The onehot - // bitvector generated by the parallel comparisons is fed into a - // binary tree that determines the partition index with O(log(N)) delay. - - logic [NumPart-1:0] part_sel_oh; - for (genvar k = 0; k < NumPart; k++) begin : gen_part_sel - localparam int unsigned PartEndInt = 32'(PartInfo[k].offset) + 32'(PartInfo[k].size); - localparam int unsigned DigestOffsetInt = PartEndInt - ScrmblBlockWidth / 8; - localparam int unsigned DigestAddrLutInt = DigestOffsetInt >> OtpAddrShift; - - // PartEnd has an extra bit to cope with the case where offset + size overflows. However, we - // arrange the address map to make sure that PartEndInt is at most 1 << OtpByteAddrWidth. Check - // that here. - `ASSERT_INIT(PartEndMax_A, PartEndInt <= (1 << OtpByteAddrWidth)) - - // The shift right by OtpAddrShift drops exactly the bottom bits that are needed to convert - // between OtpAddrWidth and OtpByteAddrWidth, so we know that we can slice safely here. - localparam bit [OtpAddrWidth-1:0] DigestAddrLut = DigestAddrLutInt[OtpAddrWidth-1:0]; - - if (PartInfo[k].offset == 0) begin : gen_zero_offset - assign part_sel_oh[k] = ({1'b0, dai_addr_i} < PartEndInt[OtpByteAddrWidth:0]); - - end else begin : gen_nonzero_offset - assign part_sel_oh[k] = (dai_addr_i >= PartInfo[k].offset) & - ({1'b0, dai_addr_i} < PartEndInt[OtpByteAddrWidth:0]); - end - assign digest_addr_lut[k] = DigestAddrLut; - end - - `ASSERT(ScrmblBlockWidthGe8_A, ScrmblBlockWidth >= 8) - `ASSERT(PartSelMustBeOnehot_A, $onehot0(part_sel_oh)) - - prim_arbiter_fixed #( - .N(NumPart), - .EnDataPort(0) - ) u_part_sel_idx ( - .clk_i, - .rst_ni, - .req_i ( part_sel_oh ), - .data_i ( '{default: '0} ), - .gnt_o ( ), // unused - .idx_o ( part_idx ), - .valid_o ( part_sel_valid ), // used for detecting OOB addresses - .data_o ( ), // unused - .ready_i ( 1'b0 ) - ); - - ///////////////////////////////////// - // Address Calculations for Digest // - ///////////////////////////////////// - - // Depending on whether this is a 32bit or 64bit partition, we cut off the lower address bits. - // Access sizes are either 64bit or 32bit, depending on what region the access goes to. - logic [OtpByteAddrWidth-1:0] addr_base; - always_comb begin : p_size_sel - otp_size_o = OtpSizeWidth'(unsigned'(32 / OtpWidth - 1)); - addr_base = {dai_addr_i[OtpByteAddrWidth-1:2], 2'h0}; - - // 64bit transaction for scrambled partitions. - if (PartInfo[part_idx].secret) begin - otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth - 1)); - addr_base = {dai_addr_i[OtpByteAddrWidth-1:3], 3'h0}; - // 64bit transaction if computing a digest. - end else if (PartInfo[part_idx].hw_digest && (base_sel_q == PartOffset)) begin - otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth - 1)); - addr_base = PartInfo[part_idx].offset; - // 64bit transaction if the DAI address points to the partition's digest offset. - end else if ((PartInfo[part_idx].hw_digest || PartInfo[part_idx].sw_digest) && - (base_sel_q == DaiOffset) && - ({dai_addr_i[OtpByteAddrWidth-1:3], 2'b0} == digest_addr_lut[part_idx])) begin - otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth - 1)); - addr_base = {dai_addr_i[OtpByteAddrWidth-1:3], 3'h0}; - end - end - - // Address counter - this is only used for computing a digest, hence the increment is - // fixed to 8 byte. - // SEC_CM: DAI.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count ( - .clk_i, - .rst_ni, - .clr_i(cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(cnt), - .cnt_after_commit_o(), - .err_o(cnt_err) - ); - - // Note that OTP works on halfword (16bit) addresses, hence need to - // shift the addresses appropriately. - logic [OtpByteAddrWidth-1:0] addr_calc; - assign addr_calc = {cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}} + addr_base; - assign otp_addr_o = OtpAddrWidth'(addr_calc >> OtpAddrShift); - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - error_q <= NoError; - data_q <= '0; - base_sel_q <= DaiOffset; - end else begin - error_q <= error_d; - base_sel_q <= base_sel_d; - - // Working register - if (data_clr) begin - data_q <= '0; - end else if (data_en) begin - if (data_sel == ScrmblData) begin - data_q <= scrmbl_data_i; - end else if (data_sel == DaiData) begin - data_q <= dai_wdata_i; - end else begin - data_q <= otp_rdata_i; - end - end - end - end - - //////////////// - // Assertions // - //////////////// - - // Known assertions - `ASSERT_KNOWN(InitDoneKnown_A, init_done_o) - `ASSERT_KNOWN(PartInitReqKnown_A, part_init_req_o) - `ASSERT_KNOWN(ErrorKnown_A, error_o) - `ASSERT_KNOWN(DaiIdleKnown_A, dai_idle_o) - `ASSERT_KNOWN(DaiRdataKnown_A, dai_rdata_o) - `ASSERT_KNOWN(OtpReqKnown_A, otp_req_o) - `ASSERT_KNOWN(OtpCmdKnown_A, otp_cmd_o) - `ASSERT_KNOWN(OtpSizeKnown_A, otp_size_o) - `ASSERT_KNOWN(OtpWdataKnown_A, otp_wdata_o) - `ASSERT_KNOWN(OtpAddrKnown_A, otp_addr_o) - `ASSERT_KNOWN(ScrmblMtxReqKnown_A, scrmbl_mtx_req_o) - `ASSERT_KNOWN(ScrmblCmdKnown_A, scrmbl_cmd_o) - `ASSERT_KNOWN(ScrmblModeKnown_A, scrmbl_mode_o) - `ASSERT_KNOWN(ScrmblSelKnown_A, scrmbl_sel_o) - `ASSERT_KNOWN(ScrmblDataKnown_A, scrmbl_data_o) - `ASSERT_KNOWN(ScrmblValidKnown_A, scrmbl_valid_o) - - // OTP error response - `ASSERT(OtpErrorState_A, - state_q inside {InitOtpSt, ReadWaitSt, WriteWaitSt, DigReadWaitSt} && otp_rvalid_i && - !(otp_err inside {NoError, MacroEccCorrError, MacroWriteBlankError}) - |=> - state_q == ErrorSt && error_o == $past(otp_err)) - -endmodule : otp_ctrl_dai diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv deleted file mode 100644 index 2199a7cc6024d..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_ecc_reg.sv +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register file for buffered OTP partitions. ECC is used to detect up -// to two simultaneous errors within each 64bit word. - -`include "prim_assert.sv" - -module otp_ctrl_ecc_reg #( - parameter int Width = 64, // bit - parameter int Depth = 128, - localparam int Aw = prim_util_pkg::vbits(Depth) // derived parameter -) ( - input logic clk_i, - input logic rst_ni, - - input logic wren_i, - input logic [Aw-1:0] addr_i, - input logic [Width-1:0] wdata_i, - output logic [Width-1:0] rdata_o, - - // Concurrent output of the register state. - output logic [Depth-1:0][Width-1:0] data_o, - // Concurrent ECC check error is flagged via this signal. - output logic ecc_err_o -); - - // Integration checks for parameters. - `ASSERT_INIT(WidthMustBe64bit_A, Width == 64) - - localparam int EccWidth = 8; - - logic [Depth-1:0][Width-1:0] data_d, data_q; - logic [Depth-1:0][EccWidth-1:0] ecc_d, ecc_q; - logic [Width+EccWidth-1:0] ecc_enc; - - // Only one encoder is needed. - prim_secded_inv_72_64_enc u_prim_secded_inv_72_64_enc ( - .data_i(wdata_i), - .data_o(ecc_enc) - ); - - if (Depth == 1) begin : gen_one_word_only - always_comb begin : p_write - data_o = data_q; - data_d = data_q; - ecc_d = ecc_q; - - rdata_o = '0; - if (32'(addr_i) < Depth) begin - rdata_o = data_q[0]; - if (wren_i) begin - {ecc_d[0], data_d[0]} = ecc_enc; - end - end - end - end else begin : gen_multiple_words - always_comb begin : p_write - data_o = data_q; - data_d = data_q; - ecc_d = ecc_q; - - rdata_o = '0; - if (32'(addr_i) < Depth) begin - rdata_o = data_q[addr_i]; - if (wren_i) begin - {ecc_d[addr_i], data_d[addr_i]} = ecc_enc; - end - end - end - end - - // Concurrent ECC checks. - logic [Depth-1:0][1:0] err; - for (genvar k = 0; k < Depth; k++) begin : gen_ecc_dec - prim_secded_inv_72_64_dec u_prim_secded_inv_72_64_dec ( - .data_i({ecc_q[k], data_q[k]}), - // We only rely on the error detection mechanism, - // and not on error correction. - .data_o(), - .syndrome_o(), - .err_o(err[k]) - ); - end - - assign ecc_err_o = |err; - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - ecc_q <= {Depth{prim_secded_pkg::SecdedInv7264ZeroEcc}}; - data_q <= '0; - end else begin - ecc_q <= ecc_d; - data_q <= data_d; - end - end - - `ASSERT_KNOWN(EccKnown_A, ecc_q) - `ASSERT_KNOWN(DataKnown_A, data_q) - `ASSERT_KNOWN(RDataOutKnown_A, rdata_o) - `ASSERT_KNOWN(DataOutKnown_A, data_o) - `ASSERT_KNOWN(EccErrKnown_A, ecc_err_o) - -endmodule : otp_ctrl_ecc_reg diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_kdi.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_kdi.sv deleted file mode 100644 index 581c280e85498..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_kdi.sv +++ /dev/null @@ -1,603 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Scrambling key derivation module for OTP. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_kdi - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -#( - parameter scrmbl_key_init_t RndCnstScrmblKeyInit = RndCnstScrmblKeyInitDefault -) ( - input clk_i, - input rst_ni, - // Pulse to enable this module after OTP partitions have - // been initialized. - input kdi_en_i, - // Escalation input. This moves the FSM into a terminal state. - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - // FSM is in error state - output logic fsm_err_o, - // Key seed inputs from OTP - input logic scrmbl_key_seed_valid_i, - input logic [FlashKeySeedWidth-1:0] flash_data_key_seed_i, - input logic [FlashKeySeedWidth-1:0] flash_addr_key_seed_i, - input logic [SramKeySeedWidth-1:0] sram_data_key_seed_i, - // EDN interface for requesting entropy - output logic edn_req_o, - input edn_ack_i, - input [EdnDataWidth-1:0] edn_data_i, - // Scrambling key requests - input flash_otp_key_req_t flash_otp_key_i, - output flash_otp_key_rsp_t flash_otp_key_o, - input sram_otp_key_req_t [NumSramKeyReqSlots-1:0] sram_otp_key_i, - output sram_otp_key_rsp_t [NumSramKeyReqSlots-1:0] sram_otp_key_o, - input otbn_otp_key_req_t otbn_otp_key_i, - output otbn_otp_key_rsp_t otbn_otp_key_o, - // Scrambling mutex request - output logic scrmbl_mtx_req_o, - input scrmbl_mtx_gnt_i, - // Scrambling datapath interface - output otp_scrmbl_cmd_e scrmbl_cmd_o, - output digest_mode_e scrmbl_mode_o, - output logic [ConstSelWidth-1:0] scrmbl_sel_o, - output logic [ScrmblBlockWidth-1:0] scrmbl_data_o, - output logic scrmbl_valid_o, - input logic scrmbl_ready_i, - input logic scrmbl_valid_i, - input logic [ScrmblBlockWidth-1:0] scrmbl_data_i -); - - import prim_util_pkg::vbits; - - //////////////////////// - // Integration Checks // - //////////////////////// - - // 2xFlash, OTBN + SRAM slots - localparam int NumReq = 3 + NumSramKeyReqSlots; - // Make sure key sizes in the system are multiples of 64bit and not larger than 256bit. - `ASSERT_INIT(KeyNonceSize0_A, (FlashKeySeedWidth <= 256) && ((FlashKeySeedWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize1_A, (SramKeySeedWidth <= 256) && ((SramKeySeedWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize2_A, (FlashKeyWidth <= 256) && ((FlashKeyWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize3_A, (SramKeyWidth <= 256) && ((SramKeyWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize4_A, (SramNonceWidth <= 256) && ((SramNonceWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize5_A, (OtbnKeyWidth <= 256) && ((OtbnKeyWidth % 64) == 0)) - `ASSERT_INIT(KeyNonceSize6_A, (OtbnNonceWidth <= 256) && ((OtbnNonceWidth % 64) == 0)) - - // Make sure EDN interface has compatible width. - `ASSERT_INIT(EntropyWidthDividesDigestBlockWidth_A, (ScrmblKeyWidth % EdnDataWidth) == 0) - - // Currently the assumption is that the SRAM nonce is the widest. - `ASSERT_INIT(NonceWidth_A, NumNonceChunks * ScrmblBlockWidth == SramNonceWidth) - - /////////////////////////////////// - // Input Mapping and Arbitration // - /////////////////////////////////// - - // The key derivation and token hashing functions are aligned such that 2 x 128bit key - // seeds / token blocks are processed in two subsequent steps using the digest primitive. - // This effectively compresses these blocks down into 2 x 64bit blocks, thereby creating - // one 128bit key or token output. - // - // The same FSM is shared among the different flavors of key derivation and token - // hashing functions, and the following configuration options are available: - // - // 1) ingest an additional 128bit entropy block after ingesting a 128bit key seed. - // 2) keep digest state after producing the first 64bit block instead of reverting to the IV. - // 3) netlist constant index. - // 4) fetch additional entropy for the nonce output. - // 5) whether or not the key seed is valid. if not, it will be defaulted to '0. - // 6) 256bit key seed / token input. - // - // The configuration options are set further below, depending on the request type. - - typedef struct packed { - logic ingest_entropy; // 1) - logic chained_digest; // 2) - digest_sel_e digest_sel; // 3) - logic fetch_nonce; // 4) - logic [1:0] nonce_size; // 4) - logic seed_valid; // 5) - logic [3:0][ScrmblBlockWidth-1:0] seed; // 6) - } req_bundle_t; - - logic [NumReq-1:0] req, gnt; - req_bundle_t req_bundles [NumReq]; - - assign req[0] = flash_otp_key_i.data_req; - assign req[1] = flash_otp_key_i.addr_req; - assign req[2] = otbn_otp_key_i.req; - - assign flash_otp_key_o.data_ack = gnt[0]; - assign flash_otp_key_o.addr_ack = gnt[1]; - assign otbn_otp_key_o.ack = gnt[2]; - - // anchored seeds - logic [FlashKeySeedWidth-1:0] flash_data_key_seed; - logic [FlashKeySeedWidth-1:0] flash_addr_key_seed; - logic [SramKeySeedWidth-1:0] sram_data_key_seed; - - prim_sec_anchor_buf #( - .Width(FlashKeySeedWidth) - ) u_flash_data_key_anchor ( - .in_i(flash_data_key_seed_i), - .out_o(flash_data_key_seed) - ); - - prim_sec_anchor_buf #( - .Width(FlashKeySeedWidth) - ) u_flash_addr_key_anchor ( - .in_i(flash_addr_key_seed_i), - .out_o(flash_addr_key_seed) - ); - - prim_sec_anchor_buf #( - .Width(SramKeySeedWidth) - ) u_sram_data_key_anchor ( - .in_i(sram_data_key_seed_i), - .out_o(sram_data_key_seed) - ); - - // Flash data key - assign req_bundles[0] = '{ingest_entropy: 1'b0, // no random entropy added - chained_digest: 1'b0, // revert to netlist IV between blocks - digest_sel: FlashDataKey, - fetch_nonce: 1'b1, - nonce_size: 2'(FlashKeyWidth/EdnDataWidth-1), - seed_valid: scrmbl_key_seed_valid_i, - seed: flash_data_key_seed}; // 2x128bit - // Flash addr key - assign req_bundles[1] = '{ingest_entropy: 1'b0, // no random entropy added - chained_digest: 1'b0, // revert to netlist IV between blocks - digest_sel: FlashAddrKey, - fetch_nonce: 1'b1, - nonce_size: '0, - seed_valid: scrmbl_key_seed_valid_i, - seed: flash_addr_key_seed}; // 2x128bit - // OTBN key - assign req_bundles[2] = '{ingest_entropy: 1'b1, // ingest random data - chained_digest: 1'b0, // revert to netlist IV between blocks - digest_sel: SramDataKey, - fetch_nonce: 1'b1, // fetch nonce - nonce_size: 2'(OtbnNonceWidth/EdnDataWidth-1), - seed_valid: scrmbl_key_seed_valid_i, - seed: {sram_data_key_seed, // reuse same seed - sram_data_key_seed}}; - - // SRAM keys - for (genvar k = 3; k < NumReq; k++) begin : gen_req_assign - assign req[k] = sram_otp_key_i[k-3].req; - assign sram_otp_key_o[k-3].ack = gnt[k]; - assign req_bundles[k] = '{ingest_entropy: 1'b1, // ingest random data - chained_digest: 1'b0, // revert to netlist IV between blocks - digest_sel: SramDataKey, - fetch_nonce: 1'b1, // fetch nonce - nonce_size: 2'(SramNonceWidth/EdnDataWidth-1), - seed_valid: scrmbl_key_seed_valid_i, - seed: {sram_data_key_seed, // reuse same seed - sram_data_key_seed}}; - end - - // This arbitrates among incoming key derivation requests on a - // round robin basis to prevent deadlock. - logic req_valid, req_ready; - req_bundle_t req_bundle; - - prim_arbiter_tree #( - .N(NumReq), - .DW($bits(req_bundle_t))) - u_req_arb ( - .clk_i, - .rst_ni, - .req_chk_i ( 1'b1 ), - .req_i ( req ), - .data_i ( req_bundles ), - .gnt_o ( gnt ), - .idx_o ( ), - .valid_o ( req_valid ), - .data_o ( req_bundle ), - .ready_i ( req_ready ) - ); - - ////////////////////////////// - // Temporary Regs and Muxes // - ////////////////////////////// - - localparam int CntWidth = 2; - logic seed_cnt_clr, seed_cnt_en, entropy_cnt_clr, entropy_cnt_en, seed_cnt_err, entropy_cnt_err; - logic [CntWidth-1:0] seed_cnt, entropy_cnt; - - // SEC_CM: KDI_SEED.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count_seed ( - .clk_i, - .rst_ni, - .clr_i(seed_cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(seed_cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(seed_cnt), - .cnt_after_commit_o(), - .err_o(seed_cnt_err) - ); - - // SEC_CM: KDI_ENTROPY.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count_entropy ( - .clk_i, - .rst_ni, - .clr_i(entropy_cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(entropy_cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(entropy_cnt), - .cnt_after_commit_o(), - .err_o(entropy_cnt_err) - ); - - logic seed_valid_reg_en; - logic key_reg_en, nonce_reg_en; - logic seed_valid_d, seed_valid_q; - logic [ScrmblKeyWidth/ScrmblBlockWidth-1:0][ScrmblBlockWidth-1:0] key_out_d, key_out_q; - logic [NumNonceChunks-1:0][ScrmblBlockWidth-1:0] nonce_out_d, nonce_out_q; - - always_comb begin : p_outregs - key_out_d = key_out_q; - nonce_out_d = nonce_out_q; - seed_valid_d = seed_valid_q; - if (key_reg_en) begin - key_out_d[seed_cnt[1]] = scrmbl_data_i; - end - if (nonce_reg_en) begin - nonce_out_d[entropy_cnt[$clog2(NumNonceChunks)-1:0]] = edn_data_i; - end - if (seed_valid_reg_en) begin - seed_valid_d = req_bundle.seed_valid; - end - end - - // Connect keys/nonce outputs to output regs. - prim_sec_anchor_flop #( - .Width(ScrmblKeyWidth), - .ResetValue(RndCnstScrmblKeyInit.key) - ) u_key_out_anchor ( - .clk_i, - .rst_ni, - .d_i(key_out_d), - .q_o(key_out_q) - ); - - assign otbn_otp_key_o.key = key_out_q; - assign otbn_otp_key_o.nonce = nonce_out_q[OtbnNonceSel-1:0]; - assign otbn_otp_key_o.seed_valid = seed_valid_q; - - assign flash_otp_key_o.key = key_out_q; - assign flash_otp_key_o.rand_key = nonce_out_q[FlashNonceSel-1:0]; - assign flash_otp_key_o.seed_valid = seed_valid_q; - - for (genvar k = 0; k < NumSramKeyReqSlots; k++) begin : gen_out_assign - assign sram_otp_key_o[k].key = key_out_q; - assign sram_otp_key_o[k].nonce = nonce_out_q[SramNonceSel-1:0]; - assign sram_otp_key_o[k].seed_valid = seed_valid_q; - end - - typedef enum logic { - SeedData, - EntropyData - } data_sel_e; - - // Select correct 64bit block. - data_sel_e data_sel; - assign scrmbl_data_o = (data_sel == EntropyData) ? nonce_out_q[entropy_cnt[0]] : - // Gate seed value to '0 if invalid. - (req_bundle.seed_valid) ? req_bundle.seed[seed_cnt] : '0; - - ///////////////// - // Control FSM // - ///////////////// - - // SEC_CM: KDI.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 11 -n 10 \ - // -s 2544133835 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (54.55%) - // 6: |||||||||||||||| (45.45%) - // 7: -- - // 8: -- - // 9: -- - // 10: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 3 - // Maximum Hamming weight: 9 - // - localparam int StateWidth = 10; - typedef enum logic [StateWidth-1:0] { - ResetSt = 10'b0101100001, - IdleSt = 10'b0001011011, - DigClrSt = 10'b1101010110, - DigLoadSt = 10'b0010110111, - FetchEntropySt = 10'b1000001101, - DigEntropySt = 10'b0100111100, - DigFinSt = 10'b1000100010, - DigWaitSt = 10'b1110010001, - FetchNonceSt = 10'b0011000100, - FinishSt = 10'b1011111000, - ErrorSt = 10'b1111101111 - } state_e; - - state_e state_d, state_q; - logic edn_req_d, edn_req_q; - assign edn_req_o = edn_req_q; - - always_comb begin : p_fsm - state_d = state_q; - - // FSM Error output - fsm_err_o = 1'b0; - - // Counters - seed_cnt_en = 1'b0; - seed_cnt_clr = 1'b0; - entropy_cnt_en = 1'b0; - entropy_cnt_clr = 1'b0; - - // EDN 128bit block fetch request. - // This keeps the request alive until it has - // been acked to adhere to the req/ack protocol - // even in cases where the FSM jumps into - // an error state while waiting for a request. - edn_req_d = edn_req_q & ~edn_ack_i; - - // Data selection and temp registers - data_sel = SeedData; - key_reg_en = 1'b0; - nonce_reg_en = 1'b0; - seed_valid_reg_en = 1'b0; - - // Scrambling datapath - scrmbl_mtx_req_o = 1'b0; - scrmbl_sel_o = req_bundle.digest_sel; - scrmbl_cmd_o = LoadShadow; - scrmbl_mode_o = StandardMode; - - scrmbl_valid_o = 1'b0; - - // Request acknowledgement - req_ready = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // State right after reset. Wait here until KDI gets enabled. - ResetSt: begin - if (kdi_en_i) begin - state_d = IdleSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for a request, then go and acquire the mutex. - IdleSt: begin - if (req_valid) begin - state_d = DigClrSt; - seed_cnt_clr = 1'b1; - entropy_cnt_clr = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // First, acquire the mutex for the digest and clear the digest state. - DigClrSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - // Need to reset the digest state and set digest mode to "standard". - scrmbl_cmd_o = DigestInit; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = DigLoadSt; - end - end - /////////////////////////////////////////////////////////////////// - // Load two 64bit blocks of the seed, and trigger digest calculation. - DigLoadSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - // Trigger digest round in case this is the second block in a row. - if (seed_cnt[0]) begin - scrmbl_cmd_o = Digest; - if (scrmbl_ready_i) begin - // Go and ingest a block of entropy if required. - if (req_bundle.ingest_entropy) begin - state_d = FetchEntropySt; - // Otherwise go to digest finalization state. - end else begin - state_d = DigFinSt; - end - end - // Just load first 64bit block and stay here. - end else if (scrmbl_ready_i) begin - seed_cnt_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Fetch random data to ingest for key derivation. - FetchEntropySt: begin - scrmbl_mtx_req_o = 1'b1; - edn_req_d = 1'b1; - if (edn_ack_i) begin - nonce_reg_en = 1'b1; - // Finished, go and acknowledge this request. - if (entropy_cnt == 2'h1) begin - state_d = DigEntropySt; - entropy_cnt_clr = 1'b1; - // Keep on requesting entropy. - end else begin - entropy_cnt_en = 1'b1; - end - end - end - /////////////////////////////////////////////////////////////////// - // Load two 64bit blocks of entropy data. - DigEntropySt: begin - scrmbl_mtx_req_o = 1'b1; - data_sel = EntropyData; - scrmbl_valid_o = 1'b1; - // Trigger digest round in case this is the second block in a row, - // and go to digest finalization. - if (entropy_cnt[0]) begin - scrmbl_cmd_o = Digest; - if (scrmbl_ready_i) begin - state_d = DigFinSt; - entropy_cnt_clr = 1'b1; - end - // Just load first 64bit block and stay here. - end else if (scrmbl_ready_i) begin - entropy_cnt_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Trigger digest finalization and go wait for the result. - DigFinSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = DigestFinalize; - if (scrmbl_ready_i) begin - state_d = DigWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the digest to return, and write the result to the key - // output register. Go back and process the second part of the - // input seed if needed. - DigWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - if (scrmbl_valid_i) begin - key_reg_en = 1'b1; - // Not finished yet, need to go back and produce second 64bit block. - if (seed_cnt == 2'h1) begin - seed_cnt_en = 1'b1; - // In this case the previous digest state is kept, - // which leads to a chained digest. - if (req_bundle.chained_digest) begin - state_d = DigLoadSt; - // In this case we revert the digest state to the netlist IV. - end else begin - state_d = DigClrSt; - end - // This was the second 64bit output block. - end else begin - seed_cnt_clr = 1'b1; - // Make sure we output the status of the key seed in OTP. - seed_valid_reg_en = 1'b1; - // Check whether we need to fetch additional nonce data. - if (req_bundle.fetch_nonce) begin - state_d = FetchNonceSt; - end else begin - // Finished, go and acknowledge this request. - state_d = FinishSt; - end - end - end - end - /////////////////////////////////////////////////////////////////// - // Fetch additional nonce data. Note that the mutex is released in - // this state. - FetchNonceSt: begin - edn_req_d = 1'b1; - if (edn_ack_i) begin - nonce_reg_en = 1'b1; - // Finished, go and acknowledge this request. - if (entropy_cnt == req_bundle.nonce_size) begin - state_d = FinishSt; - entropy_cnt_clr = 1'b1; - // Keep on requesting entropy. - end else begin - entropy_cnt_en = 1'b1; - end - end - end - /////////////////////////////////////////////////////////////////// - // Acknowledge request and go back to IdleSt. - FinishSt: begin - state_d = IdleSt; - req_ready = 1'b1; - end - /////////////////////////////////////////////////////////////////// - // Terminal error state. This raises an alert. - ErrorSt: begin - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - // This should never happen, hence we directly jump into the - // error state, where an alert will be triggered. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of escalation. - // SEC_CM: KDI.FSM.LOCAL_ESC, KDI.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || - seed_cnt_err || entropy_cnt_err) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - end - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - nonce_out_q <= RndCnstScrmblKeyInit.nonce; - seed_valid_q <= 1'b0; - edn_req_q <= 1'b0; - end else begin - nonce_out_q <= nonce_out_d; - seed_valid_q <= seed_valid_d; - edn_req_q <= edn_req_d; - end - end - - //////////////// - // Assertions // - //////////////// - - `ASSERT_KNOWN(FsmErrKnown_A, fsm_err_o) - `ASSERT_KNOWN(EdnReqKnown_A, edn_req_o) - `ASSERT_KNOWN(FlashOtpKeyRspKnown_A, flash_otp_key_o) - `ASSERT_KNOWN(SramOtpKeyRspKnown_A, sram_otp_key_o) - `ASSERT_KNOWN(OtbnOtpKeyRspKnown_A, otbn_otp_key_o) - `ASSERT_KNOWN(ScrmblMtxReqKnown_A, scrmbl_mtx_req_o) - `ASSERT_KNOWN(ScrmblCmdKnown_A, scrmbl_cmd_o) - `ASSERT_KNOWN(ScrmblModeKnown_A, scrmbl_mode_o) - `ASSERT_KNOWN(ScrmblSelKnown_A, scrmbl_sel_o) - `ASSERT_KNOWN(ScrmblDataKnown_A, scrmbl_data_o) - `ASSERT_KNOWN(ScrmblValidKnown_A, scrmbl_valid_o) - -endmodule : otp_ctrl_kdi diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv deleted file mode 100644 index 122675069d059..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Life cycle interface for performing life cycle transitions in OTP. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_lci - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -#( - // Lifecycle partition information - parameter part_info_t Info = PartInfoDefault -) ( - input clk_i, - input rst_ni, - input lci_en_i, - // Escalation input. This moves the FSM into a terminal state and locks down - // the partition. - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - // Life cycle transition request. In order to perform a state transition, - // the LC controller signals the new count and state. The OTP wrapper then - // only programs bits that have not been programmed before. - // Note that a transition request will fail if the request attempts to - // clear already programmed bits within OTP. - input lc_req_i, - input logic [Info.size*8-1:0] lc_data_i, - output logic lc_ack_o, - output logic lc_err_o, - // Output error state of partition, to be consumed by OTP error/alert logic. - // Note that most errors are not recoverable and move the partition FSM into - // a terminal error state. - output otp_err_e error_o, - // This error signal is pulsed high if the FSM has been glitched into an invalid state. - // Although it is somewhat redundant with the error code in error_o above, it is - // meant to cover cases where we already latched an error code while the FSM is - // glitched into an invalid state (since in that case, the error code will not be - // overridden with the FSM error code so that the original error code is still - // discoverable). - output logic fsm_err_o, - output logic lci_prog_idle_o, - // OTP interface - output logic otp_req_o, - output prim_otp_pkg::cmd_e otp_cmd_o, - output logic [OtpSizeWidth-1:0] otp_size_o, - output logic [OtpIfWidth-1:0] otp_wdata_o, - output logic [OtpAddrWidth-1:0] otp_addr_o, - input otp_gnt_i, - input otp_rvalid_i, - input [ScrmblBlockWidth-1:0] otp_rdata_i, - input prim_otp_pkg::err_e otp_err_i -); - - //////////////////////// - // Integration Checks // - //////////////////////// - - import prim_util_pkg::vbits; - - localparam int NumLcOtpWords = int'(Info.size) >> OtpAddrShift; - localparam int CntWidth = vbits(NumLcOtpWords); - - localparam int unsigned LastLcOtpWordInt = NumLcOtpWords - 1; - localparam bit [CntWidth-1:0] LastLcOtpWord = LastLcOtpWordInt[CntWidth-1:0]; - - // This is required, since each native OTP word can only be programmed once. - `ASSERT_INIT(LcValueMustBeWiderThanNativeOtpWidth_A, lc_ctrl_state_pkg::LcValueWidth >= OtpWidth) - - //////////////////// - // Controller FSM // - //////////////////// - - // SEC_CM: LCI.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 5 -n 9 \ - // -s 558234734 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (60.00%) - // 6: ||||||||||||| (40.00%) - // 7: -- - // 8: -- - // 9: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 1 - // Maximum Hamming weight: 7 - // - localparam int StateWidth = 9; - typedef enum logic [StateWidth-1:0] { - ResetSt = 9'b000101011, - IdleSt = 9'b110011110, - WriteSt = 9'b101010001, - WriteWaitSt = 9'b010000000, - ErrorSt = 9'b011111101 - } state_e; - - state_e state_d, state_q; - logic cnt_clr, cnt_en, cnt_err; - logic [CntWidth-1:0] cnt; - otp_err_e error_d, error_q; - - // Output LCI errors - assign error_o = error_q; - - always_comb begin : p_fsm - state_d = state_q; - - // Counter - cnt_en = 1'b0; - cnt_clr = 1'b0; - - // Idle status - lci_prog_idle_o = 1'b1; - - // OTP signals - otp_req_o = 1'b0; - otp_cmd_o = prim_otp_pkg::Read; - - // Response to LC controller - lc_err_o = 1'b0; - lc_ack_o = 1'b0; - - // Error Register - error_d = error_q; - fsm_err_o = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // State right after reset. Wait here until LCI gets enabled. - ResetSt: begin - lci_prog_idle_o = 1'b0; - if (lci_en_i) begin - state_d = IdleSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for a request from the life cycle controller - IdleSt: begin - if (lc_req_i) begin - state_d = WriteSt; - cnt_clr = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Loop through the lifecycle sate and burn in all words. - // If the write data contains a 0 bit in a position where a bit has already been - // programmed to 1 before, the OTP errors out. - WriteSt: begin - otp_req_o = 1'b1; - otp_cmd_o = prim_otp_pkg::Write; - lci_prog_idle_o = 1'b0; - if (otp_gnt_i) begin - state_d = WriteWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response, and check whether there are more words to burn in. - // In case an OTP transaction fails, latch the OTP error code, and jump to - // terminal error state. - WriteWaitSt: begin - lci_prog_idle_o = 1'b0; - if (otp_rvalid_i) begin - // Check OTP return code. - // Note that if errors occur, we aggregate the error code - // but still attempt to program all remaining words. - // This is done to ensure that a life cycle state with - // ECC correctable errors in some words can still be scrapped. - if (otp_err_e'(otp_err_i) != NoError) begin - error_d = otp_err_e'(otp_err_i); - end - - // Check whether we programmed all OTP words. - // If yes, we are done and can go back to idle. - if (cnt == LastLcOtpWord) begin - state_d = IdleSt; - lc_ack_o = 1'b1; - // If in any of the words a programming error has occurred, - // we signal that accordingly and go to the error state. - if (error_d != NoError) begin - lc_err_o = 1'b1; - state_d = ErrorSt; - end - // Otherwise we increase the OTP word counter. - end else begin - state_d = WriteSt; - cnt_en = 1'b1; - end - end - end - /////////////////////////////////////////////////////////////////// - // Terminal Error State. This locks access to the partition. - // Make sure the partition signals an error state if no error - // code has been latched so far, and lock the buffer regs down. - ErrorSt: begin - if (error_q == NoError) begin - error_d = FsmStateError; - end - end - /////////////////////////////////////////////////////////////////// - // We should never get here. If we do (e.g. via a malicious - // glitch), error out immediately. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of escalation. - // SEC_CM: LCI.FSM.LOCAL_ESC, LCI.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - if (error_q == NoError) begin - error_d = FsmStateError; - end - end - - end - - ////////////////////////////// - // Counter and address calc // - ////////////////////////////// - - // Native OTP word counter - // SEC_CM: LCI.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count ( - .clk_i, - .rst_ni, - .clr_i(cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(cnt), - .cnt_after_commit_o(), - .err_o(cnt_err) - ); - - // The output address is "offset + count", but we have to convert Info.offset from a byte address - // to a halfword (16-bit) address by discarding the bottom OtpAddrShift bits. We also make the - // zero-extension of cnt explicit (to avoid width mismatch warnings). - assign otp_addr_o = Info.offset[OtpByteAddrWidth-1:OtpAddrShift] + OtpAddrWidth'(cnt); - - // Always transfer 16bit blocks. - assign otp_size_o = '0; - - logic [NumLcOtpWords-1:0][OtpWidth-1:0] data; - assign data = lc_data_i; - assign otp_wdata_o = (otp_req_o) ? OtpIfWidth'(data[cnt]) : '0; - - logic unused_rdata; - assign unused_rdata = ^otp_rdata_i; - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - error_q <= NoError; - end else begin - error_q <= error_d; - end - end - - //////////////// - // Assertions // - //////////////// - - `ASSERT_KNOWN(LcAckKnown_A, lc_ack_o) - `ASSERT_KNOWN(LcErrKnown_A, lc_err_o) - `ASSERT_KNOWN(ErrorKnown_A, error_o) - `ASSERT_KNOWN(LciIdleKnown_A, lci_prog_idle_o) - `ASSERT_KNOWN(OtpReqKnown_A, otp_req_o) - `ASSERT_KNOWN(OtpCmdKnown_A, otp_cmd_o) - `ASSERT_KNOWN(OtpSizeKnown_A, otp_size_o) - `ASSERT_KNOWN(OtpWdataKnown_A, otp_wdata_o) - `ASSERT_KNOWN(OtpAddrKnown_A, otp_addr_o) - -endmodule : otp_ctrl_lci diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv deleted file mode 100644 index 22b3ec383a89c..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// This module implements the LFSR timer for triggering periodic consistency and integrity checks in -// OTP. In particular, this module contains two 40bit counters (one for the consistency and one -// for the integrity checks) and a 40bit LFSR to draw pseudo random wait counts. -// -// The integ_period_msk_i and cnsty_period_msk_i mask signals are used to mask off the LFSR outputs -// and hence determine the maximum wait count that can be drawn. If these values are set to -// zero, the corresponding timer is disabled. -// -// Once a particular check timer has expired, the module will send out a check request to all -// partitions and wait for an acknowledgment. If a particular partition encounters an integrity or -// consistency mismatch, this will be directly reported via the error and alert logic. -// -// In order to guard against wedged partition controllers or arbitration lock ups due to tampering -// attempts, this check timer module also supports a 32bit timeout that can optionally be -// programmed. If a particular check times out, chk_timeout_o will be asserted, which will raise -// an alert via the error logic. -// -// The EntropyWidth LSBs of the LFSR are reseeded with fresh entropy from EDN once -// LfsrUsageThreshold values have been drawn from the LFSR. -// -// It is also possible to trigger one-off checks via integ_chk_trig_i and cnsty_chk_trig_i. -// This can be useful if SW chooses to leave the periodic checks disabled. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_lfsr_timer - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; -#( - // Compile time random constants, to be overriden by topgen. - parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, - parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault -) ( - input clk_i, - input rst_ni, - output logic edn_req_o, // request to EDN - input edn_ack_i, // ack from EDN - input [EdnDataWidth-1:0] edn_data_i, // from EDN - input timer_en_i, // enable timer - input otp_prog_busy_i, // indicates whether prog ops are in progress - input integ_chk_trig_i, // one-off trigger for integrity check - input cnsty_chk_trig_i, // one-off trigger for consistency check - output logic chk_pending_o, // indicates whether there are pending checks - input [31:0] timeout_i, // check timeout - input [31:0] integ_period_msk_i, // maximum integrity check mask - input [31:0] cnsty_period_msk_i, // maximum consistency check mask - output logic [NumPart-1:0] integ_chk_req_o, // request to all partitions - output logic [NumPart-1:0] cnsty_chk_req_o, // request to all partitions - input [NumPart-1:0] integ_chk_ack_i, // response from partitions - input [NumPart-1:0] cnsty_chk_ack_i, // response from partitions - input lc_ctrl_pkg::lc_tx_t escalate_en_i, // escalation input, moves FSM into ErrorSt - output logic chk_timeout_o, // a check has timed out - output logic fsm_err_o // the FSM has reached an invalid state -); - - //////////////////// - // Reseed counter // - //////////////////// - - // Count how many times the LFSR has been used to generate a value. - // Once we've reached the limit, we request new entropy from EDN to reseed - // the LFSR. Note that this is not a blocking operation for the timer below. - // I.e., the timer is allowed to continue its operation, and may draw more - // values, even if the EDN reseed request is still in progress. - logic reseed_en, lfsr_en; - logic [$clog2(LfsrUsageThreshold+1)-1:0] reseed_cnt_d, reseed_cnt_q; - assign reseed_cnt_d = (reseed_en) ? '0 : - (edn_req_o) ? reseed_cnt_q : - (lfsr_en) ? reseed_cnt_q + 1'b1 : - reseed_cnt_q; - - assign edn_req_o = (reseed_cnt_q >= LfsrUsageThreshold); - assign reseed_en = edn_req_o & edn_ack_i; - - /////////////////////////// - // Tandem LFSR Instances // - /////////////////////////// - - logic lfsr_err; - logic [LfsrWidth-1:0] entropy; - logic [LfsrWidth-1:0] lfsr_state; - assign entropy = (reseed_en) ? edn_data_i[LfsrWidth-1:0] : '0; - - // We employ two redundant LFSRs to guard against FI attacks. - // If any of the two is glitched and the two LFSR states do not agree, - // the FSM below is moved into a terminal error state. - // SEC_CM: TIMER.LFSR.REDUN - prim_double_lfsr #( - .LfsrDw ( LfsrWidth ), - .EntropyDw ( LfsrWidth ), - .StateOutDw ( LfsrWidth ), - .DefaultSeed ( RndCnstLfsrSeed ), - .StatePermEn ( 1'b1 ), - .StatePerm ( RndCnstLfsrPerm ), - .ExtSeedSVA ( 1'b0 ) - ) u_prim_double_lfsr ( - .clk_i, - .rst_ni, - .seed_en_i ( 1'b0 ), - .seed_i ( '0 ), - .lfsr_en_i ( reseed_en || lfsr_en ), - .entropy_i ( entropy ), - .state_o ( lfsr_state ), - .err_o ( lfsr_err ) - ); - - // Not all entropy bits are used. - logic unused_seed; - assign unused_seed = ^edn_data_i; - - `ASSERT_INIT(EdnIsWideEnough_A, EdnDataWidth >= LfsrWidth) - - ////////////////////////////// - // Tandem Counter Instances // - ////////////////////////////// - - // We employ redundant counters to guard against FI attacks. - // If any of them is glitched and the redundant counter states do not agree, - // the FSM below is moved into a terminal error state. - logic [LfsrWidth-1:0] integ_cnt, cnsty_cnt, integ_cnt_set_val, cnsty_cnt_set_val; - logic [LfsrWidth-1:0] integ_mask, cnsty_mask; - logic integ_set_period, integ_set_timeout, integ_cnt_zero; - logic cnsty_set_period, cnsty_set_timeout, cnsty_cnt_zero; - logic integ_cnt_set, cnsty_cnt_set, integ_cnt_err, cnsty_cnt_err; - logic timeout_zero, integ_msk_zero, cnsty_msk_zero, cnsty_cnt_pause; - - assign timeout_zero = (timeout_i == '0); - assign integ_msk_zero = (integ_period_msk_i == '0); - assign cnsty_msk_zero = (cnsty_period_msk_i == '0); - assign integ_cnt_zero = (integ_cnt == '0); - assign cnsty_cnt_zero = (cnsty_cnt == '0); - - assign integ_cnt_set = integ_set_period || integ_set_timeout; - assign cnsty_cnt_set = cnsty_set_period || cnsty_set_timeout; - - assign integ_mask = {integ_period_msk_i, {LfsrWidth-32{1'b1}}}; - assign cnsty_mask = {cnsty_period_msk_i, {LfsrWidth-32{1'b1}}}; - assign integ_cnt_set_val = (integ_set_period) ? (lfsr_state & integ_mask) : LfsrWidth'(timeout_i); - assign cnsty_cnt_set_val = (cnsty_set_period) ? (lfsr_state & cnsty_mask) : LfsrWidth'(timeout_i); - - // SEC_CM: TIMER_INTEG.CTR.REDUN - prim_count #( - .Width(LfsrWidth) - ) u_prim_count_integ ( - .clk_i, - .rst_ni, - .clr_i(1'b0), - .set_i(integ_cnt_set), - .set_cnt_i(integ_cnt_set_val), - .incr_en_i(1'b0), - .decr_en_i(!integ_cnt_zero), - .step_i(LfsrWidth'(1)), - .commit_i(1'b1), - .cnt_o(integ_cnt), - .cnt_after_commit_o(), - .err_o(integ_cnt_err) - ); - - // SEC_CM: TIMER_CNSTY.CTR.REDUN - prim_count #( - .Width(LfsrWidth) - ) u_prim_count_cnsty ( - .clk_i, - .rst_ni, - .clr_i(1'b0), - .set_i(cnsty_cnt_set), - .set_cnt_i(cnsty_cnt_set_val), - .incr_en_i(1'b0), - .decr_en_i(!cnsty_cnt_zero && !cnsty_cnt_pause), - .step_i(LfsrWidth'(1)), - .commit_i(1'b1), - .cnt_o(cnsty_cnt), - .cnt_after_commit_o(), - .err_o(cnsty_cnt_err) - ); - - ///////////////////// - // Request signals // - ///////////////////// - - logic set_all_integ_reqs, set_all_cnsty_reqs; - logic [NumPart-1:0] integ_chk_req_d, integ_chk_req_q; - logic [NumPart-1:0] cnsty_chk_req_d, cnsty_chk_req_q; - assign integ_chk_req_o = integ_chk_req_q; - assign cnsty_chk_req_o = cnsty_chk_req_q; - assign integ_chk_req_d = (set_all_integ_reqs) ? {NumPart{1'b1}} : - integ_chk_req_q & ~integ_chk_ack_i; - assign cnsty_chk_req_d = (set_all_cnsty_reqs) ? {NumPart{1'b1}} : - cnsty_chk_req_q & ~cnsty_chk_ack_i; - - - // external triggers - logic clr_integ_chk_trig, clr_cnsty_chk_trig; - logic integ_chk_trig_d, integ_chk_trig_q; - logic cnsty_chk_trig_d, cnsty_chk_trig_q; - assign integ_chk_trig_d = (integ_chk_trig_q & ~clr_integ_chk_trig) | integ_chk_trig_i; - assign cnsty_chk_trig_d = (cnsty_chk_trig_q & ~clr_cnsty_chk_trig) | cnsty_chk_trig_i; - - //////////////////////////// - // Ping and Timeout Logic // - //////////////////////////// - - // SEC_CM: TIMER.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 5 -n 9 \ - // -s 628816752 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (60.00%) - // 6: ||||||||||||| (40.00%) - // 7: -- - // 8: -- - // 9: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 4 - // Maximum Hamming weight: 6 - // - localparam int StateWidth = 9; - typedef enum logic [StateWidth-1:0] { - ResetSt = 9'b100100101, - IdleSt = 9'b001101110, - IntegWaitSt = 9'b010110011, - CnstyWaitSt = 9'b111010110, - ErrorSt = 9'b001011001 - } state_e; - - state_e state_d, state_q; - logic chk_timeout_d, chk_timeout_q; - - assign chk_timeout_o = chk_timeout_q; - - always_comb begin : p_fsm - state_d = state_q; - - // LFSR and counter signals - lfsr_en = 1'b0; - integ_set_period = 1'b0; - cnsty_set_period = 1'b0; - integ_set_timeout = 1'b0; - cnsty_set_timeout = 1'b0; - cnsty_cnt_pause = 1'b0; - - // Requests going to partitions. - set_all_integ_reqs = '0; - set_all_cnsty_reqs = '0; - - // Status signals going to CSRs and error logic. - chk_timeout_d = chk_timeout_q; - chk_pending_o = cnsty_chk_trig_q || integ_chk_trig_q; - fsm_err_o = 1'b0; - - // Clear signals for external triggers - clr_integ_chk_trig = 1'b0; - clr_cnsty_chk_trig = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // Wait until enabled. We never return to this state - // once enabled! - ResetSt: begin - if (timer_en_i) begin - state_d = IdleSt; - lfsr_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait here until one of the two timers expires (if enabled) or if - // a check is triggered externally. - IdleSt: begin - if ((!integ_msk_zero && integ_cnt_zero) || integ_chk_trig_q) begin - state_d = IntegWaitSt; - integ_set_timeout = 1'b1; - set_all_integ_reqs = 1'b1; - clr_integ_chk_trig = integ_chk_trig_q; - end else if ((!cnsty_msk_zero && cnsty_cnt_zero) || cnsty_chk_trig_q) begin - state_d = CnstyWaitSt; - cnsty_set_timeout = 1'b1; - set_all_cnsty_reqs = 1'b1; - clr_cnsty_chk_trig = cnsty_chk_trig_q; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for all the partitions to respond and go back to idle. - // If the timeout is enabled, bail out into terminal error state - // if the timeout counter expires (this will raise an alert). - IntegWaitSt: begin - chk_pending_o = 1'b1; - if (!timeout_zero && integ_cnt_zero) begin - state_d = ErrorSt; - chk_timeout_d = 1'b1; - end else if (integ_chk_req_q == '0) begin - state_d = IdleSt; - // This draws the next wait period. - integ_set_period = 1'b1; - lfsr_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for all the partitions to respond and go back to idle. - // If the timeout is enabled, bail out into terminal error state - // if the timeout counter expires (this will raise an alert). - CnstyWaitSt: begin - chk_pending_o = 1'b1; - // Note that consistency checks go back and read from OTP. Hence, - // life cycle transitions and DAI programming operations - // may interfere with these checks and cause them to take longer - // than typically expected. Therefore, the timeout counter is stopped - // during programming operations. - cnsty_cnt_pause = otp_prog_busy_i; - if (!timeout_zero && cnsty_cnt_zero) begin - state_d = ErrorSt; - chk_timeout_d = 1'b1; - end else if (cnsty_chk_req_q == '0) begin - state_d = IdleSt; - // This draws the next wait period. - cnsty_set_period = 1'b1; - lfsr_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Terminal error state. This raises an alert. - ErrorSt: begin - // Continuously clear pending checks. - clr_integ_chk_trig = 1'b1; - clr_cnsty_chk_trig = 1'b1; - if (!chk_timeout_q) begin - fsm_err_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // This should never happen, hence we directly jump into the - // error state, where an alert will be triggered. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of escalation, - // or if the two LFSR or counter states do not agree. - // SEC_CM: TIMER.FSM.LOCAL_ESC, TIMER.FSM.GLOBAL_ESC - if (lfsr_err || integ_cnt_err || cnsty_cnt_err || - lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i)) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - end - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - integ_chk_req_q <= '0; - cnsty_chk_req_q <= '0; - chk_timeout_q <= 1'b0; - reseed_cnt_q <= '0; - integ_chk_trig_q <= 1'b0; - cnsty_chk_trig_q <= 1'b0; - end else begin - integ_chk_req_q <= integ_chk_req_d; - cnsty_chk_req_q <= cnsty_chk_req_d; - chk_timeout_q <= chk_timeout_d; - reseed_cnt_q <= reseed_cnt_d; - integ_chk_trig_q <= integ_chk_trig_d; - cnsty_chk_trig_q <= cnsty_chk_trig_d; - end - end - - //////////////// - // Assertions // - //////////////// - - `ASSERT_KNOWN(EdnReqKnown_A, edn_req_o) - `ASSERT_KNOWN(ChkPendingKnown_A, chk_pending_o) - `ASSERT_KNOWN(IntegChkReqKnown_A, integ_chk_req_o) - `ASSERT_KNOWN(CnstyChkReqKnown_A, cnsty_chk_req_o) - `ASSERT_KNOWN(ChkTimeoutKnown_A, chk_timeout_o) - -endmodule : otp_ctrl_lfsr_timer diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv deleted file mode 100644 index 27f6fc67d482d..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv +++ /dev/null @@ -1,821 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Buffered partition for OTP controller. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_part_buf - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -#( - // Partition information. - parameter part_info_t Info = PartInfoDefault, - parameter logic [Info.size*8-1:0] DataDefault = '0 -) ( - input clk_i, - input rst_ni, - // Pulse to start partition initialisation (required once per power cycle). - input init_req_i, - output logic init_done_o, - // Integrity check requests - input integ_chk_req_i, - output logic integ_chk_ack_o, - // Consistency check requests - input cnsty_chk_req_i, - output logic cnsty_chk_ack_o, - // Escalation input. This moves the FSM into a terminal state and locks down - // the partition. - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - // Check bypass enable. This bypasses integrity and consistency checks and - // acknowledges all incoming check requests (only used by life cycle). - input lc_ctrl_pkg::lc_tx_t check_byp_en_i, - // Output error state of partition, to be consumed by OTP error/alert logic. - // Note that most errors are not recoverable and move the partition FSM into - // a terminal error state. - output otp_err_e error_o, - // This error signal is pulsed high if the FSM has been glitched into an invalid state. - // Although it is somewhat redundant with the error code in error_o above, it is - // meant to cover cases where we already latched an error code while the FSM is - // glitched into an invalid state (since in that case, the error code will not be - // overridden with the FSM error code so that the original error code is still - // discoverable). - output logic fsm_err_o, - // Access/lock status - // SEC_CM: ACCESS.CTRL.MUBI - input part_access_t access_i, // runtime lock from CSRs - output part_access_t access_o, - // Buffered 64bit digest output. - output logic [ScrmblBlockWidth-1:0] digest_o, - output logic [Info.size*8-1:0] data_o, - // OTP interface - output logic otp_req_o, - output prim_otp_pkg::cmd_e otp_cmd_o, - output logic [OtpSizeWidth-1:0] otp_size_o, - output logic [OtpIfWidth-1:0] otp_wdata_o, - output logic [OtpAddrWidth-1:0] otp_addr_o, - input otp_gnt_i, - input otp_rvalid_i, - input [ScrmblBlockWidth-1:0] otp_rdata_i, - input prim_otp_pkg::err_e otp_err_i, - // Scrambling mutex request - output logic scrmbl_mtx_req_o, - input scrmbl_mtx_gnt_i, - // Scrambling datapath interface - output otp_scrmbl_cmd_e scrmbl_cmd_o, - output digest_mode_e scrmbl_mode_o, - output logic [ConstSelWidth-1:0] scrmbl_sel_o, - output logic [ScrmblBlockWidth-1:0] scrmbl_data_o, - output logic scrmbl_valid_o, - input logic scrmbl_ready_i, - input logic scrmbl_valid_i, - input logic [ScrmblBlockWidth-1:0] scrmbl_data_i -); - - //////////////////////// - // Integration Checks // - //////////////////////// - - import prim_mubi_pkg::*; - import prim_util_pkg::vbits; - - localparam int unsigned DigestOffsetInt = (int'(Info.offset) + - int'(Info.size) - ScrmblBlockWidth/8); - localparam int NumScrmblBlocks = int'(Info.size) / (ScrmblBlockWidth/8); - localparam int CntWidth = vbits(NumScrmblBlocks); - - localparam bit [OtpByteAddrWidth-1:0] DigestOffset = DigestOffsetInt[OtpByteAddrWidth-1:0]; - - localparam int unsigned LastScrmblBlockInt = NumScrmblBlocks - 1; - localparam int unsigned PenultimateScrmblBlockInt = NumScrmblBlocks - 2; - localparam bit [CntWidth-1:0] LastScrmblBlock = LastScrmblBlockInt[CntWidth-1:0]; - localparam bit [CntWidth-1:0] PenultimateScrmblBlock = PenultimateScrmblBlockInt[CntWidth-1:0]; - - // Integration checks for parameters. - `ASSERT_INIT(OffsetMustBeBlockAligned_A, (Info.offset % (ScrmblBlockWidth/8)) == 0) - `ASSERT_INIT(SizeMustBeBlockAligned_A, (Info.size % (ScrmblBlockWidth/8)) == 0) - `ASSERT_INIT(DigestOffsetMustBeRepresentable_A, DigestOffsetInt == int'(DigestOffset)) - `ASSERT(ScrambledImpliesDigest_A, Info.secret |-> Info.hw_digest) - `ASSERT(WriteLockImpliesDigest_A, Info.read_lock |-> Info.hw_digest) - `ASSERT(ReadLockImpliesDigest_A, Info.write_lock |-> Info.hw_digest) - - // This feature is only supposed to be used with partitions that are not scrambled - // and that do not have a digest. - `ASSERT(BypassEnable0_A, Info.secret |-> lc_ctrl_pkg::lc_tx_test_false_strict(check_byp_en_i)) - `ASSERT(BypassEnable1_A, Info.hw_digest |-> lc_ctrl_pkg::lc_tx_test_false_strict(check_byp_en_i)) - - /////////////////////// - // OTP Partition FSM // - /////////////////////// - - // SEC_CM: PART.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 16 -n 12 \ - // -s 3370657881 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||| (28.33%) - // 6: |||||||||||||||||||| (38.33%) - // 7: |||||||||| (19.17%) - // 8: ||| (5.83%) - // 9: || (4.17%) - // 10: | (2.50%) - // 11: (0.83%) - // 12: (0.83%) - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 12 - // Minimum Hamming weight: 4 - // Maximum Hamming weight: 8 - // - localparam int StateWidth = 12; - typedef enum logic [StateWidth-1:0] { - ResetSt = 12'b011000001110, - InitSt = 12'b110100100111, - InitWaitSt = 12'b001110110001, - InitDescrSt = 12'b110010000100, - InitDescrWaitSt = 12'b100110101000, - IdleSt = 12'b010101001101, - IntegScrSt = 12'b110101011010, - IntegScrWaitSt = 12'b100010011111, - IntegDigClrSt = 12'b101001000001, - IntegDigSt = 12'b011101100010, - IntegDigPadSt = 12'b001101010111, - IntegDigFinSt = 12'b011011100101, - IntegDigWaitSt = 12'b100011110010, - CnstyReadSt = 12'b000001101011, - CnstyReadWaitSt = 12'b101001111100, - ErrorSt = 12'b010110111110 - } state_e; - - typedef enum logic { - ScrmblData, - OtpData - } data_sel_e; - - typedef enum logic { - PartOffset, - DigOffset - } base_sel_e; - - state_e state_d, state_q; - otp_err_e error_d, error_q; - data_sel_e data_sel; - base_sel_e base_sel; - mubi8_t dout_locked_d, dout_locked_q; - logic [CntWidth-1:0] cnt; - logic cnt_en, cnt_clr, cnt_err; - logic ecc_err; - logic buffer_reg_en; - logic [ScrmblBlockWidth-1:0] data_mux; - - // Output partition error state. - assign error_o = error_q; - - // This partition cannot do any write accesses, hence we tie this - // constantly off. - assign otp_wdata_o = '0; - // Depending on the partition configuration, the wrapper is instructed to ignore integrity - // calculations and checks. To be on the safe side, the partition filters error responses at this - // point and does not report any integrity errors if integrity is disabled. - otp_err_e otp_err; - if (Info.integrity) begin : gen_integrity - assign otp_cmd_o = prim_otp_pkg::Read; - assign otp_err = otp_err_e'(otp_err_i); - end else begin : gen_no_integrity - assign otp_cmd_o = prim_otp_pkg::ReadRaw; - always_comb begin - if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin - otp_err = NoError; - end else begin - otp_err = otp_err_e'(otp_err_i); - end - end - end - - always_comb begin : p_fsm - state_d = state_q; - - // Redundantly encoded lock signal for buffer regs. - dout_locked_d = dout_locked_q; - - // OTP signals - otp_req_o = 1'b0; - - // Scrambling mutex - scrmbl_mtx_req_o = 1'b0; - - // Scrambling datapath - scrmbl_cmd_o = LoadShadow; - scrmbl_sel_o = CnstyDigest; - scrmbl_mode_o = StandardMode; - scrmbl_valid_o = 1'b0; - - // Counter - cnt_en = 1'b0; - cnt_clr = 1'b0; - base_sel = PartOffset; - - // Buffer register - buffer_reg_en = 1'b0; - data_sel = OtpData; - - // Error Register - error_d = error_q; - fsm_err_o = 1'b0; - - // Integrity/Consistency check responses - cnsty_chk_ack_o = 1'b0; - integ_chk_ack_o = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // State right after reset. Wait here until we get a an - // initialization request. - ResetSt: begin - if (init_req_i) begin - state_d = InitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Initialization reads out the digest only in unbuffered - // partitions. Wait here until the OTP request has been granted. - // And then wait until the OTP word comes back. - InitSt: begin - otp_req_o = 1'b1; - if (otp_gnt_i) begin - state_d = InitWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and write to buffer register, then go to - // descrambling state. In case an OTP transaction fails, latch the - // OTP error code and jump to a - // terminal error state. - InitWaitSt: begin - if (otp_rvalid_i) begin - buffer_reg_en = 1'b1; - if (otp_err inside {NoError, MacroEccCorrError}) begin - // Once we've read and descrambled the whole partition, we can go to integrity - // verification. Note that the last block is the digest value, which does not - // have to be descrambled. - if (cnt == LastScrmblBlock) begin - state_d = IntegDigClrSt; - // Only need to descramble if this is a scrambled partition. - // Otherwise, we can just go back to InitSt and read the next block. - end else if (Info.secret) begin - state_d = InitDescrSt; - end else begin - state_d = InitSt; - cnt_en = 1'b1; - end - // At this point the only error that we could have gotten are correctable ECC errors. - if (otp_err != NoError) begin - error_d = MacroEccCorrError; - end - end else begin - state_d = ErrorSt; - error_d = otp_err; - end - end - end - /////////////////////////////////////////////////////////////////// - // Descrambling state. This first acquires the scrambling - // datapath mutex. Note that once the mutex is acquired, we have - // exclusive access to the scrambling datapath until we release - // the mutex by deasserting scrmbl_mtx_req_o. - // SEC_CM: SECRET.MEM.SCRAMBLE - InitDescrSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Decrypt; - scrmbl_sel_o = Info.key_sel; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = InitDescrWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the descrambled data to return. Note that we release - // the mutex lock upon leaving this state. - // SEC_CM: SECRET.MEM.SCRAMBLE - InitDescrWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_sel_o = Info.key_sel; - data_sel = ScrmblData; - if (scrmbl_valid_i) begin - state_d = InitSt; - buffer_reg_en = 1'b1; - cnt_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Idle state. We basically wait for integrity and consistency check - // triggers in this state. - IdleSt: begin - if (integ_chk_req_i) begin - if (Info.hw_digest) begin - state_d = IntegDigClrSt; - // In case there is nothing to check we can just - // acknowledge the request right away, without going to the - // integrity check. - end else begin - integ_chk_ack_o = 1'b1; - end - end else if (cnsty_chk_req_i) begin - state_d = CnstyReadSt; - cnt_clr = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Read the digest. Wait here until the OTP request has been granted. - // And then wait until the OTP word comes back. - // SEC_CM: PART.DATA_REG.BKGN_CHK - CnstyReadSt: begin - otp_req_o = 1'b1; - // In case this partition has a hardware digest, we only have to read - // and compare the digest value. In that case we select the digest offset here. - // Otherwise we have to read and compare the whole partition, in which case we - // select the partition offset, which is the default assignment of base_sel. - if (Info.hw_digest) begin - base_sel = DigOffset; - end - if (otp_gnt_i) begin - state_d = CnstyReadWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and compare the digest. In case there is - // a mismatch, lock down the partition and go into the terminal error - // state. In case an OTP transaction fails, latch the OTP error code - // and jump to a terminal error state. - // SEC_CM: PART.DATA_REG.BKGN_CHK - CnstyReadWaitSt: begin - if (otp_rvalid_i) begin - if (otp_err inside {NoError, MacroEccCorrError}) begin - // Check whether we need to compare the digest or the full partition - // contents here. - if (Info.hw_digest) begin - // Note that we ignore this check if the digest is still blank. - if (digest_o == data_mux || digest_o == '0) begin - state_d = IdleSt; - cnsty_chk_ack_o = 1'b1; - // Error out and lock the partition if this check fails. - end else begin - state_d = ErrorSt; - error_d = CheckFailError; - // The check has finished and found an error. - cnsty_chk_ack_o = 1'b1; - end - end else begin - // Check whether the read data corresponds with the data buffered in regs. - // Note that this particular check can be bypassed in case a transition is ongoing. - if (scrmbl_data_o == data_mux || - lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin - // Can go back to idle and acknowledge the - // request if this is the last block. - if (cnt == LastScrmblBlock) begin - state_d = IdleSt; - cnsty_chk_ack_o = 1'b1; - // Need to go back and read out more blocks. - end else begin - state_d = CnstyReadSt; - cnt_en = 1'b1; - end - end else begin - state_d = ErrorSt; - error_d = CheckFailError; - // The check has finished and found an error. - cnsty_chk_ack_o = 1'b1; - end - end - // At this point the only error that we could have gotten are correctable ECC errors. - if (otp_err != NoError) begin - error_d = MacroEccCorrError; - end - end else begin - state_d = ErrorSt; - error_d = otp_err; - // The check has finished and found an error. - cnsty_chk_ack_o = 1'b1; - end - end - end - /////////////////////////////////////////////////////////////////// - // First, acquire the mutex for the digest and clear the digest state. - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegDigClrSt: begin - // Check whether this partition requires checking at all. - if (Info.hw_digest) begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - cnt_clr = 1'b1; - // Need to reset the digest state and set it to chained - // mode if this partition is scrambled. - scrmbl_cmd_o = DigestInit; - if (Info.secret) begin - scrmbl_mode_o = ChainedMode; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = IntegScrSt; - end - // If this partition is not scrambled, we can just directly - // jump to the digest state. - end else begin - scrmbl_mode_o = StandardMode; - if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin - state_d = IntegDigSt; - end - end - // Otherwise, if this partition is not digest protected, - // we can just go to idle, since there is nothing to check. - // Note that we do not come back to this state in case there is no - // digest, and hence it is safe to unlock the buffer regs at this point. - // This is the only way the buffer regs can get unlocked. - end else begin - state_d = IdleSt; - if (mubi8_test_true_strict(dout_locked_q)) begin - dout_locked_d = MuBi8False; - end - end - end - /////////////////////////////////////////////////////////////////// - // Scramble buffered data (which is held in plaintext form). - // This moves the previous scrambling result into the shadow reg - // for later use. - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegScrSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Encrypt; - scrmbl_sel_o = Info.key_sel; - if (scrmbl_ready_i) begin - state_d = IntegScrWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the scrambled data to return. - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegScrWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_sel_o = Info.key_sel; - if (scrmbl_valid_i) begin - state_d = IntegDigSt; - end - end - /////////////////////////////////////////////////////////////////// - // Push the word read into the scrambling datapath. The last - // block is repeated in case the number blocks in this partition - // is odd. - // SEC_CM: PART.MEM.DIGEST - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegDigSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - if (scrmbl_ready_i) begin - cnt_en = 1'b1; - // No need to digest the digest value itself - if (cnt == PenultimateScrmblBlock) begin - // Note that the digest operates on 128bit blocks since the data is fed in via the - // PRESENT key input. Therefore, we only trigger a digest update on every second - // 64bit block that is pushed into the scrambling datapath. - if (cnt[0]) begin - scrmbl_cmd_o = Digest; - state_d = IntegDigFinSt; - end else begin - state_d = IntegDigPadSt; - cnt_en = 1'b0; - end - end else begin - // Trigger digest round in case this is the second block in a row. - if (cnt[0]) begin - scrmbl_cmd_o = Digest; - end - // Go back and scramble the next data block if this is - // a scrambled partition. Otherwise just stay here. - if (Info.secret) begin - state_d = IntegScrSt; - end - end - end - end - /////////////////////////////////////////////////////////////////// - // Padding state. When we get here, we've copied the last encryption - // result into the shadow register such that we've effectively - // repeated the last block twice in order to pad the data to 128bit. - // SEC_CM: PART.MEM.DIGEST - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegDigPadSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = Digest; - if (scrmbl_ready_i) begin - state_d = IntegDigFinSt; - end - end - /////////////////////////////////////////////////////////////////// - // Trigger digest finalization and go wait for the result. - // SEC_CM: PART.MEM.DIGEST - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegDigFinSt: begin - scrmbl_mtx_req_o = 1'b1; - scrmbl_valid_o = 1'b1; - scrmbl_cmd_o = DigestFinalize; - if (scrmbl_ready_i) begin - state_d = IntegDigWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for the digest to return, and double check whether the digest - // matches. If yes, unlock the partition. Otherwise, go into the terminal - // error state, where the partition will be locked down. - // SEC_CM: PART.MEM.DIGEST - // SEC_CM: PART.DATA_REG.BKGN_CHK - IntegDigWaitSt: begin - scrmbl_mtx_req_o = 1'b1; - data_sel = ScrmblData; - if (scrmbl_valid_i) begin - // This is the only way the buffer regs can get unlocked. - // Note that we ignore this check if the digest is still blank. - if (digest_o == data_mux || digest_o == '0) begin - state_d = IdleSt; - // If the partition is still locked, this is the first integrity check after - // initialization. This is the only way the buffer regs can get unlocked. - if (mubi8_test_true_strict(dout_locked_q)) begin - dout_locked_d = MuBi8False; - // Otherwise, this integrity check has requested by the LFSR timer, and we have - // to acknowledge its completion. - end else begin - integ_chk_ack_o = 1'b1; - end - // Error out and lock the partition if this check fails. - end else begin - state_d = ErrorSt; - error_d = CheckFailError; - // The check has finished and found an error. - integ_chk_ack_o = 1'b1; - end - end - end - /////////////////////////////////////////////////////////////////// - // Terminal Error State. This locks access to the partition. - // Make sure the partition signals an error state if no error - // code has been latched so far, and lock the buffer regs down. - ErrorSt: begin - dout_locked_d = MuBi8True; - if (error_q == NoError) begin - error_d = FsmStateError; - end - // If we are in error state, we cannot execute the checks anymore. - // Hence the acknowledgements are returned immediately. - cnsty_chk_ack_o = 1'b1; - integ_chk_ack_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - // We should never get here. If we do (e.g. via a malicious - // glitch), error out immediately. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - - // Unconditionally jump into the terminal error state in case of - // an ECC error or escalation, and lock access to the partition down. - // SEC_CM: PART.FSM.LOCAL_ESC - if (ecc_err) begin - state_d = ErrorSt; - if (state_q != ErrorSt) begin - error_d = CheckFailError; - end - end - // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - if (state_q != ErrorSt) begin - error_d = FsmStateError; - end - end - end - - //////////////////////////// - // Address Calc and Muxes // - //////////////////////////// - - // Address counter - this is only used for computing a digest, hence the increment is - // fixed to 8 byte. - // SEC_CM: PART.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count ( - .clk_i, - .rst_ni, - .clr_i(cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(cnt), - .cnt_after_commit_o(), - .err_o(cnt_err) - ); - - logic [OtpByteAddrWidth-1:0] addr_base; - assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset; - - // Note that OTP works on halfword (16bit) addresses, hence need to - // shift the addresses appropriately. - logic [OtpByteAddrWidth-1:0] addr_calc; - assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base; - assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift]; - - if (OtpAddrShift > 0) begin : gen_unused - logic unused_bits; - assign unused_bits = ^addr_calc[OtpAddrShift-1:0]; - end - - // Always transfer 64bit blocks. - assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1); - - assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i; - - ///////////////// - // Buffer Regs // - ///////////////// - - // SEC_CM: PART.DATA_REG.INTEGRITY - logic [Info.size*8-1:0] data; - otp_ctrl_ecc_reg #( - .Width ( ScrmblBlockWidth ), - .Depth ( NumScrmblBlocks ) - ) u_otp_ctrl_ecc_reg ( - .clk_i, - .rst_ni, - .wren_i ( buffer_reg_en ), - .addr_i ( cnt ), - .wdata_i ( data_mux ), - .rdata_o ( scrmbl_data_o ), - .data_o ( data ), - .ecc_err_o ( ecc_err ) - ); - - // We have successfully initialized the partition once it has been unlocked. - assign init_done_o = mubi8_test_false_strict(dout_locked_q); - // Hardware output gating. - // Note that this is decoupled from the DAI access rules further below. - assign data_o = (init_done_o) ? data : DataDefault; - // The digest does not have to be gated. - assign digest_o = data[$high(data_o) -: ScrmblBlockWidth]; - - //////////////////////// - // DAI Access Control // - //////////////////////// - - // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized. - // Note that the locks are redundantly encoded values. - part_access_t access_pre; - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_write_lock_pre ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)), - .mubi_o(access_pre.write_lock) - ); - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_read_lock_pre ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)), - .mubi_o(access_pre.read_lock) - ); - - // SEC_CM: PART.MEM.SW_UNWRITABLE - if (Info.write_lock) begin : gen_digest_write_lock - mubi8_t digest_locked; - assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False; - - // This prevents the synthesis tool from optimizing the multibit signal. - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_write_lock ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)), - .mubi_o(access_o.write_lock) - ); - - `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock)) - end else begin : gen_no_digest_write_lock - assign access_o.write_lock = access_pre.write_lock; - end - - // SEC_CM: PART.MEM.SW_UNREADABLE - if (Info.read_lock) begin : gen_digest_read_lock - mubi8_t digest_locked; - assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False; - - // This prevents the synthesis tool from optimizing the multibit signal. - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_read_lock ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)), - .mubi_o(access_o.read_lock) - ); - - `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock)) - end else begin : gen_no_digest_read_lock - assign access_o.read_lock = access_pre.read_lock; - end - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - error_q <= NoError; - // data output is locked by default - dout_locked_q <= MuBi8True; - end else begin - error_q <= error_d; - dout_locked_q <= dout_locked_d; - end - end - - //////////////// - // Assertions // - //////////////// - - // Known assertions - `ASSERT_KNOWN(InitDoneKnown_A, init_done_o) - `ASSERT_KNOWN(IntegChkAckKnown_A, integ_chk_ack_o) - `ASSERT_KNOWN(CnstyChkAckKnown_A, cnsty_chk_ack_o) - `ASSERT_KNOWN(ErrorKnown_A, error_o) - `ASSERT_KNOWN(AccessKnown_A, access_o) - `ASSERT_KNOWN(DigestKnown_A, digest_o) - `ASSERT_KNOWN(DataKnown_A, data_o) - `ASSERT_KNOWN(OtpReqKnown_A, otp_req_o) - `ASSERT_KNOWN(OtpCmdKnown_A, otp_cmd_o) - `ASSERT_KNOWN(OtpSizeKnown_A, otp_size_o) - `ASSERT_KNOWN(OtpWdataKnown_A, otp_wdata_o) - `ASSERT_KNOWN(OtpAddrKnown_A, otp_addr_o) - `ASSERT_KNOWN(ScrmblMtxReqKnown_A, scrmbl_mtx_req_o) - `ASSERT_KNOWN(ScrmblCmdKnown_A, scrmbl_cmd_o) - `ASSERT_KNOWN(ScrmblModeKnown_A, scrmbl_mode_o) - `ASSERT_KNOWN(ScrmblSelKnown_A, scrmbl_sel_o) - `ASSERT_KNOWN(ScrmblDataKnown_A, scrmbl_data_o) - `ASSERT_KNOWN(ScrmblValidKnown_A, scrmbl_valid_o) - - // Uninitialized partitions should always be locked, no matter what. - `ASSERT(InitWriteLocksPartition_A, - mubi8_test_true_loose(dout_locked_q) - |-> - mubi8_test_true_loose(access_o.write_lock)) - `ASSERT(InitReadLocksPartition_A, - mubi8_test_true_loose(dout_locked_q) - |-> - mubi8_test_true_loose(access_o.read_lock)) - // Incoming Lock propagation - `ASSERT(WriteLockPropagation_A, - mubi8_test_true_loose(access_i.write_lock) - |-> - mubi8_test_true_loose(access_o.write_lock)) - `ASSERT(ReadLockPropagation_A, - mubi8_test_true_loose(access_i.read_lock) - |-> - mubi8_test_true_loose(access_o.read_lock)) - // ECC error in buffer regs - `ASSERT(EccErrorState_A, - ecc_err - |=> - state_q == ErrorSt) - // OTP error response - `ASSERT(OtpErrorState_A, - state_q inside {InitWaitSt, CnstyReadWaitSt} && otp_rvalid_i && - !(otp_err inside {NoError, MacroEccCorrError}) && !ecc_err - |=> - state_q == ErrorSt && error_o == $past(otp_err)) - - // The partition size must be greater than one scrambling block for the address calculation - // and muxing to work correctly. - `ASSERT_INIT(OtpPartBufSize_A, Info.size > (ScrmblBlockWidth/8)) - -endmodule : otp_ctrl_part_buf diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv deleted file mode 100644 index ae1e92cef8678..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_pkg.sv +++ /dev/null @@ -1,667 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Package partition metadata. -// -// DO NOT EDIT THIS FILE DIRECTLY. -// It has been generated with ./util/design/gen-otp-mmap.py - -package otp_ctrl_part_pkg; - - import prim_util_pkg::vbits; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_pkg::*; - - //////////////////////////////////// - // Scrambling Constants and Types // - //////////////////////////////////// - - parameter int NumScrmblKeys = 3; - parameter int NumDigestSets = 4; - - parameter int ScrmblKeySelWidth = vbits(NumScrmblKeys); - parameter int DigestSetSelWidth = vbits(NumDigestSets); - parameter int ConstSelWidth = (ScrmblKeySelWidth > DigestSetSelWidth) ? - ScrmblKeySelWidth : - DigestSetSelWidth; - - typedef enum logic [ConstSelWidth-1:0] { - StandardMode, - ChainedMode - } digest_mode_e; - - typedef logic [NumScrmblKeys-1:0][ScrmblKeyWidth-1:0] key_array_t; - typedef logic [NumDigestSets-1:0][ScrmblKeyWidth-1:0] digest_const_array_t; - typedef logic [NumDigestSets-1:0][ScrmblBlockWidth-1:0] digest_iv_array_t; - - typedef enum logic [ConstSelWidth-1:0] { - Secret0Key, - Secret1Key, - Secret2Key - } key_sel_e; - - typedef enum logic [ConstSelWidth-1:0] { - CnstyDigest, - FlashDataKey, - FlashAddrKey, - SramDataKey - } digest_sel_e; - - // SEC_CM: SECRET.MEM.SCRAMBLE - parameter key_array_t RndCnstKey = { - 128'h85A9E830BC059BA9286D6E2856A05CC3, - 128'hEFFA6D736C5EFF49AE7B70F9C46E5A62, - 128'h3BA121C5E097DDEB7768B4C666E9C3DA - }; - - // SEC_CM: PART.MEM.DIGEST - // Note: digest set 0 is used for computing the partition digests. Constants at - // higher indices are used to compute the scrambling keys. - parameter digest_const_array_t RndCnstDigestConst = { - 128'h4A22D4B78FE0266FBEE3958332F2939B, - 128'hD60822E1FAEC5C7290C7F21F6224F027, - 128'h277195FC471E4B26B6641214B61D1B43, - 128'hE95F517CB98955B4D5A89AA9109294A - }; - - parameter digest_iv_array_t RndCnstDigestIV = { - 64'hF98C48B1F9377284, - 64'hB7474D640F8A7F5, - 64'hE048B657396B4B83, - 64'hBEAD91D5FA4E0915 - }; - - - ///////////////////////////////////// - // Typedefs for Partition Metadata // - ///////////////////////////////////// - - typedef enum logic [1:0] { - Unbuffered, - Buffered, - LifeCycle - } part_variant_e; - - typedef struct packed { - part_variant_e variant; - // Offset and size within the OTP array, in Bytes. - logic [OtpByteAddrWidth-1:0] offset; - logic [OtpByteAddrWidth-1:0] size; - // Key index to use for scrambling. - key_sel_e key_sel; - // Attributes - logic secret; // Whether the partition is secret (and hence scrambled) - logic sw_digest; // Whether the partition has a software digest - logic hw_digest; // Whether the partition has a hardware digest - logic write_lock; // Whether the partition is write lockable (via digest) - logic read_lock; // Whether the partition is read lockable (via digest) - logic integrity; // Whether the partition is integrity protected - logic iskeymgr_creator; // Whether the partition has any creator key material - logic iskeymgr_owner; // Whether the partition has any owner key material - } part_info_t; - - parameter part_info_t PartInfoDefault = '{ - variant: Unbuffered, - offset: '0, - size: OtpByteAddrWidth'('hFF), - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b0, - hw_digest: 1'b0, - write_lock: 1'b0, - read_lock: 1'b0, - integrity: 1'b0, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }; - - //////////////////////// - // Partition Metadata // - //////////////////////// - - localparam part_info_t PartInfo [NumPart] = '{ - // VENDOR_TEST - '{ - variant: Unbuffered, - offset: 11'd0, - size: 64, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b1, - hw_digest: 1'b0, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b0, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // CREATOR_SW_CFG - '{ - variant: Unbuffered, - offset: 11'd64, - size: 368, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b1, - hw_digest: 1'b0, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // OWNER_SW_CFG - '{ - variant: Unbuffered, - offset: 11'd432, - size: 712, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b1, - hw_digest: 1'b0, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // ROT_CREATOR_AUTH_CODESIGN - '{ - variant: Unbuffered, - offset: 11'd1144, - size: 472, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b1, - hw_digest: 1'b0, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // ROT_CREATOR_AUTH_STATE - '{ - variant: Unbuffered, - offset: 11'd1616, - size: 40, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b1, - hw_digest: 1'b0, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // HW_CFG0 - '{ - variant: Buffered, - offset: 11'd1656, - size: 72, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b0, - hw_digest: 1'b1, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // HW_CFG1 - '{ - variant: Buffered, - offset: 11'd1728, - size: 16, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b0, - hw_digest: 1'b1, - write_lock: 1'b1, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // SECRET0 - '{ - variant: Buffered, - offset: 11'd1744, - size: 40, - key_sel: Secret0Key, - secret: 1'b1, - sw_digest: 1'b0, - hw_digest: 1'b1, - write_lock: 1'b1, - read_lock: 1'b1, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // SECRET1 - '{ - variant: Buffered, - offset: 11'd1784, - size: 88, - key_sel: Secret1Key, - secret: 1'b1, - sw_digest: 1'b0, - hw_digest: 1'b1, - write_lock: 1'b1, - read_lock: 1'b1, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - }, - // SECRET2 - '{ - variant: Buffered, - offset: 11'd1872, - size: 88, - key_sel: Secret2Key, - secret: 1'b1, - sw_digest: 1'b0, - hw_digest: 1'b1, - write_lock: 1'b1, - read_lock: 1'b1, - integrity: 1'b1, - iskeymgr_creator: 1'b1, - iskeymgr_owner: 1'b0 - }, - // LIFE_CYCLE - '{ - variant: LifeCycle, - offset: 11'd1960, - size: 88, - key_sel: key_sel_e'('0), - secret: 1'b0, - sw_digest: 1'b0, - hw_digest: 1'b0, - write_lock: 1'b0, - read_lock: 1'b0, - integrity: 1'b1, - iskeymgr_creator: 1'b0, - iskeymgr_owner: 1'b0 - } - }; - - typedef enum { - VendorTestIdx, - CreatorSwCfgIdx, - OwnerSwCfgIdx, - RotCreatorAuthCodesignIdx, - RotCreatorAuthStateIdx, - HwCfg0Idx, - HwCfg1Idx, - Secret0Idx, - Secret1Idx, - Secret2Idx, - LifeCycleIdx, - // These are not "real partitions", but in terms of implementation it is convenient to - // add these at the end of certain arrays. - DaiIdx, - LciIdx, - KdiIdx, - // Number of agents is the last idx+1. - NumAgentsIdx - } part_idx_e; - - parameter int NumAgents = int'(NumAgentsIdx); - - // Breakout types for easier access of individual items. - typedef struct packed { - logic [63:0] hw_cfg0_digest; - logic [255:0] manuf_state; - logic [255:0] device_id; - } otp_hw_cfg0_data_t; - - // default value used for intermodule - parameter otp_hw_cfg0_data_t OTP_HW_CFG0_DATA_DEFAULT = '{ - hw_cfg0_digest: 64'hF87BED95CFBA3727, - manuf_state: 256'hDF3888886BD10DC67ABB319BDA0529AE40119A3C6E63CDF358840E458E4029A6, - device_id: 256'h63B9485A3856C417CF7A50A9A91EF7F7B3A5B4421F462370FFF698183664DC7E - }; - typedef struct packed { - logic [63:0] hw_cfg1_digest; - logic [39:0] unallocated; - prim_mubi_pkg::mubi8_t dis_rv_dm_late_debug; - prim_mubi_pkg::mubi8_t en_csrng_sw_app_read; - prim_mubi_pkg::mubi8_t en_sram_ifetch; - } otp_hw_cfg1_data_t; - - // default value used for intermodule - parameter otp_hw_cfg1_data_t OTP_HW_CFG1_DATA_DEFAULT = '{ - hw_cfg1_digest: 64'hBBF4A76885E754F2, - unallocated: 40'h0, - dis_rv_dm_late_debug: prim_mubi_pkg::mubi8_t'(8'h69), - en_csrng_sw_app_read: prim_mubi_pkg::mubi8_t'(8'h69), - en_sram_ifetch: prim_mubi_pkg::mubi8_t'(8'h69) - }; - typedef struct packed { - // This reuses the same encoding as the life cycle signals for indicating valid status. - lc_ctrl_pkg::lc_tx_t valid; - otp_hw_cfg1_data_t hw_cfg1_data; - otp_hw_cfg0_data_t hw_cfg0_data; - } otp_broadcast_t; - - // default value for intermodule - parameter otp_broadcast_t OTP_BROADCAST_DEFAULT = '{ - valid: lc_ctrl_pkg::Off, - hw_cfg1_data: OTP_HW_CFG1_DATA_DEFAULT, - hw_cfg0_data: OTP_HW_CFG0_DATA_DEFAULT - }; - - - // OTP invalid partition default for buffered partitions. - parameter logic [16383:0] PartInvDefault = 16384'({ - 704'({ - 320'h93B61DE417B9FB339605F051E74379CBCC6596C7174EBA643E725E464F593C87A445C3C29F71A256, - 384'hA0D1E90E8C9FDDFA01E46311FD36D95401136C663A36C3E3E817E760B27AE937BFCDF15A3429452A851B80674A2B6FBE - }), - 704'({ - 64'h8CBBAD02BB4CA928, - 256'hD68C96F0B3D1FEED688098A43C33459F0279FC51CC7C626E315FD2B871D88819, - 256'hD0BAC511D08ECE0E2C0DBDDEDF7A854D5E58D0AA97A0F8F6D3D58610F4851667, - 128'h94CD3DED94B578192A4D8B51F5D41C8A - }), - 704'({ - 64'hC469C593E5DC0DA8, - 128'hE00E9680BD9B70291C752824C7DDC896, - 256'h105733EAA3880C5A234729143F97B62A55D0320379A0D260426D99D374E699CA, - 256'hDBC827839FE2DCC27E17D06B5D4E0DDDDBB9844327F20FB5D396D1CE085BDC31 - }), - 320'({ - 64'hBE193854E9CA60A0, - 128'h711D135F59A50322B6711DB6F5D40A37, - 128'hB5AC1F53D00A08C3B28B5C0FEE5F4C02 - }), - 128'({ - 64'hBBF4A76885E754F2, - 40'h0, // unallocated space - 8'h69, - 8'h69, - 8'h69 - }), - 576'({ - 64'hF87BED95CFBA3727, - 256'hDF3888886BD10DC67ABB319BDA0529AE40119A3C6E63CDF358840E458E4029A6, - 256'h63B9485A3856C417CF7A50A9A91EF7F7B3A5B4421F462370FFF698183664DC7E - }), - 320'({ - 64'h20440F25BB053FB5, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0 - }), - 3776'({ - 64'h15F164D7930C9D19, - 256'h0, - 32'h0, - 256'h0, - 32'h0, - 32'h0, - 256'h0, - 32'h0, - 32'h0, - 256'h0, - 32'h0, - 32'h0, - 256'h0, - 32'h0, - 512'h0, - 32'h0, - 512'h0, - 32'h0, - 512'h0, - 32'h0, - 512'h0, - 32'h0 - }), - 5696'({ - 64'hE29749216775E8A5, - 96'h0, // unallocated space - 1024'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 96'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 512'h0, - 128'h0, - 128'h0, - 512'h0, - 2560'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0 - }), - 2944'({ - 64'h340A5B93BB19342, - 96'h0, // unallocated space - 256'h0, - 256'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 32'h0, - 1248'h0 - }), - 512'({ - 64'h4947DD361344767A, - 448'h0 - })}); - - /////////////////////////////////////////////// - // Parameterized Assignment Helper Functions // - /////////////////////////////////////////////// - - function automatic otp_ctrl_core_hw2reg_t named_reg_assign( - logic [NumPart-1:0][ScrmblBlockWidth-1:0] part_digest); - otp_ctrl_core_hw2reg_t hw2reg; - logic unused_sigs; - unused_sigs = ^part_digest; - hw2reg = '0; - hw2reg.vendor_test_digest = part_digest[VendorTestIdx]; - hw2reg.creator_sw_cfg_digest = part_digest[CreatorSwCfgIdx]; - hw2reg.owner_sw_cfg_digest = part_digest[OwnerSwCfgIdx]; - hw2reg.rot_creator_auth_codesign_digest = part_digest[RotCreatorAuthCodesignIdx]; - hw2reg.rot_creator_auth_state_digest = part_digest[RotCreatorAuthStateIdx]; - hw2reg.hw_cfg0_digest = part_digest[HwCfg0Idx]; - hw2reg.hw_cfg1_digest = part_digest[HwCfg1Idx]; - hw2reg.secret0_digest = part_digest[Secret0Idx]; - hw2reg.secret1_digest = part_digest[Secret1Idx]; - hw2reg.secret2_digest = part_digest[Secret2Idx]; - return hw2reg; - endfunction : named_reg_assign - - function automatic part_access_t [NumPart-1:0] named_part_access_pre( - otp_ctrl_core_reg2hw_t reg2hw); - part_access_t [NumPart-1:0] part_access_pre; - logic unused_sigs; - unused_sigs = ^reg2hw; - // Default (this will be overridden by partition-internal settings). - part_access_pre = {{32'(2*NumPart)}{prim_mubi_pkg::MuBi8False}}; - // Note: these could be made a MuBi CSRs in the future. - // The main thing that is missing right now is proper support for W0C. - // VENDOR_TEST - if (!reg2hw.vendor_test_read_lock) begin - part_access_pre[VendorTestIdx].read_lock = prim_mubi_pkg::MuBi8True; - end - // CREATOR_SW_CFG - if (!reg2hw.creator_sw_cfg_read_lock) begin - part_access_pre[CreatorSwCfgIdx].read_lock = prim_mubi_pkg::MuBi8True; - end - // OWNER_SW_CFG - if (!reg2hw.owner_sw_cfg_read_lock) begin - part_access_pre[OwnerSwCfgIdx].read_lock = prim_mubi_pkg::MuBi8True; - end - // ROT_CREATOR_AUTH_CODESIGN - if (!reg2hw.rot_creator_auth_codesign_read_lock) begin - part_access_pre[RotCreatorAuthCodesignIdx].read_lock = prim_mubi_pkg::MuBi8True; - end - // ROT_CREATOR_AUTH_STATE - if (!reg2hw.rot_creator_auth_state_read_lock) begin - part_access_pre[RotCreatorAuthStateIdx].read_lock = prim_mubi_pkg::MuBi8True; - end - return part_access_pre; - endfunction : named_part_access_pre - - function automatic otp_broadcast_t named_broadcast_assign( - logic [NumPart-1:0] part_init_done, - logic [$bits(PartInvDefault)/8-1:0][7:0] part_buf_data); - otp_broadcast_t otp_broadcast; - logic valid, unused; - unused = 1'b0; - valid = 1'b1; - // VENDOR_TEST - unused ^= ^{part_init_done[VendorTestIdx], - part_buf_data[VendorTestOffset +: VendorTestSize]}; - // CREATOR_SW_CFG - unused ^= ^{part_init_done[CreatorSwCfgIdx], - part_buf_data[CreatorSwCfgOffset +: CreatorSwCfgSize]}; - // OWNER_SW_CFG - unused ^= ^{part_init_done[OwnerSwCfgIdx], - part_buf_data[OwnerSwCfgOffset +: OwnerSwCfgSize]}; - // ROT_CREATOR_AUTH_CODESIGN - unused ^= ^{part_init_done[RotCreatorAuthCodesignIdx], - part_buf_data[RotCreatorAuthCodesignOffset +: RotCreatorAuthCodesignSize]}; - // ROT_CREATOR_AUTH_STATE - unused ^= ^{part_init_done[RotCreatorAuthStateIdx], - part_buf_data[RotCreatorAuthStateOffset +: RotCreatorAuthStateSize]}; - // HW_CFG0 - valid &= part_init_done[HwCfg0Idx]; - otp_broadcast.hw_cfg0_data = otp_hw_cfg0_data_t'(part_buf_data[HwCfg0Offset +: HwCfg0Size]); - // HW_CFG1 - valid &= part_init_done[HwCfg1Idx]; - otp_broadcast.hw_cfg1_data = otp_hw_cfg1_data_t'(part_buf_data[HwCfg1Offset +: HwCfg1Size]); - // SECRET0 - unused ^= ^{part_init_done[Secret0Idx], - part_buf_data[Secret0Offset +: Secret0Size]}; - // SECRET1 - unused ^= ^{part_init_done[Secret1Idx], - part_buf_data[Secret1Offset +: Secret1Size]}; - // SECRET2 - unused ^= ^{part_init_done[Secret2Idx], - part_buf_data[Secret2Offset +: Secret2Size]}; - // LIFE_CYCLE - unused ^= ^{part_init_done[LifeCycleIdx], - part_buf_data[LifeCycleOffset +: LifeCycleSize]}; - otp_broadcast.valid = lc_ctrl_pkg::lc_tx_bool_to_lc_tx(valid); - return otp_broadcast; - endfunction : named_broadcast_assign - - function automatic otp_keymgr_key_t named_keymgr_key_assign( - logic [NumPart-1:0][ScrmblBlockWidth-1:0] part_digest, - logic [$bits(PartInvDefault)/8-1:0][7:0] part_buf_data, - lc_ctrl_pkg::lc_tx_t lc_seed_hw_rd_en); - otp_keymgr_key_t otp_keymgr_key; - logic valid, unused; - unused = 1'b0; - // For now we use a fixed struct type here so that the - // interface to the keymgr remains stable. The type contains - // a superset of all options, so we have to initialize it to '0 here. - otp_keymgr_key = '0; - // VENDOR_TEST - unused ^= ^{part_digest[VendorTestIdx], - part_buf_data[VendorTestOffset +: VendorTestSize]}; - // CREATOR_SW_CFG - unused ^= ^{part_digest[CreatorSwCfgIdx], - part_buf_data[CreatorSwCfgOffset +: CreatorSwCfgSize]}; - // OWNER_SW_CFG - unused ^= ^{part_digest[OwnerSwCfgIdx], - part_buf_data[OwnerSwCfgOffset +: OwnerSwCfgSize]}; - // ROT_CREATOR_AUTH_CODESIGN - unused ^= ^{part_digest[RotCreatorAuthCodesignIdx], - part_buf_data[RotCreatorAuthCodesignOffset +: RotCreatorAuthCodesignSize]}; - // ROT_CREATOR_AUTH_STATE - unused ^= ^{part_digest[RotCreatorAuthStateIdx], - part_buf_data[RotCreatorAuthStateOffset +: RotCreatorAuthStateSize]}; - // HW_CFG0 - unused ^= ^{part_digest[HwCfg0Idx], - part_buf_data[HwCfg0Offset +: HwCfg0Size]}; - // HW_CFG1 - unused ^= ^{part_digest[HwCfg1Idx], - part_buf_data[HwCfg1Offset +: HwCfg1Size]}; - // SECRET0 - unused ^= ^{part_digest[Secret0Idx], - part_buf_data[Secret0Offset +: Secret0Size]}; - // SECRET1 - unused ^= ^{part_digest[Secret1Idx], - part_buf_data[Secret1Offset +: Secret1Size]}; - // SECRET2 - valid = (part_digest[Secret2Idx] != 0); - unused ^= ^part_buf_data[RmaTokenOffset +: RmaTokenSize]; - otp_keymgr_key.creator_root_key_share0_valid = valid; - if (lc_ctrl_pkg::lc_tx_test_true_strict(lc_seed_hw_rd_en)) begin - otp_keymgr_key.creator_root_key_share0 = - part_buf_data[CreatorRootKeyShare0Offset +: CreatorRootKeyShare0Size]; - end else begin - otp_keymgr_key.creator_root_key_share0 = - PartInvDefault[CreatorRootKeyShare0Offset*8 +: CreatorRootKeyShare0Size*8]; - end - otp_keymgr_key.creator_root_key_share1_valid = valid; - if (lc_ctrl_pkg::lc_tx_test_true_strict(lc_seed_hw_rd_en)) begin - otp_keymgr_key.creator_root_key_share1 = - part_buf_data[CreatorRootKeyShare1Offset +: CreatorRootKeyShare1Size]; - end else begin - otp_keymgr_key.creator_root_key_share1 = - PartInvDefault[CreatorRootKeyShare1Offset*8 +: CreatorRootKeyShare1Size*8]; - end - // This is not used since we consume the - // ungated digest values from the part_digest array. - unused ^= ^part_buf_data[Secret2DigestOffset +: Secret2DigestSize]; - // LIFE_CYCLE - unused ^= ^{part_digest[LifeCycleIdx], - part_buf_data[LifeCycleOffset +: LifeCycleSize]}; - unused ^= valid; - return otp_keymgr_key; - endfunction : named_keymgr_key_assign - -endpackage : otp_ctrl_part_pkg diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv deleted file mode 100644 index 23cf3171b929e..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Unbuffered partition for OTP controller. -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_part_unbuf - import otp_ctrl_pkg::*; - import otp_ctrl_reg_pkg::*; - import otp_ctrl_part_pkg::*; -#( - // Partition information. - parameter part_info_t Info = PartInfoDefault -) ( - input clk_i, - input rst_ni, - // Pulse to start partition initialisation (required once per power cycle). - input init_req_i, - output logic init_done_o, - // Escalation input. This moves the FSM into a terminal state and locks down - // the partition. - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - // Output error state of partition, to be consumed by OTP error/alert logic. - // Note that most errors are not recoverable and move the partition FSM into - // a terminal error state. - output otp_err_e error_o, - // This error signal is pulsed high if the FSM has been glitched into an invalid state. - // Although it is somewhat redundant with the error code in error_o above, it is - // meant to cover cases where we already latched an error code while the FSM is - // glitched into an invalid state (since in that case, the error code will not be - // overridden with the FSM error code so that the original error code is still - // discoverable). - output logic fsm_err_o, - // Access/lock status - // SEC_CM: ACCESS.CTRL.MUBI - input part_access_t access_i, // runtime lock from CSRs - output part_access_t access_o, - // Buffered 64bit digest output. - output logic [ScrmblBlockWidth-1:0] digest_o, - // Interface to TL-UL adapter - input logic tlul_req_i, - output logic tlul_gnt_o, - input [SwWindowAddrWidth-1:0] tlul_addr_i, - output logic [1:0] tlul_rerror_o, - output logic tlul_rvalid_o, - output logic [31:0] tlul_rdata_o, - // OTP interface - output logic otp_req_o, - output prim_otp_pkg::cmd_e otp_cmd_o, - output logic [OtpSizeWidth-1:0] otp_size_o, - output logic [OtpIfWidth-1:0] otp_wdata_o, - output logic [OtpAddrWidth-1:0] otp_addr_o, - input otp_gnt_i, - input otp_rvalid_i, - input [ScrmblBlockWidth-1:0] otp_rdata_i, - input prim_otp_pkg::err_e otp_err_i -); - - //////////////////////// - // Integration Checks // - //////////////////////// - - import prim_mubi_pkg::*; - import prim_util_pkg::vbits; - - localparam logic [OtpByteAddrWidth:0] PartEnd = (OtpByteAddrWidth+1)'(Info.offset) + - (OtpByteAddrWidth+1)'(Info.size); - localparam int unsigned DigestOffsetInt = int'(PartEnd) - ScrmblBlockWidth/8; - - localparam bit [OtpByteAddrWidth-1:0] DigestOffset = DigestOffsetInt[OtpByteAddrWidth-1:0]; - - // Integration checks for parameters. - `ASSERT_INIT(OffsetMustBeBlockAligned_A, (Info.offset % (ScrmblBlockWidth/8)) == 0) - `ASSERT_INIT(SizeMustBeBlockAligned_A, (Info.size % (ScrmblBlockWidth/8)) == 0) - `ASSERT_INIT(DigestOffsetMustBeRepresentable_A, DigestOffsetInt == int'(DigestOffset)) - - /////////////////////// - // OTP Partition FSM // - /////////////////////// - - // SEC_CM: PART.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 7 -n 10 \ - // -s 4247417884 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (52.38%) - // 6: |||||||||||| (33.33%) - // 7: | (4.76%) - // 8: ||| (9.52%) - // 9: -- - // 10: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 8 - // Minimum Hamming weight: 3 - // Maximum Hamming weight: 9 - // - localparam int StateWidth = 10; - typedef enum logic [StateWidth-1:0] { - ResetSt = 10'b1010110110, - InitSt = 10'b0100010011, - InitWaitSt = 10'b0001011000, - IdleSt = 10'b1011101001, - ReadSt = 10'b0101101110, - ReadWaitSt = 10'b0110100101, - ErrorSt = 10'b1111011111 - } state_e; - - typedef enum logic { - DigestAddrSel = 1'b0, - DataAddrSel = 1'b1 - } addr_sel_e; - - state_e state_d, state_q; - addr_sel_e otp_addr_sel; - otp_err_e error_d, error_q; - - logic digest_reg_en; - logic ecc_err; - - logic tlul_addr_in_range; - logic [SwWindowAddrWidth-1:0] tlul_addr_d, tlul_addr_q; - - // This is only used to return bus errors when the FSM is in ErrorSt. - logic pending_tlul_error_d, pending_tlul_error_q; - - // Output partition error state. - assign error_o = error_q; - - // This partition cannot do any write accesses, hence we tie this - // constantly off. - assign otp_wdata_o = '0; - // Depending on the partition configuration, the wrapper is instructed to ignore integrity - // calculations and checks. To be on the safe side, the partition filters error responses at this - // point and does not report any integrity errors if integrity is disabled. - otp_err_e otp_err; - if (Info.integrity) begin : gen_integrity - assign otp_cmd_o = prim_otp_pkg::Read; - assign otp_err = otp_err_e'(otp_err_i); - end else begin : gen_no_integrity - assign otp_cmd_o = prim_otp_pkg::ReadRaw; - always_comb begin - if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin - otp_err = NoError; - end else begin - otp_err = otp_err_e'(otp_err_i); - end - end - end - - `ASSERT_KNOWN(FsmStateKnown_A, state_q) - always_comb begin : p_fsm - // Default assignments - state_d = state_q; - - // Response to init request - init_done_o = 1'b0; - - // OTP signals - otp_req_o = 1'b0; - otp_addr_sel = DigestAddrSel; - - // TL-UL signals - tlul_gnt_o = 1'b0; - tlul_rvalid_o = 1'b0; - tlul_rerror_o = '0; - - // Enable for buffered digest register - digest_reg_en = 1'b0; - - // Error Register - error_d = error_q; - pending_tlul_error_d = 1'b0; - fsm_err_o = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // State right after reset. Wait here until we get a an - // initialization request. - ResetSt: begin - if (init_req_i) begin - // If the partition does not have a digest, no initialization is necessary. - if (Info.sw_digest) begin - state_d = InitSt; - end else begin - state_d = IdleSt; - end - end - end - /////////////////////////////////////////////////////////////////// - // Initialization reads out the digest only in unbuffered - // partitions. Wait here until the OTP request has been granted. - // And then wait until the OTP word comes back. - InitSt: begin - otp_req_o = 1'b1; - if (otp_gnt_i) begin - state_d = InitWaitSt; - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and write to digest buffer register. In - // case an OTP transaction fails, latch the OTP error code and - // jump to a terminal error state. - InitWaitSt: begin - if (otp_rvalid_i) begin - digest_reg_en = 1'b1; - if (otp_err inside {NoError, MacroEccCorrError}) begin - state_d = IdleSt; - // At this point the only error that we could have gotten are correctable ECC errors. - if (otp_err != NoError) begin - error_d = MacroEccCorrError; - end - end else begin - state_d = ErrorSt; - error_d = otp_err; - end - end - end - /////////////////////////////////////////////////////////////////// - // Wait for TL-UL requests coming in. - // Then latch address and go to readout state. - IdleSt: begin - init_done_o = 1'b1; - if (tlul_req_i) begin - error_d = NoError; // clear recoverable soft errors. - state_d = ReadSt; - tlul_gnt_o = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // If the address is out of bounds, or if the partition is - // locked, signal back a bus error. Note that such an error does - // not cause the partition to go into error state. Otherwise if - // these checks pass, an OTP word is requested. - ReadSt: begin - init_done_o = 1'b1; - // Double check the address range. - if (tlul_addr_in_range && mubi8_test_false_strict(access_o.read_lock)) begin - otp_req_o = 1'b1; - otp_addr_sel = DataAddrSel; - if (otp_gnt_i) begin - state_d = ReadWaitSt; - end - end else begin - state_d = IdleSt; - error_d = AccessError; // Signal this error, but do not go into terminal error state. - tlul_rvalid_o = 1'b1; - tlul_rerror_o = 2'b11; // This causes the TL-UL adapter to return a bus error. - end - end - /////////////////////////////////////////////////////////////////// - // Wait for OTP response and release the TL-UL response. In - // case an OTP transaction fails, latch the OTP error code, - // signal a TL-Ul bus error and jump to a terminal error state. - ReadWaitSt: begin - init_done_o = 1'b1; - if (otp_rvalid_i) begin - tlul_rvalid_o = 1'b1; - if (otp_err inside {NoError, MacroEccCorrError}) begin - state_d = IdleSt; - // At this point the only error that we could have gotten are correctable ECC errors. - if (otp_err != NoError) begin - error_d = MacroEccCorrError; - end - end else begin - state_d = ErrorSt; - error_d = otp_err; - // This causes the TL-UL adapter to return a bus error. - tlul_rerror_o = 2'b11; - end - end - end - /////////////////////////////////////////////////////////////////// - // Terminal Error State. This locks access to the partition. - // Make sure the partition signals an error state if no error - // code has been latched so far. - ErrorSt: begin - if (error_q == NoError) begin - error_d = FsmStateError; - end - - // Return bus errors if there are pending TL-UL requests. - if (pending_tlul_error_q) begin - tlul_rerror_o = 2'b11; - tlul_rvalid_o = 1'b1; - end else if (tlul_req_i) begin - tlul_gnt_o = 1'b1; - pending_tlul_error_d = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // We should never get here. If we do (e.g. via a malicious - // glitch), error out immediately. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of - // an ECC error or escalation, and lock access to the partition down. - // SEC_CM: PART.FSM.LOCAL_ESC - if (ecc_err) begin - state_d = ErrorSt; - if (state_q != ErrorSt) begin - error_d = CheckFailError; - end - end - // SEC_CM: PART.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i)) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - if (state_q != ErrorSt) begin - error_d = FsmStateError; - end - end - end - - /////////////////////////////////// - // Signals to/from TL-UL Adapter // - /////////////////////////////////// - - assign tlul_addr_d = tlul_addr_i; - // Do not forward data in case of an error. - assign tlul_rdata_o = (tlul_rvalid_o && tlul_rerror_o == '0) ? otp_rdata_i[31:0] : '0; - - if (Info.offset == 0) begin : gen_zero_offset - assign tlul_addr_in_range = {1'b0, tlul_addr_q, 2'b00} < PartEnd; - - end else begin : gen_nonzero_offset - assign tlul_addr_in_range = {tlul_addr_q, 2'b00} >= Info.offset && - {1'b0, tlul_addr_q, 2'b00} < PartEnd; - end - - // Note that OTP works on halfword (16bit) addresses, hence need to - // shift the addresses appropriately. - logic [OtpByteAddrWidth-1:0] addr_calc; - assign addr_calc = (otp_addr_sel == DigestAddrSel) ? DigestOffset : {tlul_addr_q, 2'b00}; - assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift]; - - if (OtpAddrShift > 0) begin : gen_unused - logic unused_bits; - assign unused_bits = ^addr_calc[OtpAddrShift-1:0]; - end - - // Request 32bit except in case of the digest. - assign otp_size_o = (otp_addr_sel == DigestAddrSel) ? - OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth - 1)) : - OtpSizeWidth'(unsigned'(32 / OtpWidth - 1)); - - //////////////// - // Digest Reg // - //////////////// - - if (Info.sw_digest) begin : gen_ecc_reg - // SEC_CM: PART.DATA_REG.INTEGRITY - otp_ctrl_ecc_reg #( - .Width ( ScrmblBlockWidth ), - .Depth ( 1 ) - ) u_otp_ctrl_ecc_reg ( - .clk_i, - .rst_ni, - .wren_i ( digest_reg_en ), - .addr_i ( '0 ), - .wdata_i ( otp_rdata_i ), - .rdata_o ( ), - .data_o ( digest_o ), - .ecc_err_o ( ecc_err ) - ); - end else begin : gen_no_ecc_reg - logic unused_digest_reg_en; - logic unused_rdata; - assign unused_digest_reg_en = digest_reg_en; - assign unused_rdata = ^otp_rdata_i[32 +: 32]; // Upper word is not connected in this case. - assign digest_o = '0; - assign ecc_err = 1'b0; - end - - //////////////////////// - // DAI Access Control // - //////////////////////// - - mubi8_t init_locked; - assign init_locked = (~init_done_o) ? MuBi8True : MuBi8False; - - // Aggregate all possible DAI write locks. The partition is also locked when uninitialized. - // Note that the locks are redundantly encoded values. - part_access_t access_pre; - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_write_lock_pre ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(init_locked, access_i.write_lock)), - .mubi_o(access_pre.write_lock) - ); - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_read_lock_pre ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(init_locked, access_i.read_lock)), - .mubi_o(access_pre.read_lock) - ); - - // SEC_CM: PART.MEM.SW_UNWRITABLE - if (Info.write_lock) begin : gen_digest_write_lock - mubi8_t digest_locked; - assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False; - - // This prevents the synthesis tool from optimizing the multibit signal. - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_write_lock ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)), - .mubi_o(access_o.write_lock) - ); - - `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock)) - end else begin : gen_no_digest_write_lock - assign access_o.write_lock = access_pre.write_lock; - end - - // SEC_CM: PART.MEM.SW_UNREADABLE - if (Info.read_lock) begin : gen_digest_read_lock - mubi8_t digest_locked; - assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False; - - // This prevents the synthesis tool from optimizing the multibit signal. - prim_mubi8_sender #( - .AsyncOn(0) - ) u_prim_mubi8_sender_read_lock ( - .clk_i, - .rst_ni, - .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)), - .mubi_o(access_o.read_lock) - ); - - `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock)) - end else begin : gen_no_digest_read_lock - assign access_o.read_lock = access_pre.read_lock; - end - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - error_q <= NoError; - tlul_addr_q <= '0; - pending_tlul_error_q <= 1'b0; - end else begin - error_q <= error_d; - pending_tlul_error_q <= pending_tlul_error_d; - if (tlul_gnt_o) begin - tlul_addr_q <= tlul_addr_d; - end - end - end - - //////////////// - // Assertions // - //////////////// - - // Known assertions - `ASSERT_KNOWN(InitDoneKnown_A, init_done_o) - `ASSERT_KNOWN(ErrorKnown_A, error_o) - `ASSERT_KNOWN(AccessKnown_A, access_o) - `ASSERT_KNOWN(DigestKnown_A, digest_o) - `ASSERT_KNOWN(TlulGntKnown_A, tlul_gnt_o) - `ASSERT_KNOWN(TlulRerrorKnown_A, tlul_rerror_o) - `ASSERT_KNOWN(TlulRvalidKnown_A, tlul_rvalid_o) - `ASSERT_KNOWN(TlulRdataKnown_A, tlul_rdata_o) - `ASSERT_KNOWN(OtpReqKnown_A, otp_req_o) - `ASSERT_KNOWN(OtpCmdKnown_A, otp_cmd_o) - `ASSERT_KNOWN(OtpSizeKnown_A, otp_size_o) - `ASSERT_KNOWN(OtpWdataKnown_A, otp_wdata_o) - `ASSERT_KNOWN(OtpAddrKnown_A, otp_addr_o) - - // Uninitialized partitions should always be locked, no matter what. - `ASSERT(InitWriteLocksPartition_A, - ~init_done_o - |-> - mubi8_test_true_loose(access_o.write_lock)) - `ASSERT(InitReadLocksPartition_A, - ~init_done_o - |-> - mubi8_test_true_loose(access_o.read_lock)) - // Incoming Lock propagation - `ASSERT(WriteLockPropagation_A, - mubi8_test_true_loose(access_i.write_lock) - |-> - mubi8_test_true_loose(access_o.write_lock)) - `ASSERT(ReadLockPropagation_A, - mubi8_test_true_loose(access_i.read_lock) - |-> - mubi8_test_true_loose(access_o.read_lock)) - // If the partition is read locked, the TL-UL access must error out - `ASSERT(TlulReadOnReadLock_A, - tlul_req_i && tlul_gnt_o ##1 mubi8_test_true_loose(access_o.read_lock) - |-> - tlul_rerror_o > '0 && tlul_rvalid_o) - // ECC error in buffer regs. - `ASSERT(EccErrorState_A, - ecc_err - |=> - state_q == ErrorSt) - // OTP error response - `ASSERT(OtpErrorState_A, - state_q inside {InitWaitSt, ReadWaitSt} && otp_rvalid_i && - !(otp_err inside {NoError, MacroEccCorrError}) && !ecc_err - |=> - state_q == ErrorSt && error_o == $past(otp_err)) - -endmodule : otp_ctrl_part_unbuf diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv deleted file mode 100644 index 7a460fdd58824..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_pkg.sv +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// - -package otp_ctrl_pkg; - - import prim_util_pkg::vbits; - import otp_ctrl_reg_pkg::*; - - //////////////////////// - // General Parameters // - //////////////////////// - - // Number of vendor-specific test CSR bits coming from and going to - // the life cycle TAP registers. - parameter int OtpTestCtrlWidth = 32; - parameter int OtpTestStatusWidth = 32; - parameter int OtpTestVectWidth = 8; - - // Width of entropy input - parameter int EdnDataWidth = 64; - - parameter int NumPartWidth = vbits(NumPart); - - parameter int SwWindowAddrWidth = vbits(NumSwCfgWindowWords); - - // Background check timer LFSR width. - parameter int LfsrWidth = 40; - // The LFSR will be reseeded once LfsrUsageThreshold - // values have been drawn from it. - parameter int LfsrUsageThreshold = 16; - - // Redundantly encoded and complementary values are used to for signalling to the partition - // controller FSMs and the DAI whether a partition is locked or not. Any other value than - // "Mubi8Lo" is interpreted as "Locked" in those FSMs. - typedef struct packed { - prim_mubi_pkg::mubi8_t read_lock; - prim_mubi_pkg::mubi8_t write_lock; - } part_access_t; - - parameter int DaiCmdWidth = 3; - typedef enum logic [DaiCmdWidth-1:0] { - DaiRead = 3'b001, - DaiWrite = 3'b010, - DaiDigest = 3'b100 - } dai_cmd_e; - - parameter int DeviceIdWidth = 256; - typedef logic [DeviceIdWidth-1:0] otp_device_id_t; - - parameter int ManufStateWidth = 256; - typedef logic [ManufStateWidth-1:0] otp_manuf_state_t; - - ////////////////////////////////////// - // Typedefs for OTP Macro Interface // - ////////////////////////////////////// - - // OTP-macro specific - parameter int OtpWidth = 16; - parameter int OtpAddrWidth = OtpByteAddrWidth - $clog2(OtpWidth/8); - parameter int OtpDepth = 2**OtpAddrWidth; - parameter int OtpSizeWidth = 2; // Allows to transfer up to 4 native OTP words at once. - parameter int OtpErrWidth = 3; - parameter int OtpPwrSeqWidth = 2; - parameter int OtpIfWidth = 2**OtpSizeWidth*OtpWidth; - // Number of Byte address bits to cut off in order to get the native OTP word address. - parameter int OtpAddrShift = OtpByteAddrWidth - OtpAddrWidth; - - typedef enum logic [OtpErrWidth-1:0] { - NoError = 3'h0, - MacroError = 3'h1, - MacroEccCorrError = 3'h2, - MacroEccUncorrError = 3'h3, - MacroWriteBlankError = 3'h4, - AccessError = 3'h5, - CheckFailError = 3'h6, - FsmStateError = 3'h7 - } otp_err_e; - - ///////////////////////////////// - // Typedefs for OTP Scrambling // - ///////////////////////////////// - - parameter int ScrmblKeyWidth = 128; - parameter int ScrmblBlockWidth = 64; - - parameter int NumPresentRounds = 31; - parameter int ScrmblBlockHalfWords = ScrmblBlockWidth / OtpWidth; - - typedef enum logic [2:0] { - Decrypt, - Encrypt, - LoadShadow, - Digest, - DigestInit, - DigestFinalize - } otp_scrmbl_cmd_e; - - /////////////////////////////// - // Typedefs for LC Interface // - /////////////////////////////// - - // The tokens below are all hash post-images - typedef struct packed { - logic valid; - logic error; - // Use lc_state_t and lc_cnt_t here as very wide enumerations ( > 64 bits ) - // are not supported for virtual interfaces by Excelium yet - // https://github.com/lowRISC/opentitan/issues/8884 (Cadence issue: cds_46570160) - // The enumeration types lc_state_e and lc_cnt_e are still ok in other circumstances - lc_ctrl_state_pkg::lc_state_t state; - lc_ctrl_state_pkg::lc_cnt_t count; - // This is set to "On" if the partition containing the - // root secrets have been locked. In that case, the device - // is considered "personalized". - lc_ctrl_pkg::lc_tx_t secrets_valid; - // This is set to "On" if the partition containing the - // test tokens has been locked. - lc_ctrl_pkg::lc_tx_t test_tokens_valid; - lc_ctrl_state_pkg::lc_token_t test_unlock_token; - lc_ctrl_state_pkg::lc_token_t test_exit_token; - // This is set to "On" if the partition containing the - // rma token has been locked. - lc_ctrl_pkg::lc_tx_t rma_token_valid; - lc_ctrl_state_pkg::lc_token_t rma_token; - } otp_lc_data_t; - - // Default for dangling connection. - // Note that we put the life cycle into - // TEST_UNLOCKED0 by default such that top levels without - // the OTP controller can still function. - parameter otp_lc_data_t OTP_LC_DATA_DEFAULT = '{ - valid: 1'b1, - error: 1'b0, - state: lc_ctrl_state_pkg::LcStTestUnlocked0, - count: lc_ctrl_state_pkg::LcCnt1, - secrets_valid: lc_ctrl_pkg::Off, - test_tokens_valid: lc_ctrl_pkg::Off, - test_unlock_token: '0, - test_exit_token: '0, - rma_token_valid: lc_ctrl_pkg::Off, - rma_token: '0 - }; - - typedef struct packed { - logic req; - lc_ctrl_state_pkg::lc_state_e state; - lc_ctrl_state_pkg::lc_cnt_e count; - } lc_otp_program_req_t; - - typedef struct packed { - logic err; - logic ack; - } lc_otp_program_rsp_t; - - // RAW unlock token hashing request. - typedef struct packed { - logic req; - lc_ctrl_state_pkg::lc_token_t token_input; - } lc_otp_token_req_t; - - typedef struct packed { - logic ack; - lc_ctrl_state_pkg::lc_token_t hashed_token; - } lc_otp_token_rsp_t; - - typedef struct packed { - logic [OtpTestCtrlWidth-1:0] ctrl; - } lc_otp_vendor_test_req_t; - - typedef struct packed { - logic [OtpTestStatusWidth-1:0] status; - } lc_otp_vendor_test_rsp_t; - - //////////////////////////////// - // Typedefs for Key Broadcast // - //////////////////////////////// - - parameter int FlashKeySeedWidth = 256; - parameter int SramKeySeedWidth = 128; - parameter int KeyMgrKeyWidth = 256; - parameter int FlashKeyWidth = 128; - parameter int SramKeyWidth = 128; - parameter int SramNonceWidth = 128; - parameter int OtbnKeyWidth = 128; - parameter int OtbnNonceWidth = 64; - - typedef logic [SramKeyWidth-1:0] sram_key_t; - typedef logic [SramNonceWidth-1:0] sram_nonce_t; - typedef logic [OtbnKeyWidth-1:0] otbn_key_t; - typedef logic [OtbnNonceWidth-1:0] otbn_nonce_t; - - localparam int OtbnNonceSel = OtbnNonceWidth / ScrmblBlockWidth; - localparam int FlashNonceSel = FlashKeyWidth / ScrmblBlockWidth; - localparam int SramNonceSel = SramNonceWidth / ScrmblBlockWidth; - - // Get maximum nonce width - localparam int NumNonceChunks = - (OtbnNonceWidth > FlashKeyWidth) ? - ((OtbnNonceWidth > SramNonceSel) ? OtbnNonceSel : SramNonceSel) : - ((FlashKeyWidth > SramNonceSel) ? FlashNonceSel : SramNonceSel); - - typedef struct packed { - logic [KeyMgrKeyWidth-1:0] creator_root_key_share0; - logic creator_root_key_share0_valid; - logic [KeyMgrKeyWidth-1:0] creator_root_key_share1; - logic creator_root_key_share1_valid; - logic [KeyMgrKeyWidth-1:0] creator_seed; - logic creator_seed_valid; - logic [KeyMgrKeyWidth-1:0] owner_seed; - logic owner_seed_valid; - } otp_keymgr_key_t; - - parameter otp_keymgr_key_t OTP_KEYMGR_KEY_DEFAULT = '{ - creator_root_key_share0: 256'hefb7ea7ee90093cf4affd9aaa2d6c0ec446cfdf5f2d5a0bfd7e2d93edc63a102, - creator_root_key_share0_valid: 1'b1, - creator_root_key_share1: 256'h56d24a00181de99e0f690b447a8dde2a1ffb8bc306707107aa6e2410f15cfc37, - creator_root_key_share1_valid: 1'b1, - creator_seed: 256'hc7c50b38655cc87f821e5b07fed85d2c07e222a9e00bef308b3eccba0ba406fa, - creator_seed_valid: 1'b1, - owner_seed: 256'hf5052c0f14782d8b066be9f49c0b2000d3643ff3723ea7db972f69cd3e2e3e68, - owner_seed_valid: 1'b1 - }; - - typedef struct packed { - logic data_req; // Requests static key for data scrambling. - logic addr_req; // Requests static key for address scrambling. - } flash_otp_key_req_t; - - typedef struct packed { - logic req; // Requests ephemeral scrambling key and nonce. - } sram_otp_key_req_t; - - typedef struct packed { - logic req; // Requests ephemeral scrambling key and nonce. - } otbn_otp_key_req_t; - - typedef struct packed { - logic data_ack; // Ack for data key. - logic addr_ack; // Ack for address key. - logic [FlashKeyWidth-1:0] key; // 128bit static scrambling key. - logic [FlashKeyWidth-1:0] rand_key; - logic seed_valid; // Set to 1 if the key seed has been provisioned and is - // valid. - } flash_otp_key_rsp_t; - - // Default for dangling connection - parameter flash_otp_key_rsp_t FLASH_OTP_KEY_RSP_DEFAULT = '{ - data_ack: 1'b1, - addr_ack: 1'b1, - key: '0, - rand_key: '0, - seed_valid: 1'b1 - }; - - typedef struct packed { - logic ack; // Ack for key. - sram_key_t key; // 128bit ephemeral scrambling key. - sram_nonce_t nonce; // 128bit nonce. - logic seed_valid; // Set to 1 if the key seed has been provisioned and is valid. - } sram_otp_key_rsp_t; - - // Default for dangling connection - parameter sram_otp_key_rsp_t SRAM_OTP_KEY_RSP_DEFAULT = '{ - ack: 1'b1, - key: '0, - nonce: '0, - seed_valid: 1'b1 - }; - - typedef struct packed { - logic ack; // Ack for key. - otbn_key_t key; // 128bit ephemeral scrambling key. - otbn_nonce_t nonce; // 256bit nonce. - logic seed_valid; // Set to 1 if the key seed has been provisioned and is valid. - } otbn_otp_key_rsp_t; - - //////////////////////////////// - // Power/Reset Ctrl Interface // - //////////////////////////////// - - typedef struct packed { - logic init; - } pwr_otp_init_req_t; - - typedef struct packed { - logic done; - } pwr_otp_init_rsp_t; - - typedef struct packed { - logic idle; - } otp_pwr_state_t; - - - /////////////////// - // AST Interface // - /////////////////// - - typedef struct packed { - logic [OtpPwrSeqWidth-1:0] pwr_seq; - } otp_ast_req_t; - - typedef struct packed { - logic [OtpPwrSeqWidth-1:0] pwr_seq_h; - } otp_ast_rsp_t; - - /////////////////////////////////////////// - // Defaults for random netlist constants // - /////////////////////////////////////////// - - // These LFSR parameters have been generated with - // $ util/design/gen-lfsr-seed.py --width 40 --seed 4247488366 - typedef logic [LfsrWidth-1:0] lfsr_seed_t; - typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t; - localparam lfsr_seed_t RndCnstLfsrSeedDefault = 40'h453d28ea98; - localparam lfsr_perm_t RndCnstLfsrPermDefault = - 240'h4235171482c225f79289b32181a0163a760355d3447063d16661e44c12a5; - - typedef struct packed { - sram_key_t key; - sram_nonce_t nonce; - } scrmbl_key_init_t; - localparam scrmbl_key_init_t RndCnstScrmblKeyInitDefault = - 256'hcebeb96ffe0eced795f8b2cfe23c1e519e4fa08047a6bcfb811b04f0a479006e; - -endpackage : otp_ctrl_pkg diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv deleted file mode 100644 index fb30ea5203126..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv +++ /dev/null @@ -1,1467 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - -`include "prim_assert.sv" - -module otp_ctrl_prim_reg_top ( - input clk_i, - input rst_ni, - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, - // To HW - output otp_ctrl_reg_pkg::otp_ctrl_prim_reg2hw_t reg2hw, // Write - input otp_ctrl_reg_pkg::otp_ctrl_prim_hw2reg_t hw2reg, // Read - - // Integrity check errors - output logic intg_err_o -); - - import otp_ctrl_reg_pkg::* ; - - localparam int AW = 5; - localparam int DW = 32; - localparam int DBW = DW/8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [AW-1:0] reg_addr; - logic [DW-1:0] reg_wdata; - logic [DBW-1:0] reg_be; - logic [DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - logic reg_busy; - - tlul_pkg::tl_h2d_t tl_reg_h2d; - tlul_pkg::tl_d2h_t tl_reg_d2h; - - - // incoming payload check - logic intg_err; - tlul_cmd_intg_chk u_chk ( - .tl_i(tl_i), - .err_o(intg_err) - ); - - // also check for spurious write enables - logic reg_we_err; - logic [7:0] reg_we_check; - prim_reg_we_check #( - .OneHotWidth(8) - ) u_prim_reg_we_check ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .oh_i (reg_we_check), - .en_i (reg_we && !addrmiss), - .err_o (reg_we_err) - ); - - logic err_q; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - err_q <= '0; - end else if (intg_err || reg_we_err) begin - err_q <= 1'b1; - end - end - - // integrity error output is permanent and should be used for alert generation - // register errors are transactional - assign intg_err_o = err_q | intg_err | reg_we_err; - - // outgoing integrity generation - tlul_pkg::tl_d2h_t tl_o_pre; - tlul_rsp_intg_gen #( - .EnableRspIntgGen(1), - .EnableDataIntgGen(1) - ) u_rsp_intg_gen ( - .tl_i(tl_o_pre), - .tl_o(tl_o) - ); - - assign tl_reg_h2d = tl_i; - assign tl_o_pre = tl_reg_d2h; - - tlul_adapter_reg #( - .RegAw(AW), - .RegDw(DW), - .EnableDataIntgGen(0) - ) u_reg_if ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - .tl_i (tl_reg_h2d), - .tl_o (tl_reg_d2h), - - .en_ifetch_i(prim_mubi_pkg::MuBi4False), - .intg_error_o(), - - .we_o (reg_we), - .re_o (reg_re), - .addr_o (reg_addr), - .wdata_o (reg_wdata), - .be_o (reg_be), - .busy_i (reg_busy), - .rdata_i (reg_rdata), - .error_i (reg_error) - ); - - // cdc oversampling signals - - assign reg_rdata = reg_rdata_next ; - assign reg_error = addrmiss | wr_err | intg_err; - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic csr0_we; - logic csr0_field0_qs; - logic csr0_field0_wd; - logic csr0_field1_qs; - logic csr0_field1_wd; - logic csr0_field2_qs; - logic csr0_field2_wd; - logic [9:0] csr0_field3_qs; - logic [9:0] csr0_field3_wd; - logic [10:0] csr0_field4_qs; - logic [10:0] csr0_field4_wd; - logic csr1_we; - logic [6:0] csr1_field0_qs; - logic [6:0] csr1_field0_wd; - logic csr1_field1_qs; - logic csr1_field1_wd; - logic [6:0] csr1_field2_qs; - logic [6:0] csr1_field2_wd; - logic csr1_field3_qs; - logic csr1_field3_wd; - logic [15:0] csr1_field4_qs; - logic [15:0] csr1_field4_wd; - logic csr2_we; - logic csr2_qs; - logic csr2_wd; - logic csr3_we; - logic [2:0] csr3_field0_qs; - logic [2:0] csr3_field0_wd; - logic [9:0] csr3_field1_qs; - logic [9:0] csr3_field1_wd; - logic csr3_field2_qs; - logic csr3_field2_wd; - logic csr3_field3_qs; - logic csr3_field4_qs; - logic csr3_field5_qs; - logic csr3_field6_qs; - logic csr3_field7_qs; - logic csr3_field8_qs; - logic csr4_we; - logic [9:0] csr4_field0_qs; - logic [9:0] csr4_field0_wd; - logic csr4_field1_qs; - logic csr4_field1_wd; - logic csr4_field2_qs; - logic csr4_field2_wd; - logic csr4_field3_qs; - logic csr4_field3_wd; - logic csr5_we; - logic [5:0] csr5_field0_qs; - logic [5:0] csr5_field0_wd; - logic [1:0] csr5_field1_qs; - logic [1:0] csr5_field1_wd; - logic csr5_field2_qs; - logic [2:0] csr5_field3_qs; - logic csr5_field4_qs; - logic csr5_field5_qs; - logic [15:0] csr5_field6_qs; - logic [15:0] csr5_field6_wd; - logic csr6_we; - logic [9:0] csr6_field0_qs; - logic [9:0] csr6_field0_wd; - logic csr6_field1_qs; - logic csr6_field1_wd; - logic csr6_field2_qs; - logic csr6_field2_wd; - logic [15:0] csr6_field3_qs; - logic [15:0] csr6_field3_wd; - logic [5:0] csr7_field0_qs; - logic [2:0] csr7_field1_qs; - logic csr7_field2_qs; - logic csr7_field3_qs; - - // Register instances - // R[csr0]: V(False) - // F[field0]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr0_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr0_we), - .wd (csr0_field0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr0.field0.q), - .ds (), - - // to register interface (read) - .qs (csr0_field0_qs) - ); - - // F[field1]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr0_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr0_we), - .wd (csr0_field1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr0.field1.q), - .ds (), - - // to register interface (read) - .qs (csr0_field1_qs) - ); - - // F[field2]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr0_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr0_we), - .wd (csr0_field2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr0.field2.q), - .ds (), - - // to register interface (read) - .qs (csr0_field2_qs) - ); - - // F[field3]: 13:4 - prim_subreg #( - .DW (10), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (10'h0), - .Mubi (1'b0) - ) u_csr0_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr0_we), - .wd (csr0_field3_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr0.field3.q), - .ds (), - - // to register interface (read) - .qs (csr0_field3_qs) - ); - - // F[field4]: 26:16 - prim_subreg #( - .DW (11), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (11'h0), - .Mubi (1'b0) - ) u_csr0_field4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr0_we), - .wd (csr0_field4_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr0.field4.q), - .ds (), - - // to register interface (read) - .qs (csr0_field4_qs) - ); - - - // R[csr1]: V(False) - // F[field0]: 6:0 - prim_subreg #( - .DW (7), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (7'h0), - .Mubi (1'b0) - ) u_csr1_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr1_we), - .wd (csr1_field0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr1.field0.q), - .ds (), - - // to register interface (read) - .qs (csr1_field0_qs) - ); - - // F[field1]: 7:7 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr1_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr1_we), - .wd (csr1_field1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr1.field1.q), - .ds (), - - // to register interface (read) - .qs (csr1_field1_qs) - ); - - // F[field2]: 14:8 - prim_subreg #( - .DW (7), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (7'h0), - .Mubi (1'b0) - ) u_csr1_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr1_we), - .wd (csr1_field2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr1.field2.q), - .ds (), - - // to register interface (read) - .qs (csr1_field2_qs) - ); - - // F[field3]: 15:15 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr1_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr1_we), - .wd (csr1_field3_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr1.field3.q), - .ds (), - - // to register interface (read) - .qs (csr1_field3_qs) - ); - - // F[field4]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_csr1_field4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr1_we), - .wd (csr1_field4_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr1.field4.q), - .ds (), - - // to register interface (read) - .qs (csr1_field4_qs) - ); - - - // R[csr2]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr2_we), - .wd (csr2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr2.q), - .ds (), - - // to register interface (read) - .qs (csr2_qs) - ); - - - // R[csr3]: V(False) - // F[field0]: 2:0 - prim_subreg #( - .DW (3), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (3'h0), - .Mubi (1'b0) - ) u_csr3_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr3_we), - .wd (csr3_field0_wd), - - // from internal hardware - .de (hw2reg.csr3.field0.de), - .d (hw2reg.csr3.field0.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field0.q), - .ds (), - - // to register interface (read) - .qs (csr3_field0_qs) - ); - - // F[field1]: 13:4 - prim_subreg #( - .DW (10), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (10'h0), - .Mubi (1'b0) - ) u_csr3_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr3_we), - .wd (csr3_field1_wd), - - // from internal hardware - .de (hw2reg.csr3.field1.de), - .d (hw2reg.csr3.field1.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field1.q), - .ds (), - - // to register interface (read) - .qs (csr3_field1_qs) - ); - - // F[field2]: 16:16 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr3_we), - .wd (csr3_field2_wd), - - // from internal hardware - .de (hw2reg.csr3.field2.de), - .d (hw2reg.csr3.field2.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field2.q), - .ds (), - - // to register interface (read) - .qs (csr3_field2_qs) - ); - - // F[field3]: 17:17 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field3.de), - .d (hw2reg.csr3.field3.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field3.q), - .ds (), - - // to register interface (read) - .qs (csr3_field3_qs) - ); - - // F[field4]: 18:18 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field4.de), - .d (hw2reg.csr3.field4.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field4.q), - .ds (), - - // to register interface (read) - .qs (csr3_field4_qs) - ); - - // F[field5]: 19:19 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field5 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field5.de), - .d (hw2reg.csr3.field5.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field5.q), - .ds (), - - // to register interface (read) - .qs (csr3_field5_qs) - ); - - // F[field6]: 20:20 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field6 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field6.de), - .d (hw2reg.csr3.field6.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field6.q), - .ds (), - - // to register interface (read) - .qs (csr3_field6_qs) - ); - - // F[field7]: 21:21 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field7 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field7.de), - .d (hw2reg.csr3.field7.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field7.q), - .ds (), - - // to register interface (read) - .qs (csr3_field7_qs) - ); - - // F[field8]: 22:22 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr3_field8 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr3.field8.de), - .d (hw2reg.csr3.field8.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr3.field8.q), - .ds (), - - // to register interface (read) - .qs (csr3_field8_qs) - ); - - - // R[csr4]: V(False) - // F[field0]: 9:0 - prim_subreg #( - .DW (10), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (10'h0), - .Mubi (1'b0) - ) u_csr4_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr4_we), - .wd (csr4_field0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr4.field0.q), - .ds (), - - // to register interface (read) - .qs (csr4_field0_qs) - ); - - // F[field1]: 12:12 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr4_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr4_we), - .wd (csr4_field1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr4.field1.q), - .ds (), - - // to register interface (read) - .qs (csr4_field1_qs) - ); - - // F[field2]: 13:13 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr4_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr4_we), - .wd (csr4_field2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr4.field2.q), - .ds (), - - // to register interface (read) - .qs (csr4_field2_qs) - ); - - // F[field3]: 14:14 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr4_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr4_we), - .wd (csr4_field3_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr4.field3.q), - .ds (), - - // to register interface (read) - .qs (csr4_field3_qs) - ); - - - // R[csr5]: V(False) - // F[field0]: 5:0 - prim_subreg #( - .DW (6), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (6'h0), - .Mubi (1'b0) - ) u_csr5_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr5_we), - .wd (csr5_field0_wd), - - // from internal hardware - .de (hw2reg.csr5.field0.de), - .d (hw2reg.csr5.field0.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field0.q), - .ds (), - - // to register interface (read) - .qs (csr5_field0_qs) - ); - - // F[field1]: 7:6 - prim_subreg #( - .DW (2), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (2'h0), - .Mubi (1'b0) - ) u_csr5_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr5_we), - .wd (csr5_field1_wd), - - // from internal hardware - .de (hw2reg.csr5.field1.de), - .d (hw2reg.csr5.field1.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field1.q), - .ds (), - - // to register interface (read) - .qs (csr5_field1_qs) - ); - - // F[field2]: 8:8 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr5_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr5.field2.de), - .d (hw2reg.csr5.field2.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field2.q), - .ds (), - - // to register interface (read) - .qs (csr5_field2_qs) - ); - - // F[field3]: 11:9 - prim_subreg #( - .DW (3), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (3'h0), - .Mubi (1'b0) - ) u_csr5_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr5.field3.de), - .d (hw2reg.csr5.field3.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field3.q), - .ds (), - - // to register interface (read) - .qs (csr5_field3_qs) - ); - - // F[field4]: 12:12 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr5_field4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr5.field4.de), - .d (hw2reg.csr5.field4.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field4.q), - .ds (), - - // to register interface (read) - .qs (csr5_field4_qs) - ); - - // F[field5]: 13:13 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr5_field5 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr5.field5.de), - .d (hw2reg.csr5.field5.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field5.q), - .ds (), - - // to register interface (read) - .qs (csr5_field5_qs) - ); - - // F[field6]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_csr5_field6 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr5_we), - .wd (csr5_field6_wd), - - // from internal hardware - .de (hw2reg.csr5.field6.de), - .d (hw2reg.csr5.field6.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr5.field6.q), - .ds (), - - // to register interface (read) - .qs (csr5_field6_qs) - ); - - - // R[csr6]: V(False) - // F[field0]: 9:0 - prim_subreg #( - .DW (10), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (10'h0), - .Mubi (1'b0) - ) u_csr6_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr6_we), - .wd (csr6_field0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr6.field0.q), - .ds (), - - // to register interface (read) - .qs (csr6_field0_qs) - ); - - // F[field1]: 11:11 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr6_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr6_we), - .wd (csr6_field1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr6.field1.q), - .ds (), - - // to register interface (read) - .qs (csr6_field1_qs) - ); - - // F[field2]: 12:12 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr6_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr6_we), - .wd (csr6_field2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr6.field2.q), - .ds (), - - // to register interface (read) - .qs (csr6_field2_qs) - ); - - // F[field3]: 31:16 - prim_subreg #( - .DW (16), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (16'h0), - .Mubi (1'b0) - ) u_csr6_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (csr6_we), - .wd (csr6_field3_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.csr6.field3.q), - .ds (), - - // to register interface (read) - .qs (csr6_field3_qs) - ); - - - // R[csr7]: V(False) - // F[field0]: 5:0 - prim_subreg #( - .DW (6), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (6'h0), - .Mubi (1'b0) - ) u_csr7_field0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr7.field0.de), - .d (hw2reg.csr7.field0.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr7.field0.q), - .ds (), - - // to register interface (read) - .qs (csr7_field0_qs) - ); - - // F[field1]: 10:8 - prim_subreg #( - .DW (3), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (3'h0), - .Mubi (1'b0) - ) u_csr7_field1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr7.field1.de), - .d (hw2reg.csr7.field1.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr7.field1.q), - .ds (), - - // to register interface (read) - .qs (csr7_field1_qs) - ); - - // F[field2]: 14:14 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr7_field2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr7.field2.de), - .d (hw2reg.csr7.field2.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr7.field2.q), - .ds (), - - // to register interface (read) - .qs (csr7_field2_qs) - ); - - // F[field3]: 15:15 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_csr7_field3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.csr7.field3.de), - .d (hw2reg.csr7.field3.d), - - // to internal hardware - .qe (), - .q (reg2hw.csr7.field3.q), - .ds (), - - // to register interface (read) - .qs (csr7_field3_qs) - ); - - - - logic [7:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[0] = (reg_addr == OTP_CTRL_CSR0_OFFSET); - addr_hit[1] = (reg_addr == OTP_CTRL_CSR1_OFFSET); - addr_hit[2] = (reg_addr == OTP_CTRL_CSR2_OFFSET); - addr_hit[3] = (reg_addr == OTP_CTRL_CSR3_OFFSET); - addr_hit[4] = (reg_addr == OTP_CTRL_CSR4_OFFSET); - addr_hit[5] = (reg_addr == OTP_CTRL_CSR5_OFFSET); - addr_hit[6] = (reg_addr == OTP_CTRL_CSR6_OFFSET); - addr_hit[7] = (reg_addr == OTP_CTRL_CSR7_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[0] & (|(OTP_CTRL_PRIM_PERMIT[0] & ~reg_be))) | - (addr_hit[1] & (|(OTP_CTRL_PRIM_PERMIT[1] & ~reg_be))) | - (addr_hit[2] & (|(OTP_CTRL_PRIM_PERMIT[2] & ~reg_be))) | - (addr_hit[3] & (|(OTP_CTRL_PRIM_PERMIT[3] & ~reg_be))) | - (addr_hit[4] & (|(OTP_CTRL_PRIM_PERMIT[4] & ~reg_be))) | - (addr_hit[5] & (|(OTP_CTRL_PRIM_PERMIT[5] & ~reg_be))) | - (addr_hit[6] & (|(OTP_CTRL_PRIM_PERMIT[6] & ~reg_be))) | - (addr_hit[7] & (|(OTP_CTRL_PRIM_PERMIT[7] & ~reg_be))))); - end - - // Generate write-enables - assign csr0_we = addr_hit[0] & reg_we & !reg_error; - - assign csr0_field0_wd = reg_wdata[0]; - - assign csr0_field1_wd = reg_wdata[1]; - - assign csr0_field2_wd = reg_wdata[2]; - - assign csr0_field3_wd = reg_wdata[13:4]; - - assign csr0_field4_wd = reg_wdata[26:16]; - assign csr1_we = addr_hit[1] & reg_we & !reg_error; - - assign csr1_field0_wd = reg_wdata[6:0]; - - assign csr1_field1_wd = reg_wdata[7]; - - assign csr1_field2_wd = reg_wdata[14:8]; - - assign csr1_field3_wd = reg_wdata[15]; - - assign csr1_field4_wd = reg_wdata[31:16]; - assign csr2_we = addr_hit[2] & reg_we & !reg_error; - - assign csr2_wd = reg_wdata[0]; - assign csr3_we = addr_hit[3] & reg_we & !reg_error; - - assign csr3_field0_wd = reg_wdata[2:0]; - - assign csr3_field1_wd = reg_wdata[13:4]; - - assign csr3_field2_wd = reg_wdata[16]; - assign csr4_we = addr_hit[4] & reg_we & !reg_error; - - assign csr4_field0_wd = reg_wdata[9:0]; - - assign csr4_field1_wd = reg_wdata[12]; - - assign csr4_field2_wd = reg_wdata[13]; - - assign csr4_field3_wd = reg_wdata[14]; - assign csr5_we = addr_hit[5] & reg_we & !reg_error; - - assign csr5_field0_wd = reg_wdata[5:0]; - - assign csr5_field1_wd = reg_wdata[7:6]; - - assign csr5_field6_wd = reg_wdata[31:16]; - assign csr6_we = addr_hit[6] & reg_we & !reg_error; - - assign csr6_field0_wd = reg_wdata[9:0]; - - assign csr6_field1_wd = reg_wdata[11]; - - assign csr6_field2_wd = reg_wdata[12]; - - assign csr6_field3_wd = reg_wdata[31:16]; - - // Assign write-enables to checker logic vector. - always_comb begin - reg_we_check = '0; - reg_we_check[0] = csr0_we; - reg_we_check[1] = csr1_we; - reg_we_check[2] = csr2_we; - reg_we_check[3] = csr3_we; - reg_we_check[4] = csr4_we; - reg_we_check[5] = csr5_we; - reg_we_check[6] = csr6_we; - reg_we_check[7] = 1'b0; - end - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[0] = csr0_field0_qs; - reg_rdata_next[1] = csr0_field1_qs; - reg_rdata_next[2] = csr0_field2_qs; - reg_rdata_next[13:4] = csr0_field3_qs; - reg_rdata_next[26:16] = csr0_field4_qs; - end - - addr_hit[1]: begin - reg_rdata_next[6:0] = csr1_field0_qs; - reg_rdata_next[7] = csr1_field1_qs; - reg_rdata_next[14:8] = csr1_field2_qs; - reg_rdata_next[15] = csr1_field3_qs; - reg_rdata_next[31:16] = csr1_field4_qs; - end - - addr_hit[2]: begin - reg_rdata_next[0] = csr2_qs; - end - - addr_hit[3]: begin - reg_rdata_next[2:0] = csr3_field0_qs; - reg_rdata_next[13:4] = csr3_field1_qs; - reg_rdata_next[16] = csr3_field2_qs; - reg_rdata_next[17] = csr3_field3_qs; - reg_rdata_next[18] = csr3_field4_qs; - reg_rdata_next[19] = csr3_field5_qs; - reg_rdata_next[20] = csr3_field6_qs; - reg_rdata_next[21] = csr3_field7_qs; - reg_rdata_next[22] = csr3_field8_qs; - end - - addr_hit[4]: begin - reg_rdata_next[9:0] = csr4_field0_qs; - reg_rdata_next[12] = csr4_field1_qs; - reg_rdata_next[13] = csr4_field2_qs; - reg_rdata_next[14] = csr4_field3_qs; - end - - addr_hit[5]: begin - reg_rdata_next[5:0] = csr5_field0_qs; - reg_rdata_next[7:6] = csr5_field1_qs; - reg_rdata_next[8] = csr5_field2_qs; - reg_rdata_next[11:9] = csr5_field3_qs; - reg_rdata_next[12] = csr5_field4_qs; - reg_rdata_next[13] = csr5_field5_qs; - reg_rdata_next[31:16] = csr5_field6_qs; - end - - addr_hit[6]: begin - reg_rdata_next[9:0] = csr6_field0_qs; - reg_rdata_next[11] = csr6_field1_qs; - reg_rdata_next[12] = csr6_field2_qs; - reg_rdata_next[31:16] = csr6_field3_qs; - end - - addr_hit[7]: begin - reg_rdata_next[5:0] = csr7_field0_qs; - reg_rdata_next[10:8] = csr7_field1_qs; - reg_rdata_next[14] = csr7_field2_qs; - reg_rdata_next[15] = csr7_field3_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // shadow busy - logic shadow_busy; - assign shadow_busy = 1'b0; - - // register busy - assign reg_busy = shadow_busy; - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) - `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) - - `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) - - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) - - // this is formulated as an assumption such that the FPV testbenches do disprove this - // property by mistake - //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis) - -endmodule diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_pkg.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_pkg.sv deleted file mode 100644 index f03c323fd7e9b..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_pkg.sv +++ /dev/null @@ -1,1161 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Package auto-generated by `reggen` containing data structure - -package otp_ctrl_reg_pkg; - - // Param list - parameter int NumSramKeyReqSlots = 4; - parameter int OtpByteAddrWidth = 11; - parameter int NumErrorEntries = 13; - parameter int NumDaiWords = 2; - parameter int NumDigestWords = 2; - parameter int NumSwCfgWindowWords = 512; - parameter int NumPart = 11; - parameter int NumPartUnbuf = 5; - parameter int NumPartBuf = 6; - parameter int VendorTestOffset = 0; - parameter int VendorTestSize = 64; - parameter int ScratchOffset = 0; - parameter int ScratchSize = 56; - parameter int VendorTestDigestOffset = 56; - parameter int VendorTestDigestSize = 8; - parameter int CreatorSwCfgOffset = 64; - parameter int CreatorSwCfgSize = 368; - parameter int CreatorSwCfgAstCfgOffset = 64; - parameter int CreatorSwCfgAstCfgSize = 156; - parameter int CreatorSwCfgAstInitEnOffset = 220; - parameter int CreatorSwCfgAstInitEnSize = 4; - parameter int CreatorSwCfgRomExtSkuOffset = 224; - parameter int CreatorSwCfgRomExtSkuSize = 4; - parameter int CreatorSwCfgSigverifySpxEnOffset = 228; - parameter int CreatorSwCfgSigverifySpxEnSize = 4; - parameter int CreatorSwCfgFlashDataDefaultCfgOffset = 232; - parameter int CreatorSwCfgFlashDataDefaultCfgSize = 4; - parameter int CreatorSwCfgFlashInfoBootDataCfgOffset = 236; - parameter int CreatorSwCfgFlashInfoBootDataCfgSize = 4; - parameter int CreatorSwCfgFlashHwInfoCfgOverrideOffset = 240; - parameter int CreatorSwCfgFlashHwInfoCfgOverrideSize = 4; - parameter int CreatorSwCfgRngEnOffset = 244; - parameter int CreatorSwCfgRngEnSize = 4; - parameter int CreatorSwCfgJitterEnOffset = 248; - parameter int CreatorSwCfgJitterEnSize = 4; - parameter int CreatorSwCfgRetRamResetMaskOffset = 252; - parameter int CreatorSwCfgRetRamResetMaskSize = 4; - parameter int CreatorSwCfgManufStateOffset = 256; - parameter int CreatorSwCfgManufStateSize = 4; - parameter int CreatorSwCfgRomExecEnOffset = 260; - parameter int CreatorSwCfgRomExecEnSize = 4; - parameter int CreatorSwCfgCpuctrlOffset = 264; - parameter int CreatorSwCfgCpuctrlSize = 4; - parameter int CreatorSwCfgMinSecVerRomExtOffset = 268; - parameter int CreatorSwCfgMinSecVerRomExtSize = 4; - parameter int CreatorSwCfgMinSecVerBl0Offset = 272; - parameter int CreatorSwCfgMinSecVerBl0Size = 4; - parameter int CreatorSwCfgDefaultBootDataInProdEnOffset = 276; - parameter int CreatorSwCfgDefaultBootDataInProdEnSize = 4; - parameter int CreatorSwCfgRmaSpinEnOffset = 280; - parameter int CreatorSwCfgRmaSpinEnSize = 4; - parameter int CreatorSwCfgRmaSpinCyclesOffset = 284; - parameter int CreatorSwCfgRmaSpinCyclesSize = 4; - parameter int CreatorSwCfgRngRepcntThresholdsOffset = 288; - parameter int CreatorSwCfgRngRepcntThresholdsSize = 4; - parameter int CreatorSwCfgRngRepcntsThresholdsOffset = 292; - parameter int CreatorSwCfgRngRepcntsThresholdsSize = 4; - parameter int CreatorSwCfgRngAdaptpHiThresholdsOffset = 296; - parameter int CreatorSwCfgRngAdaptpHiThresholdsSize = 4; - parameter int CreatorSwCfgRngAdaptpLoThresholdsOffset = 300; - parameter int CreatorSwCfgRngAdaptpLoThresholdsSize = 4; - parameter int CreatorSwCfgRngBucketThresholdsOffset = 304; - parameter int CreatorSwCfgRngBucketThresholdsSize = 4; - parameter int CreatorSwCfgRngMarkovHiThresholdsOffset = 308; - parameter int CreatorSwCfgRngMarkovHiThresholdsSize = 4; - parameter int CreatorSwCfgRngMarkovLoThresholdsOffset = 312; - parameter int CreatorSwCfgRngMarkovLoThresholdsSize = 4; - parameter int CreatorSwCfgRngExthtHiThresholdsOffset = 316; - parameter int CreatorSwCfgRngExthtHiThresholdsSize = 4; - parameter int CreatorSwCfgRngExthtLoThresholdsOffset = 320; - parameter int CreatorSwCfgRngExthtLoThresholdsSize = 4; - parameter int CreatorSwCfgRngAlertThresholdOffset = 324; - parameter int CreatorSwCfgRngAlertThresholdSize = 4; - parameter int CreatorSwCfgRngHealthConfigDigestOffset = 328; - parameter int CreatorSwCfgRngHealthConfigDigestSize = 4; - parameter int CreatorSwCfgSramKeyRenewEnOffset = 332; - parameter int CreatorSwCfgSramKeyRenewEnSize = 4; - parameter int CreatorSwCfgImmutableRomExtEnOffset = 336; - parameter int CreatorSwCfgImmutableRomExtEnSize = 4; - parameter int CreatorSwCfgImmutableRomExtStartOffsetOffset = 340; - parameter int CreatorSwCfgImmutableRomExtStartOffsetSize = 4; - parameter int CreatorSwCfgImmutableRomExtLengthOffset = 344; - parameter int CreatorSwCfgImmutableRomExtLengthSize = 4; - parameter int CreatorSwCfgImmutableRomExtSha256HashOffset = 348; - parameter int CreatorSwCfgImmutableRomExtSha256HashSize = 32; - parameter int CreatorSwCfgReservedOffset = 380; - parameter int CreatorSwCfgReservedSize = 32; - parameter int CreatorSwCfgDigestOffset = 424; - parameter int CreatorSwCfgDigestSize = 8; - parameter int OwnerSwCfgOffset = 432; - parameter int OwnerSwCfgSize = 712; - parameter int OwnerSwCfgRomErrorReportingOffset = 432; - parameter int OwnerSwCfgRomErrorReportingSize = 4; - parameter int OwnerSwCfgRomBootstrapDisOffset = 436; - parameter int OwnerSwCfgRomBootstrapDisSize = 4; - parameter int OwnerSwCfgRomAlertClassEnOffset = 440; - parameter int OwnerSwCfgRomAlertClassEnSize = 4; - parameter int OwnerSwCfgRomAlertEscalationOffset = 444; - parameter int OwnerSwCfgRomAlertEscalationSize = 4; - parameter int OwnerSwCfgRomAlertClassificationOffset = 448; - parameter int OwnerSwCfgRomAlertClassificationSize = 320; - parameter int OwnerSwCfgRomLocalAlertClassificationOffset = 768; - parameter int OwnerSwCfgRomLocalAlertClassificationSize = 64; - parameter int OwnerSwCfgRomAlertAccumThreshOffset = 832; - parameter int OwnerSwCfgRomAlertAccumThreshSize = 16; - parameter int OwnerSwCfgRomAlertTimeoutCyclesOffset = 848; - parameter int OwnerSwCfgRomAlertTimeoutCyclesSize = 16; - parameter int OwnerSwCfgRomAlertPhaseCyclesOffset = 864; - parameter int OwnerSwCfgRomAlertPhaseCyclesSize = 64; - parameter int OwnerSwCfgRomAlertDigestProdOffset = 928; - parameter int OwnerSwCfgRomAlertDigestProdSize = 4; - parameter int OwnerSwCfgRomAlertDigestProdEndOffset = 932; - parameter int OwnerSwCfgRomAlertDigestProdEndSize = 4; - parameter int OwnerSwCfgRomAlertDigestDevOffset = 936; - parameter int OwnerSwCfgRomAlertDigestDevSize = 4; - parameter int OwnerSwCfgRomAlertDigestRmaOffset = 940; - parameter int OwnerSwCfgRomAlertDigestRmaSize = 4; - parameter int OwnerSwCfgRomWatchdogBiteThresholdCyclesOffset = 944; - parameter int OwnerSwCfgRomWatchdogBiteThresholdCyclesSize = 4; - parameter int OwnerSwCfgRomKeymgrOtpMeasEnOffset = 948; - parameter int OwnerSwCfgRomKeymgrOtpMeasEnSize = 4; - parameter int OwnerSwCfgManufStateOffset = 952; - parameter int OwnerSwCfgManufStateSize = 4; - parameter int OwnerSwCfgRomRstmgrInfoEnOffset = 956; - parameter int OwnerSwCfgRomRstmgrInfoEnSize = 4; - parameter int OwnerSwCfgRomExtBootstrapEnOffset = 960; - parameter int OwnerSwCfgRomExtBootstrapEnSize = 4; - parameter int OwnerSwCfgRomSensorCtrlAlertCfgOffset = 964; - parameter int OwnerSwCfgRomSensorCtrlAlertCfgSize = 12; - parameter int OwnerSwCfgRomSramReadbackEnOffset = 976; - parameter int OwnerSwCfgRomSramReadbackEnSize = 4; - parameter int OwnerSwCfgRomPreserveResetReasonEnOffset = 980; - parameter int OwnerSwCfgRomPreserveResetReasonEnSize = 4; - parameter int OwnerSwCfgRomResetReasonCheckValueOffset = 984; - parameter int OwnerSwCfgRomResetReasonCheckValueSize = 4; - parameter int OwnerSwCfgRomBannerEnOffset = 988; - parameter int OwnerSwCfgRomBannerEnSize = 4; - parameter int OwnerSwCfgRomFlashEccExcHandlerEnOffset = 992; - parameter int OwnerSwCfgRomFlashEccExcHandlerEnSize = 4; - parameter int OwnerSwCfgReservedOffset = 996; - parameter int OwnerSwCfgReservedSize = 128; - parameter int OwnerSwCfgDigestOffset = 1136; - parameter int OwnerSwCfgDigestSize = 8; - parameter int RotCreatorAuthCodesignOffset = 1144; - parameter int RotCreatorAuthCodesignSize = 472; - parameter int RotCreatorAuthCodesignEcdsaKeyType0Offset = 1144; - parameter int RotCreatorAuthCodesignEcdsaKeyType0Size = 4; - parameter int RotCreatorAuthCodesignEcdsaKey0Offset = 1148; - parameter int RotCreatorAuthCodesignEcdsaKey0Size = 64; - parameter int RotCreatorAuthCodesignEcdsaKeyType1Offset = 1212; - parameter int RotCreatorAuthCodesignEcdsaKeyType1Size = 4; - parameter int RotCreatorAuthCodesignEcdsaKey1Offset = 1216; - parameter int RotCreatorAuthCodesignEcdsaKey1Size = 64; - parameter int RotCreatorAuthCodesignEcdsaKeyType2Offset = 1280; - parameter int RotCreatorAuthCodesignEcdsaKeyType2Size = 4; - parameter int RotCreatorAuthCodesignEcdsaKey2Offset = 1284; - parameter int RotCreatorAuthCodesignEcdsaKey2Size = 64; - parameter int RotCreatorAuthCodesignEcdsaKeyType3Offset = 1348; - parameter int RotCreatorAuthCodesignEcdsaKeyType3Size = 4; - parameter int RotCreatorAuthCodesignEcdsaKey3Offset = 1352; - parameter int RotCreatorAuthCodesignEcdsaKey3Size = 64; - parameter int RotCreatorAuthCodesignSpxKeyType0Offset = 1416; - parameter int RotCreatorAuthCodesignSpxKeyType0Size = 4; - parameter int RotCreatorAuthCodesignSpxKey0Offset = 1420; - parameter int RotCreatorAuthCodesignSpxKey0Size = 32; - parameter int RotCreatorAuthCodesignSpxKeyConfig0Offset = 1452; - parameter int RotCreatorAuthCodesignSpxKeyConfig0Size = 4; - parameter int RotCreatorAuthCodesignSpxKeyType1Offset = 1456; - parameter int RotCreatorAuthCodesignSpxKeyType1Size = 4; - parameter int RotCreatorAuthCodesignSpxKey1Offset = 1460; - parameter int RotCreatorAuthCodesignSpxKey1Size = 32; - parameter int RotCreatorAuthCodesignSpxKeyConfig1Offset = 1492; - parameter int RotCreatorAuthCodesignSpxKeyConfig1Size = 4; - parameter int RotCreatorAuthCodesignSpxKeyType2Offset = 1496; - parameter int RotCreatorAuthCodesignSpxKeyType2Size = 4; - parameter int RotCreatorAuthCodesignSpxKey2Offset = 1500; - parameter int RotCreatorAuthCodesignSpxKey2Size = 32; - parameter int RotCreatorAuthCodesignSpxKeyConfig2Offset = 1532; - parameter int RotCreatorAuthCodesignSpxKeyConfig2Size = 4; - parameter int RotCreatorAuthCodesignSpxKeyType3Offset = 1536; - parameter int RotCreatorAuthCodesignSpxKeyType3Size = 4; - parameter int RotCreatorAuthCodesignSpxKey3Offset = 1540; - parameter int RotCreatorAuthCodesignSpxKey3Size = 32; - parameter int RotCreatorAuthCodesignSpxKeyConfig3Offset = 1572; - parameter int RotCreatorAuthCodesignSpxKeyConfig3Size = 4; - parameter int RotCreatorAuthCodesignBlockSha2_256HashOffset = 1576; - parameter int RotCreatorAuthCodesignBlockSha2_256HashSize = 32; - parameter int RotCreatorAuthCodesignDigestOffset = 1608; - parameter int RotCreatorAuthCodesignDigestSize = 8; - parameter int RotCreatorAuthStateOffset = 1616; - parameter int RotCreatorAuthStateSize = 40; - parameter int RotCreatorAuthStateEcdsaKey0Offset = 1616; - parameter int RotCreatorAuthStateEcdsaKey0Size = 4; - parameter int RotCreatorAuthStateEcdsaKey1Offset = 1620; - parameter int RotCreatorAuthStateEcdsaKey1Size = 4; - parameter int RotCreatorAuthStateEcdsaKey2Offset = 1624; - parameter int RotCreatorAuthStateEcdsaKey2Size = 4; - parameter int RotCreatorAuthStateEcdsaKey3Offset = 1628; - parameter int RotCreatorAuthStateEcdsaKey3Size = 4; - parameter int RotCreatorAuthStateSpxKey0Offset = 1632; - parameter int RotCreatorAuthStateSpxKey0Size = 4; - parameter int RotCreatorAuthStateSpxKey1Offset = 1636; - parameter int RotCreatorAuthStateSpxKey1Size = 4; - parameter int RotCreatorAuthStateSpxKey2Offset = 1640; - parameter int RotCreatorAuthStateSpxKey2Size = 4; - parameter int RotCreatorAuthStateSpxKey3Offset = 1644; - parameter int RotCreatorAuthStateSpxKey3Size = 4; - parameter int RotCreatorAuthStateDigestOffset = 1648; - parameter int RotCreatorAuthStateDigestSize = 8; - parameter int HwCfg0Offset = 1656; - parameter int HwCfg0Size = 72; - parameter int DeviceIdOffset = 1656; - parameter int DeviceIdSize = 32; - parameter int ManufStateOffset = 1688; - parameter int ManufStateSize = 32; - parameter int HwCfg0DigestOffset = 1720; - parameter int HwCfg0DigestSize = 8; - parameter int HwCfg1Offset = 1728; - parameter int HwCfg1Size = 16; - parameter int EnSramIfetchOffset = 1728; - parameter int EnSramIfetchSize = 1; - parameter int EnCsrngSwAppReadOffset = 1729; - parameter int EnCsrngSwAppReadSize = 1; - parameter int DisRvDmLateDebugOffset = 1730; - parameter int DisRvDmLateDebugSize = 1; - parameter int HwCfg1DigestOffset = 1736; - parameter int HwCfg1DigestSize = 8; - parameter int Secret0Offset = 1744; - parameter int Secret0Size = 40; - parameter int TestUnlockTokenOffset = 1744; - parameter int TestUnlockTokenSize = 16; - parameter int TestExitTokenOffset = 1760; - parameter int TestExitTokenSize = 16; - parameter int Secret0DigestOffset = 1776; - parameter int Secret0DigestSize = 8; - parameter int Secret1Offset = 1784; - parameter int Secret1Size = 88; - parameter int FlashAddrKeySeedOffset = 1784; - parameter int FlashAddrKeySeedSize = 32; - parameter int FlashDataKeySeedOffset = 1816; - parameter int FlashDataKeySeedSize = 32; - parameter int SramDataKeySeedOffset = 1848; - parameter int SramDataKeySeedSize = 16; - parameter int Secret1DigestOffset = 1864; - parameter int Secret1DigestSize = 8; - parameter int Secret2Offset = 1872; - parameter int Secret2Size = 88; - parameter int RmaTokenOffset = 1872; - parameter int RmaTokenSize = 16; - parameter int CreatorRootKeyShare0Offset = 1888; - parameter int CreatorRootKeyShare0Size = 32; - parameter int CreatorRootKeyShare1Offset = 1920; - parameter int CreatorRootKeyShare1Size = 32; - parameter int Secret2DigestOffset = 1952; - parameter int Secret2DigestSize = 8; - parameter int LifeCycleOffset = 1960; - parameter int LifeCycleSize = 88; - parameter int LcTransitionCntOffset = 1960; - parameter int LcTransitionCntSize = 48; - parameter int LcStateOffset = 2008; - parameter int LcStateSize = 40; - parameter int NumAlerts = 5; - - // Address widths within the block - parameter int CoreAw = 12; - parameter int PrimAw = 5; - - /////////////////////////////////////////////// - // Typedefs for registers for core interface // - /////////////////////////////////////////////// - - typedef struct packed { - struct packed { - logic q; - } otp_error; - struct packed { - logic q; - } otp_operation_done; - } otp_ctrl_reg2hw_intr_state_reg_t; - - typedef struct packed { - struct packed { - logic q; - } otp_error; - struct packed { - logic q; - } otp_operation_done; - } otp_ctrl_reg2hw_intr_enable_reg_t; - - typedef struct packed { - struct packed { - logic q; - logic qe; - } otp_error; - struct packed { - logic q; - logic qe; - } otp_operation_done; - } otp_ctrl_reg2hw_intr_test_reg_t; - - typedef struct packed { - struct packed { - logic q; - logic qe; - } recov_prim_otp_alert; - struct packed { - logic q; - logic qe; - } fatal_prim_otp_alert; - struct packed { - logic q; - logic qe; - } fatal_bus_integ_error; - struct packed { - logic q; - logic qe; - } fatal_check_error; - struct packed { - logic q; - logic qe; - } fatal_macro_error; - } otp_ctrl_reg2hw_alert_test_reg_t; - - typedef struct packed { - logic q; - logic qe; - } otp_ctrl_reg2hw_direct_access_regwen_reg_t; - - typedef struct packed { - struct packed { - logic q; - logic qe; - } digest; - struct packed { - logic q; - logic qe; - } wr; - struct packed { - logic q; - logic qe; - } rd; - } otp_ctrl_reg2hw_direct_access_cmd_reg_t; - - typedef struct packed { - logic [10:0] q; - } otp_ctrl_reg2hw_direct_access_address_reg_t; - - typedef struct packed { - logic [31:0] q; - } otp_ctrl_reg2hw_direct_access_wdata_mreg_t; - - typedef struct packed { - struct packed { - logic q; - logic qe; - } consistency; - struct packed { - logic q; - logic qe; - } integrity; - } otp_ctrl_reg2hw_check_trigger_reg_t; - - typedef struct packed { - logic [31:0] q; - } otp_ctrl_reg2hw_check_timeout_reg_t; - - typedef struct packed { - logic [31:0] q; - } otp_ctrl_reg2hw_integrity_check_period_reg_t; - - typedef struct packed { - logic [31:0] q; - } otp_ctrl_reg2hw_consistency_check_period_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_vendor_test_read_lock_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_creator_sw_cfg_read_lock_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_owner_sw_cfg_read_lock_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_rot_creator_auth_codesign_read_lock_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_rot_creator_auth_state_read_lock_reg_t; - - typedef struct packed { - struct packed { - logic d; - logic de; - } otp_operation_done; - struct packed { - logic d; - logic de; - } otp_error; - } otp_ctrl_hw2reg_intr_state_reg_t; - - typedef struct packed { - struct packed { - logic d; - } vendor_test_error; - struct packed { - logic d; - } creator_sw_cfg_error; - struct packed { - logic d; - } owner_sw_cfg_error; - struct packed { - logic d; - } rot_creator_auth_codesign_error; - struct packed { - logic d; - } rot_creator_auth_state_error; - struct packed { - logic d; - } hw_cfg0_error; - struct packed { - logic d; - } hw_cfg1_error; - struct packed { - logic d; - } secret0_error; - struct packed { - logic d; - } secret1_error; - struct packed { - logic d; - } secret2_error; - struct packed { - logic d; - } life_cycle_error; - struct packed { - logic d; - } dai_error; - struct packed { - logic d; - } lci_error; - struct packed { - logic d; - } timeout_error; - struct packed { - logic d; - } lfsr_fsm_error; - struct packed { - logic d; - } scrambling_fsm_error; - struct packed { - logic d; - } key_deriv_fsm_error; - struct packed { - logic d; - } bus_integ_error; - struct packed { - logic d; - } dai_idle; - struct packed { - logic d; - } check_pending; - } otp_ctrl_hw2reg_status_reg_t; - - typedef struct packed { - logic [2:0] d; - } otp_ctrl_hw2reg_err_code_mreg_t; - - typedef struct packed { - logic d; - } otp_ctrl_hw2reg_direct_access_regwen_reg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_direct_access_rdata_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_vendor_test_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_creator_sw_cfg_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_owner_sw_cfg_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_rot_creator_auth_codesign_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_rot_creator_auth_state_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_hw_cfg0_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_hw_cfg1_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_secret0_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_secret1_digest_mreg_t; - - typedef struct packed { - logic [31:0] d; - } otp_ctrl_hw2reg_secret2_digest_mreg_t; - - // Register -> HW type for core interface - typedef struct packed { - otp_ctrl_reg2hw_intr_state_reg_t intr_state; // [205:204] - otp_ctrl_reg2hw_intr_enable_reg_t intr_enable; // [203:202] - otp_ctrl_reg2hw_intr_test_reg_t intr_test; // [201:198] - otp_ctrl_reg2hw_alert_test_reg_t alert_test; // [197:188] - otp_ctrl_reg2hw_direct_access_regwen_reg_t direct_access_regwen; // [187:186] - otp_ctrl_reg2hw_direct_access_cmd_reg_t direct_access_cmd; // [185:180] - otp_ctrl_reg2hw_direct_access_address_reg_t direct_access_address; // [179:169] - otp_ctrl_reg2hw_direct_access_wdata_mreg_t [1:0] direct_access_wdata; // [168:105] - otp_ctrl_reg2hw_check_trigger_reg_t check_trigger; // [104:101] - otp_ctrl_reg2hw_check_timeout_reg_t check_timeout; // [100:69] - otp_ctrl_reg2hw_integrity_check_period_reg_t integrity_check_period; // [68:37] - otp_ctrl_reg2hw_consistency_check_period_reg_t consistency_check_period; // [36:5] - otp_ctrl_reg2hw_vendor_test_read_lock_reg_t vendor_test_read_lock; // [4:4] - otp_ctrl_reg2hw_creator_sw_cfg_read_lock_reg_t creator_sw_cfg_read_lock; // [3:3] - otp_ctrl_reg2hw_owner_sw_cfg_read_lock_reg_t owner_sw_cfg_read_lock; // [2:2] - otp_ctrl_reg2hw_rot_creator_auth_codesign_read_lock_reg_t - rot_creator_auth_codesign_read_lock; // [1:1] - otp_ctrl_reg2hw_rot_creator_auth_state_read_lock_reg_t - rot_creator_auth_state_read_lock; // [0:0] - } otp_ctrl_core_reg2hw_t; - - // HW -> register type for core interface - typedef struct packed { - otp_ctrl_hw2reg_intr_state_reg_t intr_state; // [767:764] - otp_ctrl_hw2reg_status_reg_t status; // [763:744] - otp_ctrl_hw2reg_err_code_mreg_t [12:0] err_code; // [743:705] - otp_ctrl_hw2reg_direct_access_regwen_reg_t direct_access_regwen; // [704:704] - otp_ctrl_hw2reg_direct_access_rdata_mreg_t [1:0] direct_access_rdata; // [703:640] - otp_ctrl_hw2reg_vendor_test_digest_mreg_t [1:0] vendor_test_digest; // [639:576] - otp_ctrl_hw2reg_creator_sw_cfg_digest_mreg_t [1:0] creator_sw_cfg_digest; // [575:512] - otp_ctrl_hw2reg_owner_sw_cfg_digest_mreg_t [1:0] owner_sw_cfg_digest; // [511:448] - otp_ctrl_hw2reg_rot_creator_auth_codesign_digest_mreg_t [1:0] - rot_creator_auth_codesign_digest; // [447:384] - otp_ctrl_hw2reg_rot_creator_auth_state_digest_mreg_t [1:0] - rot_creator_auth_state_digest; // [383:320] - otp_ctrl_hw2reg_hw_cfg0_digest_mreg_t [1:0] hw_cfg0_digest; // [319:256] - otp_ctrl_hw2reg_hw_cfg1_digest_mreg_t [1:0] hw_cfg1_digest; // [255:192] - otp_ctrl_hw2reg_secret0_digest_mreg_t [1:0] secret0_digest; // [191:128] - otp_ctrl_hw2reg_secret1_digest_mreg_t [1:0] secret1_digest; // [127:64] - otp_ctrl_hw2reg_secret2_digest_mreg_t [1:0] secret2_digest; // [63:0] - } otp_ctrl_core_hw2reg_t; - - // Register offsets for core interface - parameter logic [CoreAw-1:0] OTP_CTRL_INTR_STATE_OFFSET = 12'h 0; - parameter logic [CoreAw-1:0] OTP_CTRL_INTR_ENABLE_OFFSET = 12'h 4; - parameter logic [CoreAw-1:0] OTP_CTRL_INTR_TEST_OFFSET = 12'h 8; - parameter logic [CoreAw-1:0] OTP_CTRL_ALERT_TEST_OFFSET = 12'h c; - parameter logic [CoreAw-1:0] OTP_CTRL_STATUS_OFFSET = 12'h 10; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_0_OFFSET = 12'h 14; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_1_OFFSET = 12'h 18; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_2_OFFSET = 12'h 1c; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_3_OFFSET = 12'h 20; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_4_OFFSET = 12'h 24; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_5_OFFSET = 12'h 28; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_6_OFFSET = 12'h 2c; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_7_OFFSET = 12'h 30; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_8_OFFSET = 12'h 34; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_9_OFFSET = 12'h 38; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_10_OFFSET = 12'h 3c; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_11_OFFSET = 12'h 40; - parameter logic [CoreAw-1:0] OTP_CTRL_ERR_CODE_12_OFFSET = 12'h 44; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_REGWEN_OFFSET = 12'h 48; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_CMD_OFFSET = 12'h 4c; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_ADDRESS_OFFSET = 12'h 50; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_WDATA_0_OFFSET = 12'h 54; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_WDATA_1_OFFSET = 12'h 58; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_RDATA_0_OFFSET = 12'h 5c; - parameter logic [CoreAw-1:0] OTP_CTRL_DIRECT_ACCESS_RDATA_1_OFFSET = 12'h 60; - parameter logic [CoreAw-1:0] OTP_CTRL_CHECK_TRIGGER_REGWEN_OFFSET = 12'h 64; - parameter logic [CoreAw-1:0] OTP_CTRL_CHECK_TRIGGER_OFFSET = 12'h 68; - parameter logic [CoreAw-1:0] OTP_CTRL_CHECK_REGWEN_OFFSET = 12'h 6c; - parameter logic [CoreAw-1:0] OTP_CTRL_CHECK_TIMEOUT_OFFSET = 12'h 70; - parameter logic [CoreAw-1:0] OTP_CTRL_INTEGRITY_CHECK_PERIOD_OFFSET = 12'h 74; - parameter logic [CoreAw-1:0] OTP_CTRL_CONSISTENCY_CHECK_PERIOD_OFFSET = 12'h 78; - parameter logic [CoreAw-1:0] OTP_CTRL_VENDOR_TEST_READ_LOCK_OFFSET = 12'h 7c; - parameter logic [CoreAw-1:0] OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_OFFSET = 12'h 80; - parameter logic [CoreAw-1:0] OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OFFSET = 12'h 84; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_OFFSET = 12'h 88; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_OFFSET = 12'h 8c; - parameter logic [CoreAw-1:0] OTP_CTRL_VENDOR_TEST_DIGEST_0_OFFSET = 12'h 90; - parameter logic [CoreAw-1:0] OTP_CTRL_VENDOR_TEST_DIGEST_1_OFFSET = 12'h 94; - parameter logic [CoreAw-1:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_OFFSET = 12'h 98; - parameter logic [CoreAw-1:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_OFFSET = 12'h 9c; - parameter logic [CoreAw-1:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_0_OFFSET = 12'h a0; - parameter logic [CoreAw-1:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_1_OFFSET = 12'h a4; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_OFFSET = 12'h a8; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_OFFSET = 12'h ac; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_OFFSET = 12'h b0; - parameter logic [CoreAw-1:0] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_OFFSET = 12'h b4; - parameter logic [CoreAw-1:0] OTP_CTRL_HW_CFG0_DIGEST_0_OFFSET = 12'h b8; - parameter logic [CoreAw-1:0] OTP_CTRL_HW_CFG0_DIGEST_1_OFFSET = 12'h bc; - parameter logic [CoreAw-1:0] OTP_CTRL_HW_CFG1_DIGEST_0_OFFSET = 12'h c0; - parameter logic [CoreAw-1:0] OTP_CTRL_HW_CFG1_DIGEST_1_OFFSET = 12'h c4; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET0_DIGEST_0_OFFSET = 12'h c8; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET0_DIGEST_1_OFFSET = 12'h cc; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET1_DIGEST_0_OFFSET = 12'h d0; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET1_DIGEST_1_OFFSET = 12'h d4; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET2_DIGEST_0_OFFSET = 12'h d8; - parameter logic [CoreAw-1:0] OTP_CTRL_SECRET2_DIGEST_1_OFFSET = 12'h dc; - - // Reset values for hwext registers and their fields for core interface - parameter logic [1:0] OTP_CTRL_INTR_TEST_RESVAL = 2'h 0; - parameter logic [0:0] OTP_CTRL_INTR_TEST_OTP_OPERATION_DONE_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_INTR_TEST_OTP_ERROR_RESVAL = 1'h 0; - parameter logic [4:0] OTP_CTRL_ALERT_TEST_RESVAL = 5'h 0; - parameter logic [0:0] OTP_CTRL_ALERT_TEST_FATAL_MACRO_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_ALERT_TEST_FATAL_CHECK_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_ALERT_TEST_FATAL_BUS_INTEG_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_ALERT_TEST_FATAL_PRIM_OTP_ALERT_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_ALERT_TEST_RECOV_PRIM_OTP_ALERT_RESVAL = 1'h 0; - parameter logic [19:0] OTP_CTRL_STATUS_RESVAL = 20'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_VENDOR_TEST_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_CREATOR_SW_CFG_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_OWNER_SW_CFG_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_ROT_CREATOR_AUTH_CODESIGN_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_ROT_CREATOR_AUTH_STATE_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_HW_CFG0_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_HW_CFG1_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_SECRET0_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_SECRET1_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_SECRET2_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_LIFE_CYCLE_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_DAI_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_LCI_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_TIMEOUT_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_LFSR_FSM_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_SCRAMBLING_FSM_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_KEY_DERIV_FSM_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_BUS_INTEG_ERROR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_DAI_IDLE_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_STATUS_CHECK_PENDING_RESVAL = 1'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_0_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_0_ERR_CODE_0_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_1_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_1_ERR_CODE_1_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_2_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_2_ERR_CODE_2_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_3_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_3_ERR_CODE_3_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_4_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_4_ERR_CODE_4_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_5_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_5_ERR_CODE_5_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_6_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_6_ERR_CODE_6_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_7_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_7_ERR_CODE_7_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_8_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_8_ERR_CODE_8_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_9_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_9_ERR_CODE_9_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_10_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_10_ERR_CODE_10_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_11_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_11_ERR_CODE_11_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_12_RESVAL = 3'h 0; - parameter logic [2:0] OTP_CTRL_ERR_CODE_12_ERR_CODE_12_RESVAL = 3'h 0; - parameter logic [0:0] OTP_CTRL_DIRECT_ACCESS_REGWEN_RESVAL = 1'h 1; - parameter logic [0:0] OTP_CTRL_DIRECT_ACCESS_REGWEN_DIRECT_ACCESS_REGWEN_RESVAL = 1'h 1; - parameter logic [2:0] OTP_CTRL_DIRECT_ACCESS_CMD_RESVAL = 3'h 0; - parameter logic [0:0] OTP_CTRL_DIRECT_ACCESS_CMD_RD_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_DIRECT_ACCESS_CMD_WR_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_DIRECT_ACCESS_CMD_DIGEST_RESVAL = 1'h 0; - parameter logic [31:0] OTP_CTRL_DIRECT_ACCESS_RDATA_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_DIRECT_ACCESS_RDATA_0_DIRECT_ACCESS_RDATA_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_DIRECT_ACCESS_RDATA_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_DIRECT_ACCESS_RDATA_1_DIRECT_ACCESS_RDATA_1_RESVAL = 32'h 0; - parameter logic [1:0] OTP_CTRL_CHECK_TRIGGER_RESVAL = 2'h 0; - parameter logic [0:0] OTP_CTRL_CHECK_TRIGGER_INTEGRITY_RESVAL = 1'h 0; - parameter logic [0:0] OTP_CTRL_CHECK_TRIGGER_CONSISTENCY_RESVAL = 1'h 0; - parameter logic [31:0] OTP_CTRL_VENDOR_TEST_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_VENDOR_TEST_DIGEST_0_VENDOR_TEST_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_VENDOR_TEST_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_VENDOR_TEST_DIGEST_1_VENDOR_TEST_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_CREATOR_SW_CFG_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_CREATOR_SW_CFG_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_0_OWNER_SW_CFG_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_OWNER_SW_CFG_DIGEST_1_OWNER_SW_CFG_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] - OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_RESVAL = - 32'h 0; - parameter logic [31:0] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] - OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1_RESVAL = - 32'h 0; - parameter logic [31:0] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] - OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_ROT_CREATOR_AUTH_STATE_DIGEST_0_RESVAL = - 32'h 0; - parameter logic [31:0] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] - OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1_ROT_CREATOR_AUTH_STATE_DIGEST_1_RESVAL = - 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG0_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG0_DIGEST_0_HW_CFG0_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG0_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG0_DIGEST_1_HW_CFG0_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG1_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG1_DIGEST_0_HW_CFG1_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG1_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_HW_CFG1_DIGEST_1_HW_CFG1_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET0_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET0_DIGEST_0_SECRET0_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET0_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET0_DIGEST_1_SECRET0_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET1_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET1_DIGEST_0_SECRET1_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET1_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET1_DIGEST_1_SECRET1_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET2_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET2_DIGEST_0_SECRET2_DIGEST_0_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET2_DIGEST_1_RESVAL = 32'h 0; - parameter logic [31:0] OTP_CTRL_SECRET2_DIGEST_1_SECRET2_DIGEST_1_RESVAL = 32'h 0; - - // Window parameters for core interface - parameter logic [CoreAw-1:0] OTP_CTRL_SW_CFG_WINDOW_OFFSET = 12'h 800; - parameter int unsigned OTP_CTRL_SW_CFG_WINDOW_SIZE = 'h 800; - parameter int unsigned OTP_CTRL_SW_CFG_WINDOW_IDX = 0; - - // Register index for core interface - typedef enum int { - OTP_CTRL_INTR_STATE, - OTP_CTRL_INTR_ENABLE, - OTP_CTRL_INTR_TEST, - OTP_CTRL_ALERT_TEST, - OTP_CTRL_STATUS, - OTP_CTRL_ERR_CODE_0, - OTP_CTRL_ERR_CODE_1, - OTP_CTRL_ERR_CODE_2, - OTP_CTRL_ERR_CODE_3, - OTP_CTRL_ERR_CODE_4, - OTP_CTRL_ERR_CODE_5, - OTP_CTRL_ERR_CODE_6, - OTP_CTRL_ERR_CODE_7, - OTP_CTRL_ERR_CODE_8, - OTP_CTRL_ERR_CODE_9, - OTP_CTRL_ERR_CODE_10, - OTP_CTRL_ERR_CODE_11, - OTP_CTRL_ERR_CODE_12, - OTP_CTRL_DIRECT_ACCESS_REGWEN, - OTP_CTRL_DIRECT_ACCESS_CMD, - OTP_CTRL_DIRECT_ACCESS_ADDRESS, - OTP_CTRL_DIRECT_ACCESS_WDATA_0, - OTP_CTRL_DIRECT_ACCESS_WDATA_1, - OTP_CTRL_DIRECT_ACCESS_RDATA_0, - OTP_CTRL_DIRECT_ACCESS_RDATA_1, - OTP_CTRL_CHECK_TRIGGER_REGWEN, - OTP_CTRL_CHECK_TRIGGER, - OTP_CTRL_CHECK_REGWEN, - OTP_CTRL_CHECK_TIMEOUT, - OTP_CTRL_INTEGRITY_CHECK_PERIOD, - OTP_CTRL_CONSISTENCY_CHECK_PERIOD, - OTP_CTRL_VENDOR_TEST_READ_LOCK, - OTP_CTRL_CREATOR_SW_CFG_READ_LOCK, - OTP_CTRL_OWNER_SW_CFG_READ_LOCK, - OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK, - OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK, - OTP_CTRL_VENDOR_TEST_DIGEST_0, - OTP_CTRL_VENDOR_TEST_DIGEST_1, - OTP_CTRL_CREATOR_SW_CFG_DIGEST_0, - OTP_CTRL_CREATOR_SW_CFG_DIGEST_1, - OTP_CTRL_OWNER_SW_CFG_DIGEST_0, - OTP_CTRL_OWNER_SW_CFG_DIGEST_1, - OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0, - OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1, - OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0, - OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1, - OTP_CTRL_HW_CFG0_DIGEST_0, - OTP_CTRL_HW_CFG0_DIGEST_1, - OTP_CTRL_HW_CFG1_DIGEST_0, - OTP_CTRL_HW_CFG1_DIGEST_1, - OTP_CTRL_SECRET0_DIGEST_0, - OTP_CTRL_SECRET0_DIGEST_1, - OTP_CTRL_SECRET1_DIGEST_0, - OTP_CTRL_SECRET1_DIGEST_1, - OTP_CTRL_SECRET2_DIGEST_0, - OTP_CTRL_SECRET2_DIGEST_1 - } otp_ctrl_core_id_e; - - // Register width information to check illegal writes for core interface - parameter logic [3:0] OTP_CTRL_CORE_PERMIT [56] = '{ - 4'b 0001, // index[ 0] OTP_CTRL_INTR_STATE - 4'b 0001, // index[ 1] OTP_CTRL_INTR_ENABLE - 4'b 0001, // index[ 2] OTP_CTRL_INTR_TEST - 4'b 0001, // index[ 3] OTP_CTRL_ALERT_TEST - 4'b 0111, // index[ 4] OTP_CTRL_STATUS - 4'b 0001, // index[ 5] OTP_CTRL_ERR_CODE_0 - 4'b 0001, // index[ 6] OTP_CTRL_ERR_CODE_1 - 4'b 0001, // index[ 7] OTP_CTRL_ERR_CODE_2 - 4'b 0001, // index[ 8] OTP_CTRL_ERR_CODE_3 - 4'b 0001, // index[ 9] OTP_CTRL_ERR_CODE_4 - 4'b 0001, // index[10] OTP_CTRL_ERR_CODE_5 - 4'b 0001, // index[11] OTP_CTRL_ERR_CODE_6 - 4'b 0001, // index[12] OTP_CTRL_ERR_CODE_7 - 4'b 0001, // index[13] OTP_CTRL_ERR_CODE_8 - 4'b 0001, // index[14] OTP_CTRL_ERR_CODE_9 - 4'b 0001, // index[15] OTP_CTRL_ERR_CODE_10 - 4'b 0001, // index[16] OTP_CTRL_ERR_CODE_11 - 4'b 0001, // index[17] OTP_CTRL_ERR_CODE_12 - 4'b 0001, // index[18] OTP_CTRL_DIRECT_ACCESS_REGWEN - 4'b 0001, // index[19] OTP_CTRL_DIRECT_ACCESS_CMD - 4'b 0011, // index[20] OTP_CTRL_DIRECT_ACCESS_ADDRESS - 4'b 1111, // index[21] OTP_CTRL_DIRECT_ACCESS_WDATA_0 - 4'b 1111, // index[22] OTP_CTRL_DIRECT_ACCESS_WDATA_1 - 4'b 1111, // index[23] OTP_CTRL_DIRECT_ACCESS_RDATA_0 - 4'b 1111, // index[24] OTP_CTRL_DIRECT_ACCESS_RDATA_1 - 4'b 0001, // index[25] OTP_CTRL_CHECK_TRIGGER_REGWEN - 4'b 0001, // index[26] OTP_CTRL_CHECK_TRIGGER - 4'b 0001, // index[27] OTP_CTRL_CHECK_REGWEN - 4'b 1111, // index[28] OTP_CTRL_CHECK_TIMEOUT - 4'b 1111, // index[29] OTP_CTRL_INTEGRITY_CHECK_PERIOD - 4'b 1111, // index[30] OTP_CTRL_CONSISTENCY_CHECK_PERIOD - 4'b 0001, // index[31] OTP_CTRL_VENDOR_TEST_READ_LOCK - 4'b 0001, // index[32] OTP_CTRL_CREATOR_SW_CFG_READ_LOCK - 4'b 0001, // index[33] OTP_CTRL_OWNER_SW_CFG_READ_LOCK - 4'b 0001, // index[34] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK - 4'b 0001, // index[35] OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK - 4'b 1111, // index[36] OTP_CTRL_VENDOR_TEST_DIGEST_0 - 4'b 1111, // index[37] OTP_CTRL_VENDOR_TEST_DIGEST_1 - 4'b 1111, // index[38] OTP_CTRL_CREATOR_SW_CFG_DIGEST_0 - 4'b 1111, // index[39] OTP_CTRL_CREATOR_SW_CFG_DIGEST_1 - 4'b 1111, // index[40] OTP_CTRL_OWNER_SW_CFG_DIGEST_0 - 4'b 1111, // index[41] OTP_CTRL_OWNER_SW_CFG_DIGEST_1 - 4'b 1111, // index[42] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0 - 4'b 1111, // index[43] OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_1 - 4'b 1111, // index[44] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0 - 4'b 1111, // index[45] OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_1 - 4'b 1111, // index[46] OTP_CTRL_HW_CFG0_DIGEST_0 - 4'b 1111, // index[47] OTP_CTRL_HW_CFG0_DIGEST_1 - 4'b 1111, // index[48] OTP_CTRL_HW_CFG1_DIGEST_0 - 4'b 1111, // index[49] OTP_CTRL_HW_CFG1_DIGEST_1 - 4'b 1111, // index[50] OTP_CTRL_SECRET0_DIGEST_0 - 4'b 1111, // index[51] OTP_CTRL_SECRET0_DIGEST_1 - 4'b 1111, // index[52] OTP_CTRL_SECRET1_DIGEST_0 - 4'b 1111, // index[53] OTP_CTRL_SECRET1_DIGEST_1 - 4'b 1111, // index[54] OTP_CTRL_SECRET2_DIGEST_0 - 4'b 1111 // index[55] OTP_CTRL_SECRET2_DIGEST_1 - }; - - /////////////////////////////////////////////// - // Typedefs for registers for prim interface // - /////////////////////////////////////////////// - - typedef struct packed { - struct packed { - logic [10:0] q; - } field4; - struct packed { - logic [9:0] q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic q; - } field1; - struct packed { - logic q; - } field0; - } otp_ctrl_reg2hw_csr0_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } field4; - struct packed { - logic q; - } field3; - struct packed { - logic [6:0] q; - } field2; - struct packed { - logic q; - } field1; - struct packed { - logic [6:0] q; - } field0; - } otp_ctrl_reg2hw_csr1_reg_t; - - typedef struct packed { - logic q; - } otp_ctrl_reg2hw_csr2_reg_t; - - typedef struct packed { - struct packed { - logic q; - } field8; - struct packed { - logic q; - } field7; - struct packed { - logic q; - } field6; - struct packed { - logic q; - } field5; - struct packed { - logic q; - } field4; - struct packed { - logic q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic [9:0] q; - } field1; - struct packed { - logic [2:0] q; - } field0; - } otp_ctrl_reg2hw_csr3_reg_t; - - typedef struct packed { - struct packed { - logic q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic q; - } field1; - struct packed { - logic [9:0] q; - } field0; - } otp_ctrl_reg2hw_csr4_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } field6; - struct packed { - logic q; - } field5; - struct packed { - logic q; - } field4; - struct packed { - logic [2:0] q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic [1:0] q; - } field1; - struct packed { - logic [5:0] q; - } field0; - } otp_ctrl_reg2hw_csr5_reg_t; - - typedef struct packed { - struct packed { - logic [15:0] q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic q; - } field1; - struct packed { - logic [9:0] q; - } field0; - } otp_ctrl_reg2hw_csr6_reg_t; - - typedef struct packed { - struct packed { - logic q; - } field3; - struct packed { - logic q; - } field2; - struct packed { - logic [2:0] q; - } field1; - struct packed { - logic [5:0] q; - } field0; - } otp_ctrl_reg2hw_csr7_reg_t; - - typedef struct packed { - struct packed { - logic [2:0] d; - logic de; - } field0; - struct packed { - logic [9:0] d; - logic de; - } field1; - struct packed { - logic d; - logic de; - } field2; - struct packed { - logic d; - logic de; - } field3; - struct packed { - logic d; - logic de; - } field4; - struct packed { - logic d; - logic de; - } field5; - struct packed { - logic d; - logic de; - } field6; - struct packed { - logic d; - logic de; - } field7; - struct packed { - logic d; - logic de; - } field8; - } otp_ctrl_hw2reg_csr3_reg_t; - - typedef struct packed { - struct packed { - logic [5:0] d; - logic de; - } field0; - struct packed { - logic [1:0] d; - logic de; - } field1; - struct packed { - logic d; - logic de; - } field2; - struct packed { - logic [2:0] d; - logic de; - } field3; - struct packed { - logic d; - logic de; - } field4; - struct packed { - logic d; - logic de; - } field5; - struct packed { - logic [15:0] d; - logic de; - } field6; - } otp_ctrl_hw2reg_csr5_reg_t; - - typedef struct packed { - struct packed { - logic [5:0] d; - logic de; - } field0; - struct packed { - logic [2:0] d; - logic de; - } field1; - struct packed { - logic d; - logic de; - } field2; - struct packed { - logic d; - logic de; - } field3; - } otp_ctrl_hw2reg_csr7_reg_t; - - // Register -> HW type for prim interface - typedef struct packed { - otp_ctrl_reg2hw_csr0_reg_t csr0; // [158:135] - otp_ctrl_reg2hw_csr1_reg_t csr1; // [134:103] - otp_ctrl_reg2hw_csr2_reg_t csr2; // [102:102] - otp_ctrl_reg2hw_csr3_reg_t csr3; // [101:82] - otp_ctrl_reg2hw_csr4_reg_t csr4; // [81:69] - otp_ctrl_reg2hw_csr5_reg_t csr5; // [68:39] - otp_ctrl_reg2hw_csr6_reg_t csr6; // [38:11] - otp_ctrl_reg2hw_csr7_reg_t csr7; // [10:0] - } otp_ctrl_prim_reg2hw_t; - - // HW -> register type for prim interface - typedef struct packed { - otp_ctrl_hw2reg_csr3_reg_t csr3; // [80:52] - otp_ctrl_hw2reg_csr5_reg_t csr5; // [51:15] - otp_ctrl_hw2reg_csr7_reg_t csr7; // [14:0] - } otp_ctrl_prim_hw2reg_t; - - // Register offsets for prim interface - parameter logic [PrimAw-1:0] OTP_CTRL_CSR0_OFFSET = 5'h 0; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR1_OFFSET = 5'h 4; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR2_OFFSET = 5'h 8; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR3_OFFSET = 5'h c; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR4_OFFSET = 5'h 10; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR5_OFFSET = 5'h 14; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR6_OFFSET = 5'h 18; - parameter logic [PrimAw-1:0] OTP_CTRL_CSR7_OFFSET = 5'h 1c; - - // Register index for prim interface - typedef enum int { - OTP_CTRL_CSR0, - OTP_CTRL_CSR1, - OTP_CTRL_CSR2, - OTP_CTRL_CSR3, - OTP_CTRL_CSR4, - OTP_CTRL_CSR5, - OTP_CTRL_CSR6, - OTP_CTRL_CSR7 - } otp_ctrl_prim_id_e; - - // Register width information to check illegal writes for prim interface - parameter logic [3:0] OTP_CTRL_PRIM_PERMIT [8] = '{ - 4'b 1111, // index[0] OTP_CTRL_CSR0 - 4'b 1111, // index[1] OTP_CTRL_CSR1 - 4'b 0001, // index[2] OTP_CTRL_CSR2 - 4'b 0111, // index[3] OTP_CTRL_CSR3 - 4'b 0011, // index[4] OTP_CTRL_CSR4 - 4'b 1111, // index[5] OTP_CTRL_CSR5 - 4'b 1111, // index[6] OTP_CTRL_CSR6 - 4'b 0011 // index[7] OTP_CTRL_CSR7 - }; - -endpackage diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv deleted file mode 100644 index 9470ff8eb1512..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv +++ /dev/null @@ -1,510 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This module contains the scrambling datapath for the OTP controller. It basically consists of -// two single-round PRESENT primitives (one for encryption and one for decryption mode), a counter -// with a simple FSM and four working registers, as listed below. -// -// key_state_q (128bit): working register to hold the round key (needed for the key schedule). -// -// data_state_q (64bit): working register to hold the data state in between rounds. -// -// data_shadow_q (64bit): shadow register for holding a second 64bit block of input data. This is -// used to form a 128bit data block for the digest mode, which has a block -// size of 128bit. -// -// digest_state_q (64bit): register to hold the digest state in between digest updates. Technically, -// this is not needed when the data for the digest is fed into this block -// back-to-back. However, the partition integrity checks require that it is -// possible to interleave encryption operations and digest update steps, -// hence an additional state register is needed, as otherwise the digest -// state would be lost. -// -// The scrambling datapath is arranged such that it can also be used for calculating a digest using -// the encryption primitive in a Merkle-Damgard construction. To that end, the PRESENT block cipher -// is turned into a one way function according to the Davies-Meyer scheme. Note however that this -// makes the digest block size 128bit wide, since the Merkle-Damgard construction leverages the -// cipher key input to ingest data. -// -// The scrambling datapath exposes a few simple commands and the FSM hides the complexity -// of steering the appropriate muxes and keeping track of the cipher rounds. These commands are -// briefly explained below. -// -// Decrypt: This decrypts the data block provided via data_i with the key at index sel_i. -// -// Encrypt: This encrypts the data block provided via data_i with the key at index sel_i. -// In addition, this command copies the prvious result into a shadow register before -// the first encryption round for later use in the digest (see description further below). -// This enables interleaved encrypt/digest operation needed for the integrity checks of -// the secret partitions. -// -// LoadShadow: In "StandardMode", the LoadShadow command loads the data provided via data_i into a -// shadow register that is mapped to the lower 64bit of the 128bit digest input data -// block. In "ChainedMode", this command copies the contents of the data state register -// into the shadow register. -// -// DigestInit: This ensures that the digest initialization vector (IV) is selected upon the next -// call of the Digest command. Also, mode_i can be used to set the digest mode. If -// mode_i is set to "StandardMode", the data to be digested has to be provided via -// data_i and LoadShadow. If mode_i is set to "ChainedMode", the digest input is formed -// by concatenating the results of the revious two encryption commands. -// -// Digest: In "StandardMode", this command concatenates the data input supplied via data_i with -// the shadow register in order to form a 128bit block ({data_i, data_shadow_q}). This block -// is then used to encrypt the digest state. In "ChainedMode" digest mode, the 128bit block -// to be digested is formed by concatenating {data_state_q, data_shadow_q}. If a DigestInit -// command has been executed right before calling Digest, the IV selected with sel_i is -// used to initialize the state. -// -// DigestFinalize: This command encrypts the digest state with the finalization constant selected -// by sel_i in order to form the final digest. -// -// References: - https://docs.opentitan.org/hw/ip/otp_ctrl/doc/index.html#design-details -// - https://docs.opentitan.org/hw/ip/prim/doc/prim_present/ -// - https://en.wikipedia.org/wiki/Merkle-Damgard_construction -// - https://en.wikipedia.org/wiki/One-way_compression_function#Davies%E2%80%93Meyer -// - https://en.wikipedia.org/wiki/PRESENT -// - http://www.lightweightcrypto.org/present/present_ches2007.pdf -// - -`include "prim_flop_macros.sv" - -module otp_ctrl_scrmbl - import otp_ctrl_pkg::*; - import otp_ctrl_part_pkg::*; -( - input clk_i, - input rst_ni, - // input data and command - input otp_scrmbl_cmd_e cmd_i, - input digest_mode_e mode_i, - input [ConstSelWidth-1:0] sel_i, - input [ScrmblBlockWidth-1:0] data_i, - input valid_i, - output logic ready_o, - // output data - output logic [ScrmblBlockWidth-1:0] data_o, - output logic valid_o, - // escalation input and FSM error indication - input lc_ctrl_pkg::lc_tx_t escalate_en_i, - output logic fsm_err_o -); - - import prim_util_pkg::vbits; - - //////////////////////// - // Decryption Key LUT // - //////////////////////// - - // Anchor keys, constants and IVs - key_array_t rnd_cnst_key_anchor; - digest_const_array_t rnd_cnst_digest_anchor; - digest_iv_array_t rnd_cnst_digest_iv_anchor; - - for (genvar i = 0; i < NumScrmblKeys; i++) begin : gen_anchor_keys - prim_sec_anchor_buf #( - .Width(ScrmblKeyWidth) - ) u_key_anchor_buf ( - .in_i(RndCnstKey[i]), - .out_o(rnd_cnst_key_anchor[i]) - ); - end - - for (genvar i = 0; i < NumDigestSets; i++) begin : gen_anchor_digests - prim_sec_anchor_buf #( - .Width(ScrmblKeyWidth) - ) u_const_anchor_buf ( - .in_i(RndCnstDigestConst[i]), - .out_o(rnd_cnst_digest_anchor[i]) - ); - - prim_sec_anchor_buf #( - .Width(ScrmblBlockWidth) - ) u_iv_anchor_buf ( - .in_i(RndCnstDigestIV[i]), - .out_o(rnd_cnst_digest_iv_anchor[i]) - ); - end - - - // Align these arrays to power of 2's to prevent X's in the muxing operations further below. - logic [2**$clog2(NumScrmblKeys)-1:0][ScrmblKeyWidth-1:0] otp_enc_key_lut; - logic [2**$clog2(NumScrmblKeys)-1:0][ScrmblKeyWidth-1:0] otp_dec_key_lut; - logic [2**$clog2(NumDigestSets)-1:0][ScrmblKeyWidth-1:0] digest_const_lut; - logic [2**$clog2(NumDigestSets)-1:0][ScrmblBlockWidth-1:0] digest_iv_lut; - - // This pre-calculates the inverse scrambling keys at elab time. - `ASSERT_INIT(NumMaxPresentRounds_A, NumPresentRounds <= 31) - - always_comb begin : p_luts - otp_enc_key_lut = '0; - otp_dec_key_lut = '0; - digest_const_lut = '0; - digest_iv_lut = '0; - - for (int k = 0; k < NumScrmblKeys; k++) begin - localparam logic [4:0] NumRounds = 5'(unsigned'(NumPresentRounds)); - otp_enc_key_lut[k] = rnd_cnst_key_anchor[k]; - // Due to the PRESENT key schedule, we have to step the key schedule function by - // NumPresentRounds forwards to get the decryption key. - otp_dec_key_lut[k] = - prim_cipher_pkg::present_get_dec_key128(rnd_cnst_key_anchor[k], NumRounds); - end - - for (int k = 0; k < NumDigestSets; k++) begin - digest_const_lut[k] = rnd_cnst_digest_anchor[k]; - digest_iv_lut[k] = rnd_cnst_digest_iv_anchor[k]; - end - end - `ASSERT_KNOWN(EncKeyLutKnown_A, otp_enc_key_lut) - `ASSERT_KNOWN(DecKeyLutKnown_A, otp_dec_key_lut) - `ASSERT_KNOWN(DigestConstLutKnown_A, digest_const_lut) - `ASSERT_KNOWN(DigestIvLutKnown_A, digest_iv_lut) - - ////////////// - // Datapath // - ////////////// - - logic [4:0] idx_state_d, idx_state_q; - logic [ScrmblKeyWidth-1:0] key_state_d, key_state_q; - logic [ScrmblBlockWidth-1:0] data_state_d, data_state_q, data_shadow_q; - logic [ScrmblBlockWidth-1:0] digest_state_d, digest_state_q; - logic [ScrmblBlockWidth-1:0] enc_data_out, enc_data_out_xor, dec_data_out; - logic [ScrmblKeyWidth-1:0] dec_key_out, enc_key_out; - logic [4:0] dec_idx_out, enc_idx_out; - logic [ScrmblKeyWidth-1:0] otp_digest_const_mux, otp_enc_key_mux, otp_dec_key_mux; - logic [ScrmblBlockWidth-1:0] otp_digest_iv_mux; - - typedef enum logic [2:0] {SelEncDataOut, - SelDecDataOut, - SelDigestState, - SelEncDataOutXor, - SelDataInput} data_state_sel_e; - - typedef enum logic [2:0] {SelDecKeyOut, - SelEncKeyOut, - SelDecKeyInit, - SelEncKeyInit, - SelDigestConst, - SelDigestInput, - SelDigestChained} key_state_sel_e; - - logic digest_init; - data_state_sel_e data_state_sel; - key_state_sel_e key_state_sel; - logic data_state_en, data_shadow_copy, data_shadow_load, digest_state_en, key_state_en; - digest_mode_e digest_mode_d, digest_mode_q; - - assign otp_enc_key_mux = otp_enc_key_lut[ScrmblKeySelWidth'(sel_i)]; - assign otp_dec_key_mux = otp_dec_key_lut[ScrmblKeySelWidth'(sel_i)]; - assign otp_digest_const_mux = digest_const_lut[DigestSetSelWidth'(sel_i)]; - assign otp_digest_iv_mux = digest_iv_lut[DigestSetSelWidth'(sel_i)]; - - // Make sure we always select a valid key / digest constant. - `ASSERT(CheckNumEncKeys_A, key_state_sel == SelEncKeyInit |-> sel_i < NumScrmblKeys) - `ASSERT(CheckNumDecKeys_A, key_state_sel == SelDecKeyInit |-> sel_i < NumScrmblKeys) - `ASSERT(CheckNumDigest1_A, key_state_sel == SelDigestConst |-> sel_i < NumDigestSets) - - assign data_state_d = (data_state_sel == SelEncDataOut) ? enc_data_out : - (data_state_sel == SelDecDataOut) ? dec_data_out : - (data_state_sel == SelDigestState) ? digest_state_q : - (data_state_sel == SelEncDataOutXor) ? enc_data_out_xor : - data_i; - - assign key_state_d = (key_state_sel == SelDecKeyOut) ? dec_key_out : - (key_state_sel == SelEncKeyOut) ? enc_key_out : - (key_state_sel == SelDecKeyInit) ? otp_dec_key_mux : - (key_state_sel == SelEncKeyInit) ? otp_enc_key_mux : - (key_state_sel == SelDigestConst) ? otp_digest_const_mux : - (key_state_sel == SelDigestChained) ? {data_state_q, data_shadow_q} : - {data_i, data_shadow_q}; - - // Initialize the round index state with 1 in all cases, except for the decrypt operation. - assign idx_state_d = (key_state_sel == SelDecKeyOut) ? dec_idx_out : - (key_state_sel == SelEncKeyOut) ? enc_idx_out : - (key_state_sel == SelDecKeyInit) ? unsigned'(5'(NumPresentRounds)) : - 5'd1; - - // The XOR is for the Davies-Mayer one-way function construction. - assign enc_data_out_xor = enc_data_out ^ digest_state_q; - assign digest_state_d = (digest_init) ? otp_digest_iv_mux : enc_data_out_xor; - - logic valid_q; //valid_d defined below - assign data_o = (valid_q) ? data_state_q : 0; - - ///////// - // FSM // - ///////// - - // SEC_CM: SCRMBL.FSM.SPARSE - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 5 -n 9 \ - // -s 2193087944 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (60.00%) - // 6: ||||||||||||| (40.00%) - // 7: -- - // 8: -- - // 9: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 4 - // Maximum Hamming weight: 7 - // - localparam int StateWidth = 9; - typedef enum logic [StateWidth-1:0] { - IdleSt = 9'b100011001, - DecryptSt = 9'b101101111, - EncryptSt = 9'b010010111, - DigestSt = 9'b111000010, - ErrorSt = 9'b011111000 - } state_e; - - localparam int CntWidth = $clog2(NumPresentRounds+1); - localparam int unsigned LastPresentRoundInt = NumPresentRounds - 1; - localparam bit [CntWidth-1:0] LastPresentRound = LastPresentRoundInt[CntWidth-1:0]; - - state_e state_d, state_q; - logic [CntWidth-1:0] cnt; - logic cnt_clr, cnt_en, cnt_err; - logic valid_d; //valid_q defined above - - assign valid_o = valid_q; - - // SEC_CM: SCRMBL.CTR.REDUN - prim_count #( - .Width(CntWidth) - ) u_prim_count ( - .clk_i, - .rst_ni, - .clr_i(cnt_clr), - .set_i(1'b0), - .set_cnt_i('0), - .incr_en_i(cnt_en), - .decr_en_i(1'b0), - .step_i(CntWidth'(1)), - .commit_i(1'b1), - .cnt_o(cnt), - .cnt_after_commit_o(), - .err_o(cnt_err) - ); - - always_comb begin : p_fsm - state_d = state_q; - digest_mode_d = digest_mode_q; - data_state_sel = SelDataInput; - key_state_sel = SelDigestInput; - digest_init = 1'b0; - data_state_en = 1'b0; - data_shadow_copy = 1'b0; - data_shadow_load = 1'b0; - key_state_en = 1'b0; - digest_state_en = 1'b0; - cnt_en = 1'b0; - cnt_clr = 1'b0; - valid_d = 1'b0; - ready_o = 1'b0; - fsm_err_o = 1'b0; - - unique case (state_q) - /////////////////////////////////////////////////////////////////// - // Idle State: decode command and - // load working regs accordingly - IdleSt: begin - cnt_clr = 1'b1; - ready_o = 1'b1; - - if (valid_i) begin - unique case (cmd_i) - Decrypt: begin - state_d = DecryptSt; - key_state_sel = SelDecKeyInit; - data_state_en = 1'b1; - key_state_en = 1'b1; - end - Encrypt: begin - state_d = EncryptSt; - key_state_sel = SelEncKeyInit; - data_state_en = 1'b1; - key_state_en = 1'b1; - end - LoadShadow: begin - if (digest_mode_q == ChainedMode) begin - data_shadow_copy = 1'b1; - end else begin - data_shadow_load = 1'b1; - end - end - Digest: begin - state_d = DigestSt; - data_state_sel = SelDigestState; - key_state_sel = (digest_mode_q == ChainedMode) ? SelDigestChained : SelDigestInput; - data_state_en = 1'b1; - key_state_en = 1'b1; - end - DigestInit: begin - digest_mode_d = mode_i; - digest_init = 1'b1; - digest_state_en = 1'b1; - end - DigestFinalize: begin - state_d = DigestSt; - data_state_sel = SelDigestState; - key_state_sel = SelDigestConst; - data_state_en = 1'b1; - key_state_en = 1'b1; - digest_mode_d = StandardMode; - end - default: ; // ignore - endcase // cmd_i - end - end - /////////////////////////////////////////////////////////////////// - // Perform decrypt rounds. - DecryptSt: begin - data_state_sel = SelDecDataOut; - key_state_sel = SelDecKeyOut; - data_state_en = 1'b1; - key_state_en = 1'b1; - cnt_en = 1'b1; - if (cnt == LastPresentRound) begin - state_d = IdleSt; - valid_d = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Perform encrypt rounds. - EncryptSt: begin - data_state_sel = SelEncDataOut; - key_state_sel = SelEncKeyOut; - data_state_en = 1'b1; - key_state_en = 1'b1; - cnt_en = 1'b1; - if (cnt == LastPresentRound) begin - state_d = IdleSt; - valid_d = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // The digest is calculated with a Merkle-Damgard construction that - // employs the PRESENT encryption datapath. - DigestSt: begin - data_state_sel = SelEncDataOut; - key_state_sel = SelEncKeyOut; - data_state_en = 1'b1; - key_state_en = 1'b1; - cnt_en = 1'b1; - if (cnt == LastPresentRound) begin - state_d = IdleSt; - valid_d = 1'b1; - // Apply XOR for Davies-Meyer construction. - data_state_sel = SelEncDataOutXor; - // Backup digest state for next round of updates. We can't keep this state in the - // data state register as a digest may be calculated together with encryption - // operations in an interleaved way. - digest_state_en = 1'b1; - end - end - /////////////////////////////////////////////////////////////////// - // Terminal error state. This raises an alert. - ErrorSt: begin - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - // This should never happen, hence we directly jump into the - // error state, where an alert will be triggered. - default: begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - /////////////////////////////////////////////////////////////////// - endcase // state_q - - // Unconditionally jump into the terminal error state in case of escalation. - // SEC_CM: SCRMBL.FSM.LOCAL_ESC, SCRMBL.FSM.GLOBAL_ESC - if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin - state_d = ErrorSt; - fsm_err_o = 1'b1; - end - end - - ///////////////////////////// - // PRESENT DEC/ENC Modules // - ///////////////////////////// - - prim_present #( - .KeyWidth(128), - .NumRounds(NumPresentRounds), - .NumPhysRounds(1) - ) u_prim_present_enc ( - .data_i ( data_state_q ), - .key_i ( key_state_q ), - .idx_i ( idx_state_q ), - .data_o ( enc_data_out ), - .key_o ( enc_key_out ), - .idx_o ( enc_idx_out ) - ); - - prim_present #( - .KeyWidth(128), - // We are using an iterative full-round implementation here. - .NumRounds(NumPresentRounds), - .NumPhysRounds(1), - .Decrypt(1) - ) u_prim_present_dec ( - .data_i ( data_state_q ), - .key_i ( key_state_q ), - .idx_i ( idx_state_q ), - .data_o ( dec_data_out ), - .key_o ( dec_key_out ), - .idx_o ( dec_idx_out ) - ); - - /////////////// - // Registers // - /////////////// - - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, IdleSt) - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs - if (!rst_ni) begin - key_state_q <= '0; - idx_state_q <= '0; - data_state_q <= '0; - data_shadow_q <= '0; - digest_state_q <= '0; - valid_q <= 1'b0; - digest_mode_q <= StandardMode; - end else begin - valid_q <= valid_d; - digest_mode_q <= digest_mode_d; - - // enable regs - if (key_state_en) begin - key_state_q <= key_state_d; - idx_state_q <= idx_state_d; - end - if (data_state_en) begin - data_state_q <= data_state_d; - end - if (data_shadow_copy) begin - data_shadow_q <= data_state_q; - end else if (data_shadow_load) begin - data_shadow_q <= data_state_d; - end - if (digest_state_en) begin - digest_state_q <= digest_state_d; - end - end - end - -endmodule : otp_ctrl_scrmbl diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_token_const.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_token_const.sv deleted file mode 100644 index 35cdc23dd0c7a..0000000000000 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl_token_const.sv +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This module contains the hash post-image constants for the all-zero and raw unlock tokens. -// This implementation relies on constant propagation to precompute these constants from the -// random netlist constants at compile time, and hence does not contain any "real" logic. - -module otp_ctrl_token_const import otp_ctrl_pkg::*; #( - // Compile time random constants, to be overriden by topgen. - parameter digest_const_array_t RndCnstDigestConst = RndCnstDigestConstDefault, - parameter digest_iv_array_t RndCnstDigestIV = RndCnstDigestIVDefault, - parameter lc_ctrl_pkg::lc_token_t RndCnstRawUnlockToken = RndCnstRawUnlockTokenDefault -) ( - output lc_ctrl_pkg::lc_token_t all_zero_token_hashed_o, - output lc_ctrl_pkg::lc_token_t raw_unlock_token_hashed_o -); - - localparam int NumHashes = 2; - localparam int AllZeroIdx = 0; - localparam int RawUnlockIdx = 1; - - logic [NumHashes-1:0][1:0][ScrmblKeyWidth-1:0] data; - logic [NumHashes-1:0][4:0][ScrmblBlockWidth-1:0] state; - - // First digest is for the all zero token, the second is for the raw unlock token. - assign data[AllZeroIdx][0] = '0; - assign data[RawUnlockIdx][0] = RndCnstRawUnlockToken; - - // Repeat for all precomputed hashes. - for (genvar j = 0; j < NumHashes; j++) begin : gen_hashes - // Initialize all hashes with digest IV. - assign state[j][0] = RndCnstDigestIV[LcRawDigest]; - // Second data block is always the digest finalization constant. - assign data[j][1] = RndCnstDigestConst[LcRawDigest]; - - // Each hash takes four invocations, see diagram c) on - // https://docs.opentitan.org/hw/ip/otp_ctrl/doc/index.html#scrambling-datapath - for (genvar k = 0; k < 4; k++) begin : gen_invocations - logic [ScrmblBlockWidth-1:0] next_state; - - // This relies on constant propagation to - // statically precompute the hashed token values. - prim_present #( - .KeyWidth(128), - .NumRounds(NumPresentRounds) - ) u_prim_present_enc_0 ( - .data_i ( state[j][k] ), - .key_i ( data[j][k%2] ), - .idx_i ( 5'h1 ), - .data_o ( next_state ), - .key_o ( ), - .idx_o ( ) - ); - - // XOR in last state according to the Davies-Meyer scheme. - assign state[j][k+1] = next_state ^ state[j][k]; - end - end - - // Concatenate the two 64bit hash results to form the final digests. - assign all_zero_token_hashed_o = {state[AllZeroIdx][4], state[AllZeroIdx][2]}; - assign raw_unlock_token_hashed_o = {state[RawUnlockIdx][4], state[RawUnlockIdx][2]}; - -endmodule : otp_ctrl_token_const diff --git a/hw/ip/otp_ctrl/syn/constraints.sdc b/hw/ip/otp_ctrl/syn/constraints.sdc deleted file mode 100644 index 0b119da970832..0000000000000 --- a/hw/ip/otp_ctrl/syn/constraints.sdc +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Generic constraints file for simple testsynthesis flow - -# note that we do not fix hold timing in this flow -set SETUP_CLOCK_UNCERTAINTY 0.5 - -##################### -# main clock # -##################### -set MAIN_CLK_PIN clk_i -set MAIN_RST_PIN rst_ni -# set main clock to 125 MHz -set MAIN_TCK 8.0 -set_ideal_network ${MAIN_CLK_PIN} -set_ideal_network ${MAIN_RST_PIN} -set_clock_uncertainty ${SETUP_CLOCK_UNCERTAINTY} ${MAIN_CLK_PIN} - -# other timing constraint in ns -set IN_DEL 1.0 -set OUT_DEL 1.0 -set DELAY ${MAIN_TCK} - -create_clock ${MAIN_CLK_PIN} -period ${MAIN_TCK} - -# in to out -set_max_delay ${DELAY} -from [all_inputs] -to [all_outputs] -# in to reg / reg to out -set_input_delay ${IN_DEL} [remove_from_collection [all_inputs] {${MAIN_CLK_PIN}}] -clock ${MAIN_CLK_PIN} -set_output_delay ${OUT_DEL} [all_outputs] -clock ${MAIN_CLK_PIN} - -##################### -# I/O drive/load # -##################### - -# attach load and drivers to IOs to get a more realistic estimate -set_driving_cell -no_design_rule -lib_cell ${DRIVING_CELL} -pin ${DRIVING_CELL_PIN} [all_inputs] -set_load [load_of ${LOAD_CELL_LIB}/${LOAD_CELL}/${LOAD_CELL_PIN}] [all_outputs] - -# set a nonzero critical range to be able to spot the violating paths better -# in the report -set_critical_range 0.5 ${DUT} - -##################### -# Size Only Cells # -##################### - -set_size_only -all_instances [get_cells -h *u_size_only*] true diff --git a/hw/ip/otp_ctrl/syn/otp_ctrl_gtech_syn_cfg.hjson b/hw/ip/otp_ctrl/syn/otp_ctrl_gtech_syn_cfg.hjson deleted file mode 100644 index 467e4b6914d99..0000000000000 --- a/hw/ip/otp_ctrl/syn/otp_ctrl_gtech_syn_cfg.hjson +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - // Top level dut name (sv module). - name: otp_ctrl - - // Fusesoc core file used for building the file list. - fusesoc_core: lowrisc:ip:{name}:0.1 - - import_cfgs: [// Project wide common GTECH synthesis config file - "{proj_root}/hw/syn/tools/dvsim/common_gtech_syn_cfg.hjson"] - - overrides: [ - { - name: design_level - value: "top" - } - { // Deletes black-boxed hierarchies before writing out the unmapped netlist - name: post_elab_script - value: "{proj_root}/hw/ip/{name}/syn/post_elab_gtech.tcl" - } - ] -} diff --git a/hw/ip/otp_ctrl/syn/otp_ctrl_syn_cfg.hjson b/hw/ip/otp_ctrl/syn/otp_ctrl_syn_cfg.hjson deleted file mode 100644 index 62f9783391426..0000000000000 --- a/hw/ip/otp_ctrl/syn/otp_ctrl_syn_cfg.hjson +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - // Top level dut name (sv module). - name: otp_ctrl - - // Fusesoc core file used for building the file list. - fusesoc_core: lowrisc:ip:{name}:0.1 - - import_cfgs: [// Project wide common synthesis config file - "{proj_root}/hw/syn/tools/dvsim/common_syn_cfg.hjson"] - - overrides: [ - { - name: design_level - value: "top" - } - ] - - // Timing constraints for this module - sdc_file: "{proj_root}/hw/ip/{name}/syn/constraints.sdc" - - // This is not needed for this module - foundry_sdc_file: "" -} diff --git a/hw/ip/otp_ctrl/syn/post_elab_gtech.tcl b/hw/ip/otp_ctrl/syn/post_elab_gtech.tcl deleted file mode 100644 index abe1a8c181f27..0000000000000 --- a/hw/ip/otp_ctrl/syn/post_elab_gtech.tcl +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# Post elab script, used in GTECH runs to modify the unmapped netlist before -# writing it out. - -# Remove generic views of ram macros -remove_design prim_generic_ram_1p_Width*