[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;