[dv/otp] Add sequence for LC transition
This PR add a push-pull agent for otp_lc_program req.
Later PR will add more functionality to otp_lc_vseq.
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
index 3e375b1..ccf31ff 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
+++ b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
@@ -102,7 +102,7 @@
- Seq 3. Trigger escalation_en
'''
milestone: V2
- tests: []
+ tests: ["otp_ctrl_lc"]
}
{ name: otp_macro_errors
desc: '''
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
index 9e72de6..e2b07dd 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
@@ -24,6 +24,7 @@
- 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_lc_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
generate:
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv
index 713b3f4..13effd8 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.sv
@@ -16,6 +16,7 @@
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);
@@ -24,27 +25,33 @@
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);
+ 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);
+ "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);
+ 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);
+ 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 power manager pin
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")
@@ -85,10 +92,12 @@
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.req_port.connect(scoreboard.otbn_fifo.analysis_export);
m_flash_addr_pull_agent.monitor.req_port.connect(scoreboard.flash_addr_fifo.analysis_export);
m_flash_data_pull_agent.monitor.req_port.connect(scoreboard.flash_data_fifo.analysis_export);
+ m_lc_prog_pull_agent.monitor.req_port.connect(scoreboard.lc_prog_fifo.analysis_export);
end
endfunction
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
index 8e5741c..f434806 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_cfg.sv
@@ -9,6 +9,7 @@
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;
// ext interfaces
pwr_otp_vif pwr_otp_vif;
@@ -32,21 +33,26 @@
// 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] = 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 = 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 = 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 = 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
begin
uvm_reg rg = ral.get_reg_by_name("intr_state");
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
index 5dea654..c1f0d3b 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
@@ -62,11 +62,13 @@
Secret1Size + Secret2Size)/ (TL_DW / 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;
+ 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;
+ 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;
// scramble related parameters
parameter uint SCRAMBLE_DATA_SIZE = 64;
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
index dad00a9..b9a3d80 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -22,6 +22,8 @@
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
@@ -35,6 +37,7 @@
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);
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
index cb396db..2db9250 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_virtual_sequencer.sv
@@ -14,4 +14,6 @@
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_base_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_base_vseq.sv
index d526e2a..c74ba03 100644
--- 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
@@ -163,6 +163,20 @@
`uvm_send(flash_data_pull_seq)
endtask
+ virtual task req_lc_transition();
+ // TODO: this two variables are constraints to lc_prog_pull_seq once it supports data
+ // constraint
+ lc_ctrl_pkg::lc_state_e lc_state;
+ lc_ctrl_pkg::lc_cnt_e lc_cnt;
+ push_pull_host_seq#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1))
+ lc_prog_pull_seq;
+ `uvm_create_on(lc_prog_pull_seq, p_sequencer.lc_prog_pull_sequencer_h);
+ `DV_CHECK_STD_RANDOMIZE_FATAL(lc_state);
+ `DV_CHECK_STD_RANDOMIZE_FATAL(lc_cnt)
+ `DV_CHECK_RANDOMIZE_FATAL(lc_prog_pull_seq)
+ `uvm_send(lc_prog_pull_seq)
+ 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
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_lc_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_lc_vseq.sv
new file mode 100644
index 0000000..873a67b
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_lc_vseq.sv
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// otp_ctrl_lc_vseq is developed to generate lc_otp transitions
+class otp_ctrl_lc_vseq extends otp_ctrl_smoke_vseq;
+ `uvm_object_utils(otp_ctrl_lc_vseq)
+
+ `uvm_object_new
+
+ virtual task pre_start();
+ super.pre_start();
+ do_lc_trans = 1;
+ endtask
+endclass
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
index 43a1e3b..8532c89 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
@@ -11,6 +11,8 @@
`uvm_object_new
+ bit do_lc_trans;
+
rand bit [TL_AW-1:0] dai_addr;
rand bit [TL_DW-1:0] wdata0, wdata1;
rand int num_dai_op;
@@ -110,6 +112,8 @@
// check digest
check_digests();
+
+ if (do_lc_trans) req_lc_transition();
end
endtask : body
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
index 266b36b..f39e201 100644
--- 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
@@ -6,3 +6,4 @@
`include "otp_ctrl_wake_up_vseq.sv"
`include "otp_ctrl_smoke_vseq.sv"
`include "otp_ctrl_common_vseq.sv"
+`include "otp_ctrl_lc_vseq.sv"
diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
index d3a37fb..3d52156 100644
--- a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
+++ b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
@@ -60,6 +60,11 @@
uvm_test_seq: otp_ctrl_smoke_vseq
}
+ {
+ name: otp_ctrl_lc
+ uvm_test_seq: otp_ctrl_lc_vseq
+ }
+
// TODO: add more tests here
]
diff --git a/hw/ip/otp_ctrl/dv/tb.sv b/hw/ip/otp_ctrl/dv/tb.sv
index acbe89b..1041df9 100644
--- a/hw/ip/otp_ctrl/dv/tb.sv
+++ b/hw/ip/otp_ctrl/dv/tb.sv
@@ -31,7 +31,6 @@
//TODO: use push-pull agent once support
wire otp_ctrl_pkg::otp_ast_req_t ast_req;
- wire otp_ctrl_pkg::lc_otp_program_rsp_t otp_prog;
wire otp_ctrl_pkg::lc_otp_token_rsp_t otp_token;
// interfaces
@@ -39,9 +38,11 @@
pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);
pins_if #(1) devmode_if(devmode);
- 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 #(.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));
push_pull_if #(.DeviceDataWidth(cip_base_pkg::EDN_DATA_WIDTH)) edn_if(.clk(clk), .rst_n(rst_n));
@@ -82,8 +83,8 @@
.pwr_otp_i (pwr_otp[OtpPwrInitReq]),
.pwr_otp_o (pwr_otp[OtpPwrDoneRsp:OtpPwrIdleRsp]),
// lc
- .lc_otp_program_i ('0),
- .lc_otp_program_o (otp_prog),
+ .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_otp_token_i ('0),
.lc_otp_token_o (otp_token),
.lc_escalate_en_i (lc_ctrl_pkg::Off),
@@ -144,8 +145,10 @@
"*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#(.DeviceDataWidth(cip_base_pkg::EDN_DATA_WIDTH)))::set
- (null, "*env.m_edn_pull_agent*", "vif", edn_if);
+ uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(cip_base_pkg::EDN_DATA_WIDTH)))::
+ set(null, "*env.m_edn_pull_agent*", "vif", edn_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#(pwr_otp_vif)::set(null, "*.env", "pwr_otp_vif", pwr_otp_if);