[dv/top_level] Randomize lc exit_token value
This PR supports randomize lc exit_token in SV and C test.
To support this:
1). Add a random array in SV and pass it to C test.
2). Add cshake128 dpi function to decode the exit_token value.
This PR finishes a TODO in issue #7665
Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/top_earlgrey/dv/env/chip_env.core b/hw/top_earlgrey/dv/env/chip_env.core
index bbe5439..2610b89 100644
--- a/hw/top_earlgrey/dv/env/chip_env.core
+++ b/hw/top_earlgrey/dv/env/chip_env.core
@@ -10,15 +10,17 @@
- lowrisc:opentitan:bus_params_pkg
- lowrisc:systems:top_earlgrey_pkg
- lowrisc:ip:spi_device
- - lowrisc:dv:ralgen
- - lowrisc:dv:str_utils
+ - lowrisc:ip:kmac_pkg
- lowrisc:dv:cip_lib
- - lowrisc:dv:uart_agent
+ - lowrisc:dv:digestpp_dpi
- lowrisc:dv:jtag_riscv_agent
- - lowrisc:dv:spi_agent
- lowrisc:dv:mem_bkdr_util
+ - lowrisc:dv:ralgen
+ - lowrisc:dv:spi_agent
+ - lowrisc:dv:str_utils
- lowrisc:dv:sw_test_status
- lowrisc:dv:sw_logger_if
+ - lowrisc:dv:uart_agent
files:
- chip_env_pkg.sv
- chip_env_cfg.sv: {is_include_file: true}
diff --git a/hw/top_earlgrey/dv/env/chip_env_pkg.sv b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
index 5b0b355..b308066 100644
--- a/hw/top_earlgrey/dv/env/chip_env_pkg.sv
+++ b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
@@ -3,27 +3,31 @@
// SPDX-License-Identifier: Apache-2.0
package chip_env_pkg;
+
// dep packages
import uvm_pkg::*;
import top_pkg::*;
- import flash_ctrl_pkg::*;
- import otp_ctrl_pkg::*;
- import sram_ctrl_pkg::*;
- import dv_utils_pkg::*;
- import dv_base_reg_pkg::*;
+
+ import bus_params_pkg::*;
+ import chip_ral_pkg::*;
+ import cip_base_pkg::*;
import csr_utils_pkg::*;
+ import digestpp_dpi_pkg::*;
+ import dv_base_reg_pkg::*;
+ import dv_lib_pkg::*;
+ import dv_utils_pkg::*;
+ import flash_ctrl_pkg::*;
+ import jtag_riscv_agent_pkg::*;
+ import kmac_pkg::*;
+ import mem_bkdr_util_pkg::*;
+ import otp_ctrl_pkg::*;
+ import spi_agent_pkg::*;
+ import sram_ctrl_pkg::*;
+ import str_utils_pkg::*;
+ import sw_test_status_pkg::*;
import tl_agent_pkg::*;
import uart_agent_pkg::*;
- import jtag_riscv_agent_pkg::*;
- import spi_agent_pkg::*;
- import dv_lib_pkg::*;
- import cip_base_pkg::*;
- import chip_ral_pkg::*;
- import sw_test_status_pkg::*;
import xbar_env_pkg::*;
- import bus_params_pkg::*;
- import str_utils_pkg::*;
- import mem_bkdr_util_pkg::*;
// macro includes
`include "uvm_macros.svh"
diff --git a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_ctrl_transition_vseq.sv b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_ctrl_transition_vseq.sv
index 519e367..0a79741 100644
--- a/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_ctrl_transition_vseq.sv
+++ b/hw/top_earlgrey/dv/env/seq_lib/chip_sw_lc_ctrl_transition_vseq.sv
@@ -7,6 +7,12 @@
`uvm_object_new
+ // LC sends two 64-bit msg as input token.
+ localparam uint ExitTokenWidthBit = kmac_pkg::MsgWidth * 2;
+ localparam uint ExitTokenWidthByte = ExitTokenWidthBit / 8;
+
+ rand bit [7:0] lc_exit_token[ExitTokenWidthByte];
+
virtual task dut_init(string reset_kind = "HARD");
bit [otp_ctrl_reg_pkg::TestUnlockTokenSize-1:0] rand_unlock_token;
`DV_CHECK_STD_RANDOMIZE_FATAL(rand_unlock_token)
@@ -17,18 +23,40 @@
cfg.mem_bkdr_util_h[Otp].otp_write_lc_partition(lc_ctrl_state_pkg::LcStTestUnlocked2);
// Override the test exit token to match SW test's input token.
- // TODO: randomize the exit_token.
cfg.mem_bkdr_util_h[Otp].otp_write_secret0_partition(
.unlock_token(rand_unlock_token),
- .exit_token('h547070d7503264af5b9a971b894ef3be));
+ .exit_token(get_otp_exit_token(lc_exit_token)));
endtask
+ // This function takes the token value from LC_CTRL token CSRs, then runs through cshake128 to
+ // get a 768-bit XORed token output.
+ // The first 128 bits of the decoded token should match the OTP's secret9 paritition's
+ // descrambled exit token value.
+ virtual function bit[ExitTokenWidthBit-1:0] get_otp_exit_token(
+ bit[7:0] token_in[ExitTokenWidthByte]);
+
+ bit [7:0] dpi_digest[kmac_pkg::AppDigestW/8];
+ bit [kmac_pkg::AppDigestW-1:0] digest_bits;
+
+ digestpp_dpi_pkg::c_dpi_cshake128(token_in, "", "LC_CTRL", ExitTokenWidthByte,
+ kmac_pkg::AppDigestW/8, dpi_digest);
+
+ digest_bits = {<< byte {dpi_digest}};
+ return (digest_bits[ExitTokenWidthBit-1:0]);
+ endfunction
+
virtual task body();
+ byte lc_exit_token_byte [ExitTokenWidthByte];
super.body();
- // Select LC jtag.
+ // Select LC jtag.
cfg.tap_straps_vif.drive(SelectLCJtagTap);
+ // Override the C test kLcExitToken with random data.
+ // TODO: try to remove this conversion variable, and use `bit[7:0]` array type as input.
+ foreach (lc_exit_token[i]) lc_exit_token_byte[i] = lc_exit_token[i];
+ sw_symbol_backdoor_overwrite("kLcExitToken", lc_exit_token_byte);
+
// Wait for SW to finish set up LC_CTRL.
cfg.clk_rst_vif.wait_clks(21000);
diff --git a/sw/device/tests/sim_dv/lc_ctrl_transition_test.c b/sw/device/tests/sim_dv/lc_ctrl_transition_test.c
index 6ec9087..4cf8c1e 100644
--- a/sw/device/tests/sim_dv/lc_ctrl_transition_test.c
+++ b/sw/device/tests/sim_dv/lc_ctrl_transition_test.c
@@ -21,9 +21,8 @@
const test_config_t kTestConfig;
-// TODO: Issue more resets and andomize this array in each reset.
// LC exit token value for LC state transition.
-static const uint8_t lc_exit_token[LC_TOKEN_SIZE] = {
+static volatile const uint8_t kLcExitToken[LC_TOKEN_SIZE] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
@@ -75,7 +74,9 @@
dif_lc_ctrl_token_t token;
dif_lc_ctrl_settings_t settings;
settings.clock_select = kDifLcCtrlInternalClockEn;
- memcpy(token.data, lc_exit_token, sizeof(lc_exit_token));
+ for (int i = 0; i < LC_TOKEN_SIZE; i++) {
+ token.data[i] = kLcExitToken[i];
+ }
CHECK(dif_lc_ctrl_mutex_try_acquire(&lc) == kDifLcCtrlMutexOk);
CHECK(dif_lc_ctrl_transition(&lc, kDifLcCtrlStateDev, &token, &settings) ==
kDifLcCtrlMutexOk,