[csrng/dv] Modify seed generation/handling
Signed-off-by: Steve Nelson <steve.nelson@wdc.com>
diff --git a/hw/ip/csrng/dv/env/csrng_env_cfg.sv b/hw/ip/csrng/dv/env/csrng_env_cfg.sv
index 7224b62..6ef3ac0 100644
--- a/hw/ip/csrng/dv/env/csrng_env_cfg.sv
+++ b/hw/ip/csrng/dv/env/csrng_env_cfg.sv
@@ -119,8 +119,8 @@
`uvm_info(`gfn, $sformatf("******************************************\n"), UVM_DEBUG)
if (compare) begin
`DV_CHECK_EQ_FATAL(hw_reseed_counter, reseed_counter[app])
- `DV_CHECK_EQ_FATAL(hw_key, key[app])
`DV_CHECK_EQ_FATAL(hw_v, v[app])
+ `DV_CHECK_EQ_FATAL(hw_key, key[app])
`DV_CHECK_EQ_FATAL({hw_compliance, hw_status}, {compliance[app], status[app]})
end
endtask
diff --git a/hw/ip/csrng/dv/env/csrng_env_pkg.sv b/hw/ip/csrng/dv/env/csrng_env_pkg.sv
index 6245ef9..8f50c55 100644
--- a/hw/ip/csrng/dv/env/csrng_env_pkg.sv
+++ b/hw/ip/csrng/dv/env/csrng_env_pkg.sv
@@ -16,6 +16,8 @@
import csrng_ral_pkg::*;
import aes_model_dpi_pkg::*;
import prim_mubi_pkg::*;
+ import entropy_src_pkg::*;
+ import csrng_pkg::*;
// macro includes
`include "uvm_macros.svh"
@@ -23,6 +25,8 @@
// parameters
parameter uint NUM_HW_APPS = 2;
+ parameter uint HW_APP0 = 0;
+ parameter uint HW_APP1 = 1;
parameter uint SW_APP = 2;
parameter string LIST_OF_ALERTS[] = {"recov_alert","fatal_alert"};
parameter uint NUM_ALERTS = 2;
diff --git a/hw/ip/csrng/dv/env/csrng_scoreboard.sv b/hw/ip/csrng/dv/env/csrng_scoreboard.sv
index 834d804..526d7b2 100644
--- a/hw/ip/csrng/dv/env/csrng_scoreboard.sv
+++ b/hw/ip/csrng/dv/env/csrng_scoreboard.sv
@@ -9,20 +9,21 @@
);
`uvm_component_utils(csrng_scoreboard)
- csrng_item cs_item[NUM_HW_APPS + 1];
- push_pull_item#(.HostDataWidth(
- entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)) es_item[NUM_HW_APPS + 1];
- uint more_cmd_data;
- bit [TL_DW-1:0] hw_genbits_reg_q[$];
- bit [csrng_pkg::GENBITS_BUS_WIDTH-1:0] hw_genbits, prd_genbits_q[NUM_HW_APPS + 1][$];
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] cs_data[NUM_HW_APPS + 1], es_data[NUM_HW_APPS + 1];
- bit fips[NUM_HW_APPS + 1];
+ csrng_item cs_item[NUM_HW_APPS + 1];
+ push_pull_item#(.HostDataWidth(FIPS_CSRNG_BUS_WIDTH)) es_item[NUM_HW_APPS + 1],
+ es_item_q[NUM_HW_APPS + 1][$];
+ uint more_cmd_data;
+ bit [TL_DW-1:0] hw_genbits_reg_q[$];
+ bit [GENBITS_BUS_WIDTH-1:0] hw_genbits,
+ prd_genbits_q[NUM_HW_APPS + 1][$];
+ bit [CSRNG_BUS_WIDTH-1:0] cs_data[NUM_HW_APPS + 1],
+ es_data[NUM_HW_APPS + 1];
+ bit fips[NUM_HW_APPS + 1];
- virtual csrng_cov_if cov_vif;
+ virtual csrng_cov_if cov_vif;
// TLM agent fifos
- uvm_tlm_analysis_fifo#(push_pull_item#(.HostDataWidth(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)))
- entropy_src_fifo;
+ uvm_tlm_analysis_fifo#(push_pull_item#(.HostDataWidth(FIPS_CSRNG_BUS_WIDTH))) entropy_src_fifo;
uvm_tlm_analysis_fifo#(csrng_item) csrng_cmd_fifo[NUM_HW_APPS];
`uvm_component_new
@@ -48,14 +49,18 @@
task run_phase(uvm_phase phase);
super.run_phase(phase);
- for (int i = 0; i < NUM_HW_APPS; i++) begin
- automatic int j = i;
- fork
- begin
- process_csrng_cmd_fifo(j);
- end
- join_none;
- end
+ fork
+ collect_seeds();
+ join_none;
+
+ for (int i = 0; i < NUM_HW_APPS; i++) begin
+ automatic int j = i;
+ fork
+ begin
+ process_csrng_cmd_fifo(j);
+ end
+ join_none;
+ end
endtask
virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name);
@@ -121,40 +126,45 @@
end
if (!more_cmd_data) begin
for (int i = 0; i < cs_item[SW_APP].cmd_data_q.size(); i++) begin
- cs_data[SW_APP] = (cs_item[SW_APP].cmd_data_q[i] << i * csrng_pkg::CSRNG_CMD_WIDTH) +
+ cs_data[SW_APP] = (cs_item[SW_APP].cmd_data_q[i] << i * CSRNG_CMD_WIDTH) +
cs_data[SW_APP];
end
case (cs_item[SW_APP].acmd)
- csrng_pkg::INS: begin
+ INS: begin
if (!cs_item[SW_APP].flags[0]) begin
// Get seed
- entropy_src_fifo.get(es_item[SW_APP]);
- es_data[SW_APP] = es_item[SW_APP].d_data[entropy_src_pkg::
- CSRNG_BUS_WIDTH-1:0];
- cs_item[SW_APP].fips = es_item[SW_APP].d_data[entropy_src_pkg::
- CSRNG_BUS_WIDTH];
+ wait (es_item_q[SW_APP].size());
+ es_item[SW_APP] = es_item_q[SW_APP].pop_front;
+ es_data[SW_APP] = es_item[SW_APP].d_data[CSRNG_BUS_WIDTH-1:0];
+ fips[SW_APP] = es_item[SW_APP].d_data[CSRNG_BUS_WIDTH];
end
- ctr_drbg_instantiate(SW_APP, es_data[SW_APP], cs_data[SW_APP],
- cs_item[SW_APP].fips);
+ ctr_drbg_instantiate(SW_APP, es_data[SW_APP], cs_data[SW_APP], fips[SW_APP]);
end
- csrng_pkg::RES: begin
+ RES: begin
if (!cs_item[SW_APP].flags[0]) begin
// Get seed
- entropy_src_fifo.get(es_item[SW_APP]);
- es_data[SW_APP] = es_item[SW_APP].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH-1:0];
- cs_item[SW_APP].fips = es_item[SW_APP].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH];
+ wait (es_item_q[SW_APP].size());
+ es_item[SW_APP] = es_item_q[SW_APP].pop_front;
+ es_data[SW_APP] = es_item[SW_APP].d_data[CSRNG_BUS_WIDTH-1:0];
+ fips[SW_APP] = es_item[SW_APP].d_data[CSRNG_BUS_WIDTH];
end
- ctr_drbg_reseed(SW_APP, es_data[SW_APP], cs_data[SW_APP], cs_item[SW_APP].fips);
+ ctr_drbg_reseed(SW_APP, es_data[SW_APP], cs_data[SW_APP], fips[SW_APP]);
end
- csrng_pkg::UPD: begin
+ UPD: begin
ctr_drbg_update(SW_APP, cs_data[SW_APP]);
end
- csrng_pkg::UNI: begin
+ UNI: begin
ctr_drbg_uninstantiate(SW_APP);
end
+ default: begin
+ if (!GEN) begin
+ `uvm_fatal(`gfn, $sformatf("Invalid csrng.acmd: 0x%0h", cs_item[SW_APP].acmd))
+ end
+ end
endcase
cs_data[SW_APP] = 'h0;
es_data[SW_APP] = 'h0;
+ fips[SW_APP] = 'h0;
end
end
end
@@ -169,7 +179,7 @@
if (data_phase_read) begin
hw_genbits_reg_q.push_back(item.d_data);
end
- if (hw_genbits_reg_q.size() == csrng_pkg::GENBITS_BUS_WIDTH/TL_DW) begin
+ if (hw_genbits_reg_q.size() == GENBITS_BUS_WIDTH/TL_DW) begin
for (int i = 0; i < hw_genbits_reg_q.size(); i++) begin
hw_genbits += hw_genbits_reg_q[i] << i*TL_DW;
end
@@ -179,7 +189,7 @@
end
if (cs_item[SW_APP].genbits_q.size() == cs_item[SW_APP].glen) begin
for (int i = 0; i < cs_item[SW_APP].cmd_data_q.size(); i++) begin
- cs_data[SW_APP] = (cs_item[SW_APP].cmd_data_q[i] << i * csrng_pkg::CSRNG_CMD_WIDTH) +
+ cs_data[SW_APP] = (cs_item[SW_APP].cmd_data_q[i] << i * CSRNG_CMD_WIDTH) +
cs_data[SW_APP];
end
ctr_drbg_generate(SW_APP, cs_item[SW_APP].glen, cs_data[SW_APP]);
@@ -244,15 +254,14 @@
return output_block;
endfunction
- function void ctr_drbg_update(uint app,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] provided_data);
+ function void ctr_drbg_update(uint app, bit [CSRNG_BUS_WIDTH-1:0] provided_data);
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] temp;
- bit [CTR_LEN-1:0] inc;
- bit [BLOCK_LEN-1:0] output_block;
- bit [63:0] mod_val;
+ bit [CSRNG_BUS_WIDTH-1:0] temp;
+ bit [CTR_LEN-1:0] inc;
+ bit [BLOCK_LEN-1:0] output_block;
+ bit [63:0] mod_val;
- for (int i = 0; i < (entropy_src_pkg::CSRNG_BUS_WIDTH/BLOCK_LEN); i++) begin
+ for (int i = 0; i < (CSRNG_BUS_WIDTH/BLOCK_LEN); i++) begin
if (CTR_LEN < BLOCK_LEN) begin
inc = (cfg.v[app][CTR_LEN-1:0] + 1);
mod_val = 2**CTR_LEN;
@@ -270,19 +279,16 @@
end
temp = temp ^ provided_data;
- cfg.key[app] = temp[entropy_src_pkg::CSRNG_BUS_WIDTH-1:(entropy_src_pkg::CSRNG_BUS_WIDTH -
- KEY_LEN)];
+ cfg.key[app] = temp[CSRNG_BUS_WIDTH-1:(CSRNG_BUS_WIDTH - KEY_LEN)];
cfg.v[app] = temp[BLOCK_LEN-1:0];
endfunction
function void ctr_drbg_instantiate(uint app,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0]
- entropy_input,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0]
- additional_input,
+ bit [CSRNG_BUS_WIDTH-1:0] entropy_input,
+ bit [CSRNG_BUS_WIDTH-1:0] additional_input,
bit fips);
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] seed_material;
+ bit [CSRNG_BUS_WIDTH-1:0] seed_material;
seed_material = entropy_input ^ additional_input;
cfg.key[app] = 'h0;
@@ -294,12 +300,11 @@
endfunction
function void ctr_drbg_reseed(uint app,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] entropy_input,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0]
- additional_input,
+ bit [CSRNG_BUS_WIDTH-1:0] entropy_input,
+ bit [CSRNG_BUS_WIDTH-1:0] additional_input,
bit fips);
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] seed_material;
+ bit [CSRNG_BUS_WIDTH-1:0] seed_material;
seed_material = entropy_input ^ additional_input;
ctr_drbg_update(app, seed_material);
@@ -317,19 +322,18 @@
function void ctr_drbg_generate(uint app,
bit [18:0] glen,
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0]
- additional_input = 'h0);
+ bit [CSRNG_BUS_WIDTH-1:0] additional_input = 'h0);
- uint requested_bits;
- bit [csrng_pkg::GENBITS_BUS_WIDTH-1:0] genbits, hw_genbits;
- bit [CTR_LEN-1:0] inc;
- bit [BLOCK_LEN-1:0] output_block;
- bit [63:0] mod_val;
+ uint requested_bits;
+ bit [GENBITS_BUS_WIDTH-1:0] genbits, hw_genbits;
+ bit [CTR_LEN-1:0] inc;
+ bit [BLOCK_LEN-1:0] output_block;
+ bit [63:0] mod_val;
if (additional_input) begin
ctr_drbg_update(app, additional_input);
end
- requested_bits = glen * csrng_pkg::GENBITS_BUS_WIDTH;
+ requested_bits = glen * GENBITS_BUS_WIDTH;
for (int i = 0; i < glen; i++) begin
if (CTR_LEN < BLOCK_LEN) begin
inc = (cfg.v[app][CTR_LEN-1:0] + 1);
@@ -350,6 +354,33 @@
cfg.reseed_counter[app] += 1;
endfunction
+ task collect_seeds();
+ push_pull_item#(.HostDataWidth(FIPS_CSRNG_BUS_WIDTH)) es_item;
+ bit [1:0] cmd_arb_idx;
+ string cmd_arb_idx_q_path = "tb.dut.u_csrng_core.cmd_arb_idx_q";
+
+ `DV_CHECK_FATAL(uvm_hdl_check_path(cmd_arb_idx_q_path))
+ forever begin
+ entropy_src_fifo.get(es_item);
+ // Need to access rtl signal to determine which APP won arbitration
+ `DV_CHECK(uvm_hdl_read(cmd_arb_idx_q_path, cmd_arb_idx))
+ case (cmd_arb_idx)
+ HW_APP0: begin
+ es_item_q[HW_APP0].push_back(es_item);
+ end
+ HW_APP1: begin
+ es_item_q[HW_APP1].push_back(es_item);
+ end
+ SW_APP: begin
+ es_item_q[SW_APP].push_back(es_item);
+ end
+ default: begin
+ `uvm_fatal(`gfn, $sformatf("Invalid APP: %0d", cmd_arb_idx))
+ end
+ endcase
+ end
+ endtask
+
task process_csrng_cmd_fifo(bit[NUM_HW_APPS-1:0] app);
forever begin
csrng_cmd_fifo[app].get(cs_item[app]);
@@ -357,46 +388,42 @@
es_data[app] = '0;
fips[app] = 1'b0;
for (int i = 0; i < cs_item[app].cmd_data_q.size(); i++) begin
- cs_data[app] = (cs_item[app].cmd_data_q[i] << i * csrng_pkg::CSRNG_CMD_WIDTH) +
+ cs_data[app] = (cs_item[app].cmd_data_q[i] << i * CSRNG_CMD_WIDTH) +
cs_data[app];
end
- `uvm_info(`gfn, $sformatf("Received cs_item[%0d]:%0s", app, cs_item[app].convert2string()),
- UVM_DEBUG)
cov_vif.cg_cmds_sample(app, cs_item[app]);
case (cs_item[app].acmd)
- csrng_pkg::INS: begin
+ INS: begin
if (!cs_item[app].flags[0]) begin
// Get seed
- entropy_src_fifo.get(es_item[app]);
- `uvm_info(`gfn, $sformatf("Received es_item[%0d]:\n%0s", app,
- es_item[app].convert2string()), UVM_DEBUG)
- es_data[app] = es_item[app].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH-1:0];
- fips[app] = es_item[app].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH];
+ wait (es_item_q[app].size());
+ es_item[app] = es_item_q[app].pop_front();
+ es_data[app] = es_item[app].d_data[CSRNG_BUS_WIDTH-1:0];
+ fips[app] = es_item[app].d_data[CSRNG_BUS_WIDTH];
end
ctr_drbg_instantiate(app, es_data[app], cs_data[app], fips[app]);
end
- csrng_pkg::GEN: begin
+ GEN: begin
ctr_drbg_generate(app, cs_item[app].glen, cs_data[app]);
for (int i = 0; i < cs_item[app].glen; i++) begin
`DV_CHECK_EQ_FATAL(cs_item[app].genbits_q[i], prd_genbits_q[app][i])
end
end
- csrng_pkg::UNI: begin
+ UNI: begin
ctr_drbg_uninstantiate(app);
end
- csrng_pkg::RES: begin
- if (cs_item[app].flags[0] == 'b0) begin
+ RES: begin
+ if (!cs_item[app].flags[0]) begin
// Get seed
- entropy_src_fifo.get(es_item[app]);
- `uvm_info(`gfn, $sformatf("Received es_item[%0d]:\n%0s", app,
- es_item[app].convert2string()), UVM_DEBUG)
- es_data[app] = es_item[app].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH-1:0];
- fips[app] = es_item[app].d_data[entropy_src_pkg::CSRNG_BUS_WIDTH];
+ wait (es_item_q[app].size());
+ es_item[app] = es_item_q[app].pop_front();
+ es_data[app] = es_item[app].d_data[CSRNG_BUS_WIDTH-1:0];
+ fips[app] = es_item[app].d_data[CSRNG_BUS_WIDTH];
end
ctr_drbg_reseed(app, es_data[app], cs_data[app], fips[app]);
end
- csrng_pkg::UPD: begin
+ UPD: begin
ctr_drbg_update(app, cs_data[app]);
end
default: begin
diff --git a/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv b/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
index 860066d..4fb0863 100644
--- a/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
+++ b/hw/ip/csrng/dv/env/seq_lib/csrng_cmds_vseq.sv
@@ -6,11 +6,17 @@
`uvm_object_utils(csrng_cmds_vseq)
`uvm_object_new
- bit [entropy_src_pkg::FIPS_BUS_WIDTH - 1:0] fips;
- bit [entropy_src_pkg::CSRNG_BUS_WIDTH - 1:0] entropy;
- csrng_item cs_item_q[NUM_HW_APPS + 1][$];
- uint num_cmds, cmds_gen, cmds_sent;
- bit [csrng_pkg::GENBITS_BUS_WIDTH-1:0] genbits;
+ csrng_item cs_item_q[NUM_HW_APPS + 1][$];
+ uint num_cmds, cmds_gen, cmds_sent;
+
+ function void gen_seed(uint app);
+ bit [entropy_src_pkg::FIPS_BUS_WIDTH - 1:0] fips;
+ bit [entropy_src_pkg::CSRNG_BUS_WIDTH - 1:0] entropy;
+
+ `DV_CHECK_STD_RANDOMIZE_FATAL(fips)
+ `DV_CHECK_STD_RANDOMIZE_FATAL(entropy)
+ cfg.m_entropy_src_agent_cfg.add_d_user_data({fips, entropy});
+ endfunction
function void create_cmds(uint app);
bit uninstantiate;
@@ -20,12 +26,15 @@
// Start with instantiate command
`DV_CHECK_RANDOMIZE_WITH_FATAL(cs_item,
cs_item.acmd == csrng_pkg::INS;)
+ if (!cs_item.flags[0]) begin
+ gen_seed(app);
+ end
cs_item_q[app].push_back(cs_item);
// Randomize num_cmds and generate other commands
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(num_cmds, num_cmds inside
{ [cfg.num_cmds_min:cfg.num_cmds_max] };)
- `uvm_info(`gfn, $sformatf("num_cmds(%0d) = %0d", app, num_cmds), UVM_DEBUG)
+ `uvm_info(`gfn, $sformatf("num_cmds[%0d] = %0d", app, num_cmds), UVM_DEBUG)
// Generate other commands
for (int i = 0; i < num_cmds; i++) begin
@@ -34,6 +43,9 @@
cs_item.acmd inside { csrng_pkg::GEN,
csrng_pkg::RES,
csrng_pkg::UPD };)
+ if ((cs_item.acmd == csrng_pkg::RES) && (!cs_item.flags[0])) begin
+ gen_seed(app);
+ end
cs_item_q[app].push_back(cs_item);
end
@@ -53,8 +65,8 @@
task body();
// Create entropy_src sequence
- m_entropy_src_pull_seq = push_pull_device_seq#(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)::type_id::
- create("m_entropy_src_pull_seq");
+ m_entropy_src_pull_seq = push_pull_device_seq#(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)::
+ type_id::create("m_entropy_src_pull_seq");
// Create edn host sequences
for (int i = 0; i < NUM_HW_APPS; i++) begin
m_edn_push_seq[i] = push_pull_host_seq#(csrng_pkg::CSRNG_CMD_WIDTH)::type_id::create
@@ -63,7 +75,6 @@
// Generate queues of csrng commands
for (int i = 0; i < NUM_HW_APPS + 1; i++) begin
- `uvm_info(`gfn, $sformatf("create_cmds(%0d)", i), UVM_DEBUG)
create_cmds(i);
end
@@ -75,16 +86,9 @@
end
end
- // Start entropy_src
+ // Start entropy_src agent
fork
- begin
- for (int i = 0; i < 32; i++) begin
- `DV_CHECK_STD_RANDOMIZE_FATAL(fips)
- `DV_CHECK_STD_RANDOMIZE_FATAL(entropy)
- cfg.m_entropy_src_agent_cfg.add_d_user_data({fips, entropy});
- end
- m_entropy_src_pull_seq.start(p_sequencer.entropy_src_sequencer_h);
- end
+ m_entropy_src_pull_seq.start(p_sequencer.entropy_src_sequencer_h);
join_none
// Send commands
@@ -106,8 +110,9 @@
// Check internal state
if (cfg.check_int_state) begin
- for (int i = 0; i < NUM_HW_APPS + 1; i++)
+ for (int i = 0; i < NUM_HW_APPS + 1; i++) begin
cfg.check_internal_state(.app(i), .compare(1));
+ end
end
endtask : body
endclass : csrng_cmds_vseq