[otp/dv] Add a wake-up test for OTP
This PR uses `uvmdvgen` to generate an initial testbench for OTP_ctrl.
In addition to the autogen, this PR:
1). Connect basic interface signals to support a wakeup test
2). Bind OTP memory interface to initialize OTP
3). Add a wake-up test to check basic OTP-init, read, write, digest
functions
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
new file mode 100644
index 0000000..09dd5e7
--- /dev/null
+++ b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
@@ -0,0 +1,33 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+{
+ name: "otp_ctrl"
+ // TODO: remove the common testplans if not applicable
+ import_testplans: ["hw/dv/tools/testplans/csr_testplan.hjson",
+ "hw/dv/tools/testplans/mem_testplan.hjson",
+ "hw/dv/tools/testplans/intr_test_testplan.hjson",
+ "hw/dv/tools/testplans/tl_device_access_types_testplan.hjson"]
+ entries: [
+ {
+ name: sanity
+ desc: '''
+ Basic sanity test acessing a major datapath within the otp_ctrl.
+
+ **Stimulus**:
+ - TBD
+
+ **Checks**:
+ - TBD
+ '''
+ milestone: V1
+ tests: ["otp_ctrl_sanity"]
+ }
+ {
+ name: feature1
+ desc: '''Add more test entries here like above.'''
+ milestone: V1
+ tests: []
+ }
+ ]
+}
diff --git a/hw/ip/otp_ctrl/doc/checklist.md b/hw/ip/otp_ctrl/doc/checklist.md
new file mode 100644
index 0000000..61eb121
--- /dev/null
+++ b/hw/ip/otp_ctrl/doc/checklist.md
@@ -0,0 +1,240 @@
+---
+title: "OTP_CTRL Checklist"
+---
+
+<!--
+NOTE: This is a template checklist document that is required to be copied over to the 'doc'
+directory for a new design that transitions from L0 (Specification) to L1 (Development)
+stage, and updated as needed. Once done, please remove this comment before checking it in.
+-->
+This checklist is for [Hardware Stage]({{< relref "/doc/project/development_stages.md" >}}) transitions for the [OTP_CTRL peripheral.]({{< relref "hw/ip/otp_ctrl/doc" >}})
+All checklist items refer to the content in the [Checklist.]({{< relref "/doc/project/checklist.md" >}})
+
+## Design Checklist
+
+### D1
+
+Type | Item | Resolution | Note/Collaterals
+--------------|-----------------------|-------------|------------------
+Documentation | [SPEC_COMPLETE][] | Not Started | [OTP_CTRL Design Spec]({{<relref "hw/ip/otp_ctrl/doc" >}})
+Documentation | [CSR_DEFINED][] | Not Started |
+RTL | [CLKRST_CONNECTED][] | Not Started |
+RTL | [IP_TOP][] | Not Started |
+RTL | [IP_INSTANTIABLE][] | Not Started |
+RTL | [MEM_INSTANCED_80][] | Not Started |
+RTL | [FUNC_IMPLEMENTED][] | Not Started |
+RTL | [ASSERT_KNOWN_ADDED][]| Not Started |
+Code Quality | [LINT_SETUP][] | Not Started |
+Review | Reviewer(s) | Not Started |
+Review | Signoff date | Not Started |
+
+[SPEC_COMPLETE]: {{<relref "/doc/project/checklist.md#spec-complete" >}}
+[CSR_DEFINED]: {{<relref "/doc/project/checklist.md#csr-defined" >}}
+[CLKRST_CONNECTED]: {{<relref "/doc/project/checklist.md#clkrst-connected" >}}
+[IP_TOP]: {{<relref "/doc/project/checklist.md#ip-top" >}}
+[IP_INSTANTIABLE]: {{<relref "/doc/project/checklist.md#ip-instantiable" >}}
+[MEM_INSTANCED_80]: {{<relref "/doc/project/checklist.md#mem-instanced-80" >}}
+[FUNC_IMPLEMENTED]: {{<relref "/doc/project/checklist.md#func-implemented" >}}
+[ASSERT_KNOWN_ADDED]: {{<relref "/doc/project/checklist.md#assert-known-added" >}}
+[LINT_SETUP]: {{<relref "/doc/project/checklist.md#lint-setup" >}}
+
+### D2
+
+Type | Item | Resolution | Note/Collaterals
+--------------|-------------------------|-------------|------------------
+Documentation | [NEW_FEATURES][] | Not Started |
+Documentation | [BLOCK_DIAGRAM][] | Not Started |
+Documentation | [DOC_INTERFACE][] | Not Started |
+Documentation | [MISSING_FUNC][] | Not Started |
+Documentation | [FEATURE_FROZEN][] | Not Started |
+RTL | [FEATURE_COMPLETE][] | Not Started |
+RTL | [AREA_SANITY_CHECK][] | Not Started |
+RTL | [PORT_FROZEN][] | Not Started |
+RTL | [ARCHITECTURE_FROZEN][] | Not Started |
+RTL | [REVIEW_TODO][] | Not Started |
+RTL | [STYLE_X][] | Not Started |
+Code Quality | [LINT_PASS][] | Not Started |
+Code Quality | [CDC_SETUP][] | Not Started |
+Code Quality | [FPGA_TIMING][] | Not Started |
+Code Quality | [CDC_SYNCMACRO][] | Not Started |
+Security | [SEC_CM_IMPLEMENTED][] | Not Started |
+Security | [SEC_NON_RESET_FLOPS][] | Not Started |
+Security | [SEC_SHADOW_REGS][] | Not Started |
+Review | Reviewer(s) | Not Started |
+Review | Signoff date | Not Started |
+
+[NEW_FEATURES]: {{<relref "/doc/project/checklist.md#new-features" >}}
+[BLOCK_DIAGRAM]: {{<relref "/doc/project/checklist.md#block-diagram" >}}
+[DOC_INTERFACE]: {{<relref "/doc/project/checklist.md#doc-interface" >}}
+[MISSING_FUNC]: {{<relref "/doc/project/checklist.md#missing-func" >}}
+[FEATURE_FROZEN]: {{<relref "/doc/project/checklist.md#feature-frozen" >}}
+[FEATURE_COMPLETE]: {{<relref "/doc/project/checklist.md#feature-complete" >}}
+[AREA_SANITY_CHECK]: {{<relref "/doc/project/checklist.md#area-sanity-check" >}}
+[PORT_FROZEN]: {{<relref "/doc/project/checklist.md#port-frozen" >}}
+[ARCHITECTURE_FROZEN]: {{<relref "/doc/project/checklist.md#architecture-frozen" >}}
+[REVIEW_TODO]: {{<relref "/doc/project/checklist.md#review-todo" >}}
+[STYLE_X]: {{<relref "/doc/project/checklist.md#style-x" >}}
+[LINT_PASS]: {{<relref "/doc/project/checklist.md#lint-pass" >}}
+[CDC_SETUP]: {{<relref "/doc/project/checklist.md#cdc-setup" >}}
+[FPGA_TIMING]: {{<relref "/doc/project/checklist.md#fpga-timing" >}}
+[CDC_SYNCMACRO]: {{<relref "/doc/project/checklist.md#cdc-syncmacro" >}}
+[SEC_CM_IMPLEMENTED]: {{<relref "/doc/project/checklist.md#sec-cm-implemented" >}}
+[SEC_NON_RESET_FLOPS]: {{<relref "/doc/project/checklist.md#sec-non-reset-flops" >}}
+[SEC_SHADOW_REGS]: {{<relref "/doc/project/checklist.md#sec-shadow-regs" >}}
+
+### D3
+
+ Type | Item | Resolution | Note/Collaterals
+--------------|-------------------------|-------------|------------------
+Documentation | [NEW_FEATURES_D3][] | Not Started |
+RTL | [TODO_COMPLETE][] | Not Started |
+Code Quality | [LINT_COMPLETE][] | Not Started |
+Code Quality | [CDC_COMPLETE][] | Not Started |
+Review | [REVIEW_RTL][] | Not Started |
+Review | [REVIEW_DELETED_FF][] | Not Started |
+Review | [REVIEW_SW_CSR][] | Not Started |
+Review | [REVIEW_SW_FATAL_ERR][] | Not Started |
+Review | [REVIEW_SW_CHANGE][] | Not Started |
+Review | [REVIEW_SW_ERRATA][] | Not Started |
+Review | Reviewer(s) | Not Started |
+Review | Signoff date | Not Started |
+
+[NEW_FEATURES_D3]: {{<relref "/doc/project/checklist.md#new-features-d3" >}}
+[TODO_COMPLETE]: {{<relref "/doc/project/checklist.md#todo-complete" >}}
+[LINT_COMPLETE]: {{<relref "/doc/project/checklist.md#lint-complete" >}}
+[CDC_COMPLETE]: {{<relref "/doc/project/checklist.md#cdc-complete" >}}
+[REVIEW_RTL]: {{<relref "/doc/project/checklist.md#review-rtl" >}}
+[REVIEW_DBG]: {{<relref "/doc/project/checklist.md#review-dbg" >}}
+[REVIEW_DELETED_FF]: {{<relref "/doc/project/checklist.md#review-deleted-ff" >}}
+[REVIEW_SW_CSR]: {{<relref "/doc/project/checklist.md#review-sw-csr" >}}
+[REVIEW_SW_FATAL_ERR]: {{<relref "/doc/project/checklist.md#review-sw-fatal-err" >}}
+[REVIEW_SW_CHANGE]: {{<relref "/doc/project/checklist.md#review-sw-change" >}}
+[REVIEW_SW_ERRATA]: {{<relref "/doc/project/checklist.md#review-sw-errata" >}}
+
+## Verification Checklist
+
+### V1
+
+ Type | Item | Resolution | Note/Collaterals
+--------------|---------------------------------------|-------------|------------------
+Documentation | [DV_PLAN_DRAFT_COMPLETED][] | Not Started | [OTP_CTRL DV Plan]({{<relref "hw/ip/otp_ctrl/doc/dv_plan" >}})
+Documentation | [TESTPLAN_COMPLETED][] | Not Started | [OTP_CTRL Testplan]({{<relref "hw/ip/otp_ctrl/doc/dv_plan/index.md#testplan" >}})
+Testbench | [TB_TOP_CREATED][] | Not Started |
+Testbench | [PRELIMINARY_ASSERTION_CHECKS_ADDED][]| Not Started |
+Testbench | [SIM_TB_ENV_CREATED][] | Not Started |
+Testbench | [SIM_RAL_MODEL_GEN_AUTOMATED][] | Not Started |
+Testbench | [CSR_CHECK_GEN_AUTOMATED][] | Not Started |
+Testbench | [TB_GEN_AUTOMATED][] | Not Started |
+Tests | [SIM_SANITY_TEST_PASSING][] | Not Started |
+Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | Not Started |
+Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | Not Started |
+Tool Setup | [SIM_ALT_TOOL_SETUP][] | Not Started |
+Regression | [SIM_SANITY_REGRESSION_SETUP][] | Not Started |
+Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | Not Started |
+Regression | [FPV_REGRESSION_SETUP][] | Not Started |
+Coverage | [SIM_COVERAGE_MODEL_ADDED][] | Not Started |
+Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | Not Started |
+Review | [DESIGN_SPEC_REVIEWED][] | Not Started |
+Review | [DV_PLAN_TESTPLAN_REVIEWED][] | Not Started |
+Review | [STD_TEST_CATEGORIES_PLANNED][] | Not Started | Exception (?)
+Review | [V2_CHECKLIST_SCOPED][] | Not Started |
+Review | Reviewer(s) | Not Started |
+Review | Signoff date | Not Started |
+
+[DV_PLAN_DRAFT_COMPLETED]: {{<relref "/doc/project/checklist.md#dv-plan-draft-completed" >}}
+[TESTPLAN_COMPLETED]: {{<relref "/doc/project/checklist.md#testplan-completed" >}}
+[TB_TOP_CREATED]: {{<relref "/doc/project/checklist.md#tb-top-created" >}}
+[PRELIMINARY_ASSERTION_CHECKS_ADDED]: {{<relref "/doc/project/checklist.md#preliminary-assertion-checks-added" >}}
+[SIM_TB_ENV_CREATED]: {{<relref "/doc/project/checklist.md#sim-tb-env-created" >}}
+[SIM_RAL_MODEL_GEN_AUTOMATED]: {{<relref "/doc/project/checklist.md#sim-ral-model-gen-automated" >}}
+[CSR_CHECK_GEN_AUTOMATED]: {{<relref "/doc/project/checklist.md#csr-check-gen-automated" >}}
+[TB_GEN_AUTOMATED]: {{<relref "/doc/project/checklist.md#tb-gen-automated" >}}
+[SIM_SANITY_TEST_PASSING]: {{<relref "/doc/project/checklist.md#sim-sanity-test-passing" >}}
+[SIM_CSR_MEM_TEST_SUITE_PASSING]: {{<relref "/doc/project/checklist.md#sim-csr-mem-test-suite-passing" >}}
+[FPV_MAIN_ASSERTIONS_PROVEN]: {{<relref "/doc/project/checklist.md#fpv-main-assertions-proven" >}}
+[SIM_ALT_TOOL_SETUP]: {{<relref "/doc/project/checklist.md#sim-alt-tool-setup" >}}
+[SIM_SANITY_REGRESSION_SETUP]: {{<relref "/doc/project/checklist.md#sim-sanity-regression-setup" >}}
+[SIM_NIGHTLY_REGRESSION_SETUP]: {{<relref "/doc/project/checklist.md#sim-nightly-regression-setup" >}}
+[FPV_REGRESSION_SETUP]: {{<relref "/doc/project/checklist.md#fpv-regression-setup" >}}
+[SIM_COVERAGE_MODEL_ADDED]: {{<relref "/doc/project/checklist.md#sim-coverage-model-added" >}}
+[PRE_VERIFIED_SUB_MODULES_V1]: {{<relref "/doc/project/checklist.md#pre-verified-sub-modules-v1" >}}
+[DESIGN_SPEC_REVIEWED]: {{<relref "/doc/project/checklist.md#design-spec-reviewed" >}}
+[DV_PLAN_TESTPLAN_REVIEWED]: {{<relref "/doc/project/checklist.md#dv-plan-testplan-reviewed" >}}
+[STD_TEST_CATEGORIES_PLANNED]: {{<relref "/doc/project/checklist.md#std-test-categories-planned" >}}
+[V2_CHECKLIST_SCOPED]: {{<relref "/doc/project/checklist.md#v2-checklist-scoped" >}}
+
+### V2
+
+ Type | Item | Resolution | Note/Collaterals
+--------------|-----------------------------------------|-------------|------------------
+Documentation | [DESIGN_DELTAS_CAPTURED_V2][] | Not started |
+Documentation | [DV_PLAN_COMPLETED][] | Not started |
+Testbench | [ALL_INTERFACES_EXERCISED][] | Not started |
+Testbench | [ALL_ASSERTION_CHECKS_ADDED][] | Not started |
+Testbench | [SIM_TB_ENV_COMPLETED][] | Not started |
+Tests | [SIM_ALL_TESTS_PASSING][] | Not started |
+Tests | [FPV_ALL_ASSERTIONS_WRITTEN][] | Not started |
+Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | Not started |
+Tests | [SIM_FW_SIMULATED][] | Not started |
+Regression | [SIM_NIGHTLY_REGRESSION_V2][] | Not started |
+Coverage | [SIM_CODE_COVERAGE_V2][] | Not started |
+Coverage | [SIM_FUNCTIONAL_COVERAGE_V2][] | Not started |
+Coverage | [FPV_CODE_COVERAGE_V2][] | Not started |
+Coverage | [FPV_COI_COVERAGE_V2][] | Not started |
+Issues | [NO_HIGH_PRIORITY_ISSUES_PENDING][] | Not started |
+Issues | [ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED][] | Not started |
+Integration | [PRE_VERIFIED_SUB_MODULES_V2][] | Not started |
+Review | [V3_CHECKLIST_SCOPED][] | Not started |
+Review | Reviewer(s) | Not started |
+Review | Signoff date | Not started |
+
+[DESIGN_DELTAS_CAPTURED_V2]: {{<relref "/doc/project/checklist.md#design-deltas-captured-v2" >}}
+[DV_PLAN_COMPLETED]: {{<relref "/doc/project/checklist.md#dv-plan-completed" >}}
+[ALL_INTERFACES_EXERCISED]: {{<relref "/doc/project/checklist.md#all-interfaces-exercised" >}}
+[ALL_ASSERTION_CHECKS_ADDED]: {{<relref "/doc/project/checklist.md#all-assertion-checks-added" >}}
+[SIM_TB_ENV_COMPLETED]: {{<relref "/doc/project/checklist.md#sim-tb-env-completed" >}}
+[SIM_ALL_TESTS_PASSING]: {{<relref "/doc/project/checklist.md#sim-all-tests-passing" >}}
+[FPV_ALL_ASSERTIONS_WRITTEN]: {{<relref "/doc/project/checklist.md#fpv-all-assertions-written" >}}
+[FPV_ALL_ASSUMPTIONS_REVIEWED]: {{<relref "/doc/project/checklist.md#fpv-all-assumptions-reviewed" >}}
+[SIM_FW_SIMULATED]: {{<relref "/doc/project/checklist.md#sim-fw-simulated" >}}
+[SIM_NIGHTLY_REGRESSION_V2]: {{<relref "/doc/project/checklist.md#sim-nightly-regression-v2" >}}
+[SIM_CODE_COVERAGE_V2]: {{<relref "/doc/project/checklist.md#sim-code-coverage-v2" >}}
+[SIM_FUNCTIONAL_COVERAGE_V2]: {{<relref "/doc/project/checklist.md#sim-functional-coverage-v2" >}}
+[FPV_CODE_COVERAGE_V2]: {{<relref "/doc/project/checklist.md#fpv-code-coverage-v2" >}}
+[FPV_COI_COVERAGE_V2]: {{<relref "/doc/project/checklist.md#fpv-coi-coverage-v2" >}}
+[NO_HIGH_PRIORITY_ISSUES_PENDING]: {{<relref "/doc/project/checklist.md#no-high-priority-issues-pending" >}}
+[ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED]:{{<relref "/doc/project/checklist.md#all-low-priority-issues-root-caused" >}}
+[PRE_VERIFIED_SUB_MODULES_V2]: {{<relref "/doc/project/checklist.md#pre-verified-sub-modules-v2" >}}
+[V3_CHECKLIST_SCOPED]: {{<relref "/doc/project/checklist.md#v3-checklist-scoped" >}}
+
+### V3
+
+ Type | Item | Resolution | Note/Collaterals
+--------------|-----------------------------------|-------------|------------------
+Documentation | [DESIGN_DELTAS_CAPTURED_V3][] | Not started |
+Testbench | [ALL_TODOS_RESOLVED][] | 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 |
+Issues | [NO_ISSUES_PENDING][] | Not started |
+Code Quality | [NO_TOOL_WARNINGS_THROWN][] | Not started |
+Integration | [PRE_VERIFIED_SUB_MODULES_V3][] | Not started |
+Review | Reviewer(s) | Not started |
+Review | Signoff date | Not started |
+
+[DESIGN_DELTAS_CAPTURED_V3]: {{<relref "/doc/project/checklist.md#design-deltas-captured-v3" >}}
+[ALL_TODOS_RESOLVED]: {{<relref "/doc/project/checklist.md#all-todos-resolved" >}}
+[X_PROP_ANALYSIS_COMPLETED]: {{<relref "/doc/project/checklist.md#x-prop-analysis-completed" >}}
+[FPV_ASSERTIONS_PROVEN_AT_V3]: {{<relref "/doc/project/checklist.md#fpv-assertions-proven-at-v3" >}}
+[SIM_NIGHTLY_REGRESSION_AT_V3]: {{<relref "/doc/project/checklist.md#sim-nightly-regression-at-v3" >}}
+[SIM_CODE_COVERAGE_AT_100]: {{<relref "/doc/project/checklist.md#sim-code-coverage-at-100" >}}
+[SIM_FUNCTIONAL_COVERAGE_AT_100]:{{<relref "/doc/project/checklist.md#sim-functional-coverage-at-100" >}}
+[FPV_CODE_COVERAGE_AT_100]: {{<relref "/doc/project/checklist.md#fpv-code-coverage-at-100" >}}
+[FPV_COI_COVERAGE_AT_100]: {{<relref "/doc/project/checklist.md#fpv-coi-coverage-at-100" >}}
+[NO_ISSUES_PENDING]: {{<relref "/doc/project/checklist.md#no-issues-pending" >}}
+[NO_TOOL_WARNINGS_THROWN]: {{<relref "/doc/project/checklist.md#no-tool-warnings-thrown" >}}
+[PRE_VERIFIED_SUB_MODULES_V3]: {{<relref "/doc/project/checklist.md#pre-verified-sub-modules-v3" >}}
diff --git a/hw/ip/otp_ctrl/doc/dv_plan/index.md b/hw/ip/otp_ctrl/doc/dv_plan/index.md
new file mode 100644
index 0000000..33cda76
--- /dev/null
+++ b/hw/ip/otp_ctrl/doc/dv_plan/index.md
@@ -0,0 +1,118 @@
+---
+title: "OTP_CTRL DV Plan"
+---
+
+<!-- Copy this file to hw/ip/otp_ctrl/doc/otp_ctrl_dv_plan.md and make changes as needed.
+For convenience 'otp_ctrl' in the document can be searched and replaced easily with the
+desired IP (with case sensitivity!). Also, use the testbench block diagram
+located at OpenTitan team drive / 'design verification'
+as a starting point and modify it to reflect your otp_ctrl testbench and save it
+to hw/ip/otp_ctrl/doc/tb.svg. It should get linked and rendered under the block
+diagram section below. Please update / modify / remove sections below as
+applicable. Once done, remove this comment before making a PR. -->
+
+## 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]({{< relref "hw" >}})
+ * [HW development stages]({{< relref "doc/project/development_stages" >}})
+* [Simulation results](https://reports.opentitan.org/hw/ip/otp_ctrl/dv/latest/results.html)
+
+## Design features
+For detailed information on OTP_CTRL design features, please see the [OTP_CTRL HWIP technical specification]({{< relref "hw/ip/otp_ctrl/doc" >}}).
+
+## Testbench architecture
+OTP_CTRL testbench has been constructed based on the [CIP testbench architecture]({{< relref "hw/dv/sv/cip_lib/doc" >}}).
+
+### Block diagram
+
+
+### Top level testbench
+Top level testbench is located at `hw/ip/otp_ctrl/dv/tb/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]({{< relref "hw/dv/sv/common_ifs" >}})
+* [TileLink host interface]({{< relref "hw/dv/sv/tl_agent/README.md" >}})
+* OTP_CTRL IOs
+* Interrupts ([`pins_if`]({{< relref "hw/dv/sv/common_ifs" >}})
+* Alerts ([`pins_if`]({{< relref "hw/dv/sv/common_ifs" >}})
+* Devmode ([`pins_if`]({{< relref "hw/dv/sv/common_ifs" >}})
+
+### 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]({{< relref "hw/dv/sv/dv_utils/README.md" >}})
+* [csr_utils_pkg]({{< relref "hw/dv/sv/csr_utils/README.md" >}})
+
+### Compile-time configurations
+[list compile time configurations, if any and what are they used for]
+
+### 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
+[list a few parameters, types & methods; no need to mention all]
+```
+### TL_agent
+OTP_CTRL testbench instantiates (already handled in CIP base env) [tl_agent]({{< relref "hw/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.
+
+### UVC/agent 1
+[Describe here or add link to its README]
+
+### UVC/agent 2
+[Describe here or add link to its README]
+
+### UVM RAL Model
+The OTP_CTRL RAL model is created with the [`ralgen`]({{< relref "hw/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`]({{< relref "util/reggen/README.md" >}}):
+
+### Reference models
+[Describe reference models in use if applicable, example: SHA256/HMAC]
+
+### 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:
+* task 1:
+* task 2:
+
+#### Functional coverage
+To ensure high quality constrained random stimulus, it is necessary to develop a functional coverage model.
+The following covergroups have been developed to prove that the test intent has been adequately met:
+* cg1:
+* cg2:
+
+### 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:
+* analysis port1:
+* analysis port2:
+<!-- explain inputs monitored, flow of data and outputs checked -->
+
+#### Assertions
+* TLUL assertions: The `tb/otp_ctrl_bind.sv` binds the `tlul_assert` [assertions]({{< relref "hw/ip/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.
+* assert prop 1:
+* assert prop 2:
+
+## Building and running tests
+We are using our in-house developed [regression tool]({{< relref "hw/dv/tools/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 basic sanity test:
+```console
+$ $REPO_TOP/util/dvsim/dvsim.py $REPO_TOP/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson -i otp_ctrl_sanity
+```
+
+## Testplan
+<!-- TODO: uncomment the line below after adding the testplan -->
+{{</* testplan "hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson" */>}}
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
new file mode 100644
index 0000000..f76cfdf
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
@@ -0,0 +1,39 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# 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_if
+ files:
+ - otp_ctrl_env_pkg.sv
+ - 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_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_sanity_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
new file mode 100644
index 0000000..4277f77
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv
@@ -0,0 +1,29 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class otp_ctrl_env extends cip_base_env #(
+ .CFG_T (otp_ctrl_env_cfg),
+ .COV_T (otp_ctrl_env_cov),
+ .VIRTUAL_SEQUENCER_T(otp_ctrl_virtual_sequencer),
+ .SCOREBOARD_T (otp_ctrl_scoreboard)
+ );
+ `uvm_component_utils(otp_ctrl_env)
+
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ if (!uvm_config_db#(pwr_otp_vif)::get(this, "", "pwr_otp_vif", cfg.pwr_otp_vif)) begin
+ `uvm_fatal(get_full_name(), "failed to get pwr_otp_vif from uvm_config_db")
+ end
+ if (!uvm_config_db#(mem_bkdr_vif)::get(this, "", "mem_bkdr_vif", cfg.mem_bkdr_vif)) begin
+ `uvm_fatal(`gfn, "failed to get mem_bkdr_vif from uvm_config_db")
+ end
+ endfunction
+
+ function void connect_phase(uvm_phase phase);
+ super.connect_phase(phase);
+ 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
new file mode 100644
index 0000000..04502fd
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv
@@ -0,0 +1,29 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class otp_ctrl_env_cfg extends cip_base_env_cfg #(.RAL_T(otp_ctrl_reg_block));
+
+ // ext component cfgs
+ //pwr_vif pwr_vif;
+ pwr_otp_vif pwr_otp_vif;
+ mem_bkdr_vif mem_bkdr_vif;
+
+ `uvm_object_utils_begin(otp_ctrl_env_cfg)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+
+ virtual function void initialize(bit [31:0] csr_base_addr = '1);
+ super.initialize(csr_base_addr);
+
+ // set num_interrupts & num_alerts
+ begin
+ uvm_reg rg = ral.get_reg_by_name("intr_state");
+ if (rg != null) begin
+ num_interrupts = ral.intr_state.get_n_used_bits();
+ end
+ end
+ endfunction
+
+endclass
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
new file mode 100644
index 0000000..c4ca7f8
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cov.sv
@@ -0,0 +1,32 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * 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_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
+
+ // covergroups
+ // [add covergroups here]
+
+ function new(string name, uvm_component parent);
+ super.new(name, parent);
+ // [instantiate covergroups here]
+ endfunction : new
+
+ virtual function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ // [or instantiate covergroups here]
+ // Please instantiate sticky_intr_cov array of objects for all interrupts that are sticky
+ // See cip_base_env_cov for details
+ 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
new file mode 100644
index 0000000..e8245ef
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
@@ -0,0 +1,41 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+package otp_ctrl_env_pkg;
+ // dep packages
+ import uvm_pkg::*;
+ import top_pkg::*;
+ import dv_utils_pkg::*;
+ import dv_lib_pkg::*;
+ import tl_agent_pkg::*;
+ import cip_base_pkg::*;
+ import csr_utils_pkg::*;
+ import otp_ctrl_ral_pkg::*;
+
+ // macro includes
+ `include "uvm_macros.svh"
+ `include "dv_macros.svh"
+
+ // parameters
+
+ // types
+ typedef virtual pins_if #(3) pwr_otp_vif;
+ typedef virtual mem_bkdr_if mem_bkdr_vif;
+
+ typedef enum {
+ OtpOperationDone,
+ OtpErr
+ } otp_intr_e;
+
+ // functions
+
+ // package sources
+ `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_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
new file mode 100644
index 0000000..344d64d
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -0,0 +1,99 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class otp_ctrl_scoreboard extends cip_base_scoreboard #(
+ .CFG_T(otp_ctrl_env_cfg),
+ .RAL_T(otp_ctrl_reg_block),
+ .COV_T(otp_ctrl_env_cov)
+ );
+ `uvm_component_utils(otp_ctrl_scoreboard)
+
+ // local variables
+
+ // TLM agent fifos
+
+ // local queues to hold incoming packets pending comparison
+
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ endfunction
+
+ function void connect_phase(uvm_phase phase);
+ super.connect_phase(phase);
+ endfunction
+
+ task run_phase(uvm_phase phase);
+ super.run_phase(phase);
+ fork
+ join_none
+ endtask
+
+ virtual task process_tl_access(tl_seq_item item, tl_channels_e channel = DataChannel);
+ uvm_reg csr;
+ bit do_read_check = 1'b1;
+ bit write = item.is_write();
+ uvm_reg_addr_t csr_addr = get_normalized_addr(item.a_addr);
+
+ 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 access was to a valid csr, get the csr handle
+ if (csr_addr inside {cfg.csr_addrs}) begin
+ csr = ral.default_map.get_reg_by_offset(csr_addr);
+ `DV_CHECK_NE_FATAL(csr, null)
+ end
+ else begin
+ `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
+ end
+
+ // if incoming access is a write to a valid csr, then make updates right away
+ if (addr_phase_write) begin
+ 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.get_name())
+ // add individual case item for each csr
+ "intr_state": begin
+ // FIXME
+ do_read_check = 1'b0;
+ end
+ "intr_enable": begin
+ // FIXME
+ end
+ "intr_test": begin
+ // FIXME
+ end
+ 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()))
+ end
+ void'(csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ)));
+ end
+ endtask
+
+ virtual function void reset(string kind = "HARD");
+ super.reset(kind);
+ // reset local fifos queues and variables
+ 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
+
+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
new file mode 100644
index 0000000..8d2f9db
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv
@@ -0,0 +1,14 @@
+// Copyright lowRISC contributors.
+// 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
+
+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
new file mode 100644
index 0000000..0bf784d
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv
@@ -0,0 +1,33 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class otp_ctrl_base_vseq extends cip_base_vseq #(
+ .RAL_T (otp_ctrl_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)
+
+ // various knobs to enable certain routines
+ bit do_otp_ctrl_init = 1'b1;
+
+ `uvm_object_new
+
+ virtual task dut_init(string reset_kind = "HARD");
+ super.dut_init();
+ if (do_otp_ctrl_init) otp_ctrl_init();
+ endtask
+
+ virtual task dut_shutdown();
+ // check for pending otp_ctrl operations and wait for them to complete
+ // TODO
+ endtask
+
+ // setup basic otp_ctrl features
+ virtual task otp_ctrl_init();
+ //`uvm_error(`gfn, "FIXME")
+ endtask
+
+endclass : otp_ctrl_base_vseq
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
new file mode 100644
index 0000000..5c8b898
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_common_vseq.sv
@@ -0,0 +1,17 @@
+// Copyright lowRISC contributors.
+// 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)
+
+ constraint num_trans_c {
+ num_trans inside {[1:2]};
+ }
+ `uvm_object_new
+
+ virtual task body();
+ run_common_vseq_wrapper(num_trans);
+ endtask : body
+
+endclass
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv
new file mode 100644
index 0000000..1e5f84a
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_sanity_vseq.sv
@@ -0,0 +1,19 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// basic sanity test vseq
+class otp_ctrl_sanity_vseq extends otp_ctrl_base_vseq;
+ `uvm_object_utils(otp_ctrl_sanity_vseq)
+
+ `uvm_object_new
+
+ virtual task pre_start();
+ super.pre_start();
+ endtask
+
+ task body();
+ endtask : body
+
+endclass : otp_ctrl_sanity_vseq
+
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
new file mode 100644
index 0000000..f466e67
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv
@@ -0,0 +1,8 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "otp_ctrl_base_vseq.sv"
+`include "otp_ctrl_wake_up_vseq.sv"
+`include "otp_ctrl_sanity_vseq.sv"
+`include "otp_ctrl_common_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
new file mode 100644
index 0000000..e610721
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_wake_up_vseq.sv
@@ -0,0 +1,63 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// basic sanity test vseq
+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();
+ // drive pwr_otp_req pin
+ cfg.pwr_otp_vif.drive_pin(0, 1);
+ // reset memory to avoid readout X
+ cfg.mem_bkdr_vif.clear_mem();
+ endtask
+
+ virtual task pre_start();
+ super.pre_start();
+ endtask
+
+ task body();
+ bit [TL_DW-1:0] rand_addr = $urandom_range(0, 768);
+ dut_init();
+
+ // wait until otp-init done, check status
+ wait(cfg.pwr_otp_vif.pins[2] == 1);
+ cfg.pwr_otp_vif.drive_pin(0, 0);
+ cfg.clk_rst_vif.wait_clks(1);
+ csr_wr(ral.intr_enable, 2'b11);
+ csr_rd_check(.ptr(ral.status), .compare_value(2));
+
+ // 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, 2'b11);
+
+ // 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, 2'b11);
+
+ // digest sw error seq
+ csr_wr(ral.direct_access_address, 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, 2'b11);
+
+ // digest hw seq
+ csr_wr(ral.direct_access_address, 11'h600);
+ csr_wr(ral.direct_access_cmd, 4);
+ wait(cfg.intr_vif.pins[OtpOperationDone] == 1);
+ csr_wr(ral.intr_state, OtpOperationDone);
+
+ 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
new file mode 100644
index 0000000..ff11a54
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/otp_ctrl_sim.core
@@ -0,0 +1,26 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# 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:otp_ctrl_test
+ - lowrisc:dv:otp_ctrl_sva
+ files:
+ - tb.sv
+ file_type: systemVerilogSource
+
+targets:
+ sim:
+ toplevel: tb
+ filesets:
+ - files_rtl
+ - files_dv
+ default_tool: vcs
diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
new file mode 100644
index 0000000..9acea17
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
@@ -0,0 +1,71 @@
+// Copyright lowRISC contributors.
+// 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.
+ // TODO: remove imported cfgs that do not apply.
+ import_cfgs: [// Project wide common sim cfg file
+ "{proj_root}/hw/dv/data/common_sim_cfg.hjson",
+ // Common CIP test lists
+ "{proj_root}/hw/dv/data/tests/csr_tests.hjson",
+ "{proj_root}/hw/dv/data/tests/mem_tests.hjson",
+ "{proj_root}/hw/dv/data/tests/intr_test.hjson",
+ "{proj_root}/hw/dv/data/tests/tl_access_tests.hjson",
+ "{proj_root}/hw/dv/data/tests/stress_tests.hjson"]
+
+ // Add additional tops for simulation.
+ sim_tops: ["-top {name}_bind"]
+
+ // Default iterations for all tests - each test entry can override this.
+ reseed: 50
+
+ // Default UVM test and seq class name.
+ uvm_test: otp_ctrl_base_test
+ uvm_test_seq: otp_ctrl_base_vseq
+
+ // 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_sanity
+ uvm_test_seq: otp_ctrl_sanity_vseq
+ }
+
+ // TODO: add more tests here
+ ]
+
+ // List of regressions.
+ regressions: [
+ {
+ name: sanity
+ tests: ["otp_ctrl_sanity"]
+ }
+ ]
+}
diff --git a/hw/ip/otp_ctrl/dv/tb.sv b/hw/ip/otp_ctrl/dv/tb.sv
new file mode 100644
index 0000000..a85faac
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/tb.sv
@@ -0,0 +1,79 @@
+// Copyright lowRISC contributors.
+// 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::*;
+
+ // macro includes
+ `include "uvm_macros.svh"
+ `include "dv_macros.svh"
+
+ wire clk, rst_n;
+ wire devmode;
+ // TODO: use standard req/rsp agent
+ wire [2:0] pwr_otp;
+ wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
+ wire intr_otp_operation_done, intr_otp_error;
+
+ // interfaces
+ clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
+ pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);
+ pins_if #(1) devmode_if(devmode);
+ // TODO: use standard req/rsp agent
+ pins_if #(3) pwr_otp_if(pwr_otp);
+ tl_if tl_if(.clk(clk), .rst_n(rst_n));
+
+ // dut
+ otp_ctrl dut (
+ .clk_i (clk ),
+ .rst_ni (rst_n ),
+
+ .tl_i (tl_if.h2d ),
+ .tl_o (tl_if.d2h ),
+ // interrupt
+ .intr_otp_operation_done_o (intr_otp_operation_done),
+ .intr_otp_error_o (intr_otp_error),
+ // TODO: add remaining IOs and hook them
+ .alert_rx_i ('0),
+ .otp_edn_rsp_i ('0),
+ .pwr_otp_req_i (pwr_otp[0]),
+ .pwr_otp_rsp_o (pwr_otp[2:1]),
+ .lc_otp_program_req_i ('0),
+ .lc_otp_token_req_i ('0),
+ .lc_escalate_en_i ('0),
+ .lc_provision_en_i ('0),
+ .lc_test_en_i ('0),
+ .flash_otp_key_req_i ('0),
+ .sram_otp_key_req_i ('0),
+ .otbn_otp_key_req_i ('0)
+ );
+
+ // bind mem_bkdr_if
+ `define OTP_CTRL_MEM_HIER \
+ dut.u_otp.gen_generic.u_impl_generic.i_prim_ram_1p_adv.u_mem.gen_generic.u_impl_generic
+
+ assign interrupts[OtpOperationDone] = intr_otp_operation_done;
+ assign interrupts[OtpErr] = intr_otp_error;
+
+ bind `OTP_CTRL_MEM_HIER mem_bkdr_if mem_bkdr_if();
+
+ 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#(intr_vif)::set(null, "*.env", "intr_vif", intr_if);
+ uvm_config_db#(pwr_otp_vif)::set(null, "*.env", "pwr_otp_vif", pwr_otp_if);
+ uvm_config_db#(devmode_vif)::set(null, "*.env", "devmode_vif", devmode_if);
+ uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if);
+ uvm_config_db#(mem_bkdr_vif)::set(null, "*.env", "mem_bkdr_vif", `OTP_CTRL_MEM_HIER.mem_bkdr_if);
+ $timeformat(-12, 0, " ps", 12);
+ run_test();
+ end
+
+ `undef OTP_CTRL_MEM_HIER
+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
new file mode 100644
index 0000000..9c686ce
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_base_test.sv
@@ -0,0 +1,20 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class otp_ctrl_base_test extends cip_base_test #(
+ .CFG_T(otp_ctrl_env_cfg),
+ .ENV_T(otp_ctrl_env)
+ );
+
+ `uvm_component_utils(otp_ctrl_base_test)
+ `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
new file mode 100644
index 0000000..702109a
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test.core
@@ -0,0 +1,19 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# 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
new file mode 100644
index 0000000..cde4dbf
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/tests/otp_ctrl_test_pkg.sv
@@ -0,0 +1,22 @@
+// Copyright lowRISC contributors.
+// 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