[flash_ctrl] DEBUG and Enable the OTP_MODEL For some reason, the OTP_MODEL in the Testbench had been commented out. This left the acknowledge signals floating, and hence the otp interface locked up. I have reviewed the otp_model, and have re-enabled it. This is now working with the test flash_ctrl_hw_sec_otp, and is and is safe to be present in all other tests. The otp_model is accessed through a vif between TB and the base sequence. The model provides random otp keys on demand. Signed-off-by: TIM EWINS <tim.ewins@ensilica.com>
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv index 3bd5fe3..23556b0 100644 --- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv +++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv
@@ -63,7 +63,7 @@ virtual task pre_start(); `uvm_create_on(callback_vseq, p_sequencer); - //otp_model(); // Start OTP Model + otp_model(); // Start OTP Model super.pre_start(); endtask : pre_start @@ -455,38 +455,60 @@ endtask : lc_ctrl_if_rst // Simple Model For The OTP Key Seeds + // Communicates with the TB via the flash_ctrl_vif virtual task otp_model(); - `uvm_info(`gfn, "Starting OTP Model", UVM_LOW) + `uvm_info(`gfn, "Starting OTP Model ...", UVM_LOW) + + // Initial Values + cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.key = '0; + cfg.flash_ctrl_vif.otp_rsp.rand_key = '0; + + // Note 'some values' appear in both branches of this fork, this is OK because the + // branches never run together by design. + // The order is always 'addr' followed by 'data'. fork - forever begin + forever begin // addr @(posedge cfg.clk_rst_vif.rst_n); @(posedge cfg.flash_ctrl_vif.otp_req.addr_req); - otp_addr_key = {$urandom, $urandom, $urandom, $urandom}; - otp_addr_rand_key = {$urandom, $urandom, $urandom, $urandom}; - cfg.flash_ctrl_vif.otp_rsp.key = otp_addr_key; - cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_addr_rand_key; + otp_addr_key = {$urandom, $urandom, $urandom, $urandom}; + otp_addr_rand_key = {$urandom, $urandom, $urandom, $urandom}; + `uvm_info(`gfn, $sformatf("OTP Addr Key Applied to DUT : otp_addr_key : %0x", + otp_addr_key), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("OTP Addr Rand Key Applied to DUT : otp_addr_rand_key : %0x", + otp_addr_rand_key), UVM_MEDIUM) + cfg.flash_ctrl_vif.otp_rsp.key = otp_addr_key; + cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_addr_rand_key; cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b1; - #1ns; + #1ns; // Positive Hold cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b1; @(negedge cfg.flash_ctrl_vif.otp_req.addr_req); - #1ns; + #1ns; // Positive Hold cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; end - forever begin + forever begin // data @(posedge cfg.clk_rst_vif.rst_n); @(posedge cfg.flash_ctrl_vif.otp_req.data_req); - otp_data_key = {$urandom, $urandom, $urandom, $urandom}; - otp_data_rand_key = {$urandom, $urandom, $urandom, $urandom}; - cfg.flash_ctrl_vif.otp_rsp.key = otp_data_key; - cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_data_rand_key; + otp_data_key = {$urandom, $urandom, $urandom, $urandom}; + otp_data_rand_key = {$urandom, $urandom, $urandom, $urandom}; + cfg.flash_ctrl_vif.otp_rsp.key = otp_data_key; + cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_data_rand_key; + `uvm_info(`gfn, $sformatf("OTP Data Key Applied to DUT : otp_data_key : %0x", + otp_data_key), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("OTP Data Rand Key Applied to DUT : otp_data_rand_key : %0x", + otp_data_rand_key), UVM_MEDIUM) cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b1; - #1ns; + #1ns; // Positive Hold cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b1; @(negedge cfg.flash_ctrl_vif.otp_req.data_req); - #1ns; + #1ns; // Positive Hold cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; end join_none
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv index ecb7811..2428d4f 100644 --- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv +++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv
@@ -2,16 +2,6 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -// name: secret_partition -// desc: ''' -// Verify the secret information partitions. Accessibility is controlled by the Life Cycle Controller -// Seeds are read upon flash controller initialization and sent to the Key Manager, additionally verify -// that scramble Keys are Read from the OTP and sent into the Flash Ctlr. Also erify that programmed -// Secret Partitions retain their values through a Reset Cycle. -// ''' -// milestone: V2 -// tests: ["flash_ctrl_hw_sec_otp"] - // Pseudo Code: // Randomize Flash Content (Backdoor) // Power Up Initialisation (With Secret Seeds and Keys Enabled) @@ -30,18 +20,21 @@ // Repeat // } -// flash_ctrl_secret_partition Test +// flash_ctrl_hw_sec_otp Test class flash_ctrl_hw_sec_otp_vseq extends flash_ctrl_base_vseq; `uvm_object_utils(flash_ctrl_hw_sec_otp_vseq) `uvm_object_new + // Overloaded Constraint from Base Class + constraint num_trans_c {num_trans inside {[32 : cfg.seq_cfg.max_num_trans]};} + // Configure sequence knobs to tailor it to this seq virtual function void configure_vseq(); // Max Num Iterations - cfg.seq_cfg.max_num_trans = 64; + cfg.seq_cfg.max_num_trans = 256; // Enable NO memory protection regions cfg.seq_cfg.num_en_mp_regions = 0; @@ -65,7 +58,7 @@ bit creator_prog_flag; bit owner_prog_flag; // Indicates When Secret Partition Has Been Written - `uvm_info(`gfn, "FLASH CTRL SECRET PARTITION & OTP KEY TESTS", UVM_LOW) + `uvm_info(`gfn, "TEST : FLASH CTRL SECRET PARTITION & OTP KEY TESTS", UVM_LOW) // Initialise Partion Flags to Indicate Unwritten (from Frontdoor) creator_prog_flag = 1'b0; @@ -189,7 +182,7 @@ // RESET DUT - `uvm_info(`gfn, "RESET DUT", UVM_LOW) + `uvm_info(`gfn, ">>> RESET DUT <<<", UVM_LOW) lc_ctrl_if_rst(); // Restore lc_ctrl_if to Reset Values cfg.seq_cfg.disable_flash_init = 1; // Disable Flash Random Initialisation @@ -264,7 +257,9 @@ logic [KeyWidth-1:0] prb_otp_data_rand_key[flash_ctrl_pkg::NumBanks]; // OTP SCRAMBLE KEY TESTS - CONNECTIVITY TEST ONLY - // OTP Acknowledge and Random Scramble Seeds are Provided by the TestBench (tb.sv) + + // OTP Acknowledge and Random Scramble Seeds are Provided by a model in the Base Seq + // (flash_ctrl_base_vseq), called otp_model() `uvm_info(`gfn, "FLASH OTP KEY - Scramble Connectivity Check", UVM_LOW) @@ -302,15 +297,11 @@ input logic [KeyWidth-1:0] expected_key); `uvm_info(`gfn, $sformatf("Compare OTP Key, Read : 0x%0x, Expected : 0x%0x", key, expected_key), - UVM_LOW) + UVM_MEDIUM) `DV_CHECK_EQ(key, expected_key, $sformatf( "Flash OTP Scramble Key Mismatch, Key : %s[%0d], Read : 0x%0x, Expected : 0x%0x, FAIL", - dut_prb, - i, - key, - expected_key - )) + dut_prb, i, key, expected_key)) endtask : compare_key_probe
diff --git a/hw/ip/flash_ctrl/dv/tb/tb.sv b/hw/ip/flash_ctrl/dv/tb/tb.sv index b023b9e..9459c29 100644 --- a/hw/ip/flash_ctrl/dv/tb/tb.sv +++ b/hw/ip/flash_ctrl/dv/tb/tb.sv
@@ -72,19 +72,11 @@ assign flash_ctrl_if.otp_req.addr_req = otp_req.addr_req; assign flash_ctrl_if.otp_req.data_req = otp_req.data_req; - // TODO: The otp request/response interface for keys needs to be - // propertly emulated, otherwise the flash hardware fsm will get stuck - assign flash_ctrl_if.otp_rsp = '{ - default: '0, - data_ack: otp_req.data_req, - addr_ack: otp_req.addr_req - }; - - assign otp_rsp.addr_ack = flash_ctrl_if.otp_rsp.addr_ack; - assign otp_rsp.data_ack = flash_ctrl_if.otp_rsp.data_ack; - assign otp_rsp.key = flash_ctrl_if.otp_rsp.key; - assign otp_rsp.rand_key = flash_ctrl_if.otp_rsp.rand_key; - assign otp_rsp.seed_valid = flash_ctrl_if.otp_rsp.seed_valid; + assign otp_rsp.addr_ack = flash_ctrl_if.otp_rsp.addr_ack; + assign otp_rsp.data_ack = flash_ctrl_if.otp_rsp.data_ack; + assign otp_rsp.key = flash_ctrl_if.otp_rsp.key; + assign otp_rsp.rand_key = flash_ctrl_if.otp_rsp.rand_key; + assign otp_rsp.seed_valid = flash_ctrl_if.otp_rsp.seed_valid; wire flash_test_v; assign (pull1, pull0) flash_test_v = 1'b1;