[csrng/dv] Added generate command/prediction Signed-off-by: Steve Nelson <steve.nelson@wdc.com>
diff --git a/hw/dv/sv/csrng_agent/csrng_monitor.sv b/hw/dv/sv/csrng_agent/csrng_monitor.sv index d05f45e..94b9122 100644 --- a/hw/dv/sv/csrng_agent/csrng_monitor.sv +++ b/hw/dv/sv/csrng_agent/csrng_monitor.sv
@@ -70,7 +70,6 @@ cs_item.cmd_data_q.push_back(item.h_data); end end - @(posedge cfg.vif.mon_cb.cmd_rsp.csrng_rsp_ack); `uvm_info(`gfn, $sformatf("Captured item: %s", cs_item.convert2string()), UVM_HIGH) analysis_port.write(cs_item); end
diff --git a/hw/ip/csrng/dv/env/csrng_scoreboard.sv b/hw/ip/csrng/dv/env/csrng_scoreboard.sv index 7cada3d..0b6cac7 100644 --- a/hw/ip/csrng/dv/env/csrng_scoreboard.sv +++ b/hw/ip/csrng/dv/env/csrng_scoreboard.sv
@@ -23,6 +23,7 @@ // local queues to hold incoming packets pending comparison push_pull_item#(.HostDataWidth(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)) entropy_src_q[$]; + bit [csrng_pkg::GENBITS_BUS_WIDTH-1 : 0] genbits_q[NUM_HW_APPS][$]; `uvm_component_new @@ -160,12 +161,17 @@ // post test checks - ensure that all local fifos and queues are empty endfunction - // From NIST.SP.800-90Ar1 - function bit [csrng_env_pkg::BLOCK_LEN-1:0] block_encrypt( - bit [csrng_env_pkg::KEY_LEN-1:0] key, - bit [csrng_env_pkg::BLOCK_LEN-1:0] input_block); + function void capture_genbits(bit [NUM_HW_APPS-1:0] hwapp, + bit [csrng_pkg::GENBITS_BUS_WIDTH-1:0] genbits); + genbits_q[hwapp].push_back(genbits); + endfunction - bit [csrng_env_pkg::BLOCK_LEN-1:0] output_block; + // From NIST.SP.800-90Ar1 + function bit [BLOCK_LEN-1:0] block_encrypt( + bit [KEY_LEN-1:0] key, + bit [BLOCK_LEN-1:0] input_block); + + bit [BLOCK_LEN-1:0] output_block; sv_dpi_aes_crypt_block(.impl_i(1'b0), .op_i(1'b0), .mode_i(6'b00_0001), .key_len_i(3'b100), .iv_i('h0), @@ -179,20 +185,20 @@ bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] provided_data); bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] temp; - bit [csrng_env_pkg::CTR_LEN-1:0] inc; - bit [csrng_env_pkg::BLOCK_LEN-1:0] output_block; + 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/csrng_env_pkg::BLOCK_LEN); i++) begin - if (csrng_env_pkg::CTR_LEN < csrng_env_pkg::BLOCK_LEN) begin - inc = (cfg.v[hwapp][csrng_env_pkg::CTR_LEN-1:0] + 1); - mod_val = 2**csrng_env_pkg::CTR_LEN; + for (int i = 0; i < (entropy_src_pkg::CSRNG_BUS_WIDTH/BLOCK_LEN); i++) begin + if (CTR_LEN < BLOCK_LEN) begin + inc = (cfg.v[hwapp][CTR_LEN-1:0] + 1); + mod_val = 2**CTR_LEN; inc = inc % mod_val; - cfg.v[hwapp] = {cfg.v[hwapp][csrng_env_pkg::BLOCK_LEN - 1:csrng_env_pkg::CTR_LEN], inc}; + cfg.v[hwapp] = {cfg.v[hwapp][BLOCK_LEN - 1:CTR_LEN], inc}; end else begin cfg.v[hwapp] += 1; - mod_val = 2**csrng_env_pkg::BLOCK_LEN; + mod_val = 2**BLOCK_LEN; cfg.v[hwapp] = cfg.v[hwapp] % mod_val; end @@ -202,8 +208,8 @@ temp = temp ^ provided_data; cfg.key[hwapp] = temp[entropy_src_pkg::CSRNG_BUS_WIDTH-1:(entropy_src_pkg::CSRNG_BUS_WIDTH - - csrng_env_pkg::KEY_LEN)]; - cfg.v[hwapp] = temp[csrng_env_pkg::BLOCK_LEN-1:0]; + KEY_LEN)]; + cfg.v[hwapp] = temp[BLOCK_LEN-1:0]; endfunction function void ctr_drbg_instantiate(uint hwapp, @@ -240,12 +246,47 @@ cfg.status[hwapp] = 1'b0; endfunction + function void ctr_drbg_generate(uint hwapp, + bit [18:0] requested_genbits, + bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] + additional_input = 'h0); + + uint requested_bits; + bit [csrng_pkg::GENBITS_BUS_WIDTH-1:0] genbits; + bit [CTR_LEN-1:0] inc; + bit [BLOCK_LEN-1:0] output_block; + bit [63:0] mod_val; + + requested_bits = requested_genbits * csrng_pkg::GENBITS_BUS_WIDTH; + for (int i = 0; i < requested_genbits; i++) begin + if (CTR_LEN < BLOCK_LEN) begin + inc = (cfg.v[hwapp][CTR_LEN-1:0] + 1); + mod_val = 2**CTR_LEN; + inc = inc % mod_val; + cfg.v[hwapp] = {cfg.v[hwapp][BLOCK_LEN - 1:CTR_LEN], inc}; + end + else begin + cfg.v[hwapp] += 1; + mod_val = 2**BLOCK_LEN; + cfg.v[hwapp] = cfg.v[hwapp] % mod_val; + end + output_block = block_encrypt(cfg.key[hwapp], cfg.v[hwapp]); + genbits = output_block; + `uvm_info(`gfn, $sformatf("genbits[%0d] = %h", hwapp, genbits), UVM_DEBUG) + `uvm_info(`gfn, $sformatf("genbits_q[%0d][0] = %h", hwapp, genbits_q[hwapp][0]), UVM_DEBUG) + `DV_CHECK_EQ_FATAL(genbits, genbits_q[hwapp].pop_front()) + end + ctr_drbg_update(hwapp, additional_input); + cfg.reseed_counter[hwapp] += 1; + endfunction + task process_csrng_cmd_fifo(uint hwapp); bit [entropy_src_pkg::CSRNG_BUS_WIDTH-1:0] seed; csrng_item cs_item; forever begin csrng_cmd_fifo[hwapp].get(cs_item); + `uvm_info(`gfn, $sformatf("received csrng_cmd:\n%0s", cs_item.convert2string()), UVM_HIGH) seed = '0; for (int i = 0; i < cs_item.cmd_data_q.size(); i++) begin seed = (cs_item.cmd_data_q[i] << i * csrng_pkg::CSRNG_CMD_WIDTH) + seed; @@ -253,9 +294,19 @@ case (cs_item.acmd) csrng_pkg::INS: begin + @(posedge cfg.m_edn_agent_cfg[hwapp].vif.mon_cb.cmd_rsp.csrng_rsp_ack); ctr_drbg_instantiate(hwapp, seed); end + csrng_pkg::GEN: begin + for (int i = 0; i < cs_item.glen; i++) begin + @(posedge cfg.m_edn_agent_cfg[hwapp].vif.mon_cb.cmd_rsp.genbits_valid); + capture_genbits(hwapp, cfg.m_edn_agent_cfg[hwapp].vif.mon_cb.cmd_rsp.genbits_bus); + end + @(posedge cfg.m_edn_agent_cfg[hwapp].vif.mon_cb.cmd_rsp.csrng_rsp_ack); + ctr_drbg_generate(hwapp, cs_item.glen); + end csrng_pkg::UNI: begin + @(posedge cfg.m_edn_agent_cfg[hwapp].vif.mon_cb.cmd_rsp.csrng_rsp_ack); ctr_drbg_uninstantiate(hwapp); end endcase
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 e4f05ef..5fdcadd 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
@@ -14,9 +14,7 @@ bit uninstantiate; task body(); - // TODO: Create/start entropy_src device sequence still under development. Will remove/modify - // as necessary. Also consider making task if it stays. - // TODO: Enhance to run all cmds in the queues + // TODO: Add/randomize other commands. Use/add prediction for entropy from entropy_src agent. // Create entropy_src sequence m_entropy_src_pull_seq = push_pull_device_seq#(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)::type_id:: @@ -29,27 +27,34 @@ // Generate queues of csrng commands for (int i = 0; i < NUM_HW_APPS; i++) begin - uint num_cmds; - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(num_cmds, num_cmds inside {[1:10]};) - for (int j = 0; j < num_cmds; j++) begin - `DV_CHECK_RANDOMIZE_WITH_FATAL(cs_item, - cs_item.acmd == csrng_pkg::INS; - cs_item.flags == 4'h1; - cs_item.glen == 'h0;) - `downcast(cs_item_clone, cs_item.clone()); - cs_item_q[i].push_back(cs_item_clone); - end + `DV_CHECK_RANDOMIZE_WITH_FATAL(cs_item, + cs_item.acmd == csrng_pkg::INS; + cs_item.flags == 4'h1; + cs_item.clen inside {[0:12]};) + `downcast(cs_item_clone, cs_item.clone()); + cs_item_q[i].push_back(cs_item_clone); - // Generate uninstantiate cmds + `DV_CHECK_RANDOMIZE_WITH_FATAL(cs_item, + cs_item.acmd == csrng_pkg::GEN; + cs_item.flags == 4'h0; + cs_item.clen == 4'h0; + cs_item.glen inside {[1:32]};) + `downcast(cs_item_clone, cs_item.clone()); + cs_item_q[i].push_back(cs_item_clone); + + // Randomize whether to add an uninstantiate command + // so it checks internal state without uninstantiate sometimes `DV_CHECK_STD_RANDOMIZE_FATAL(uninstantiate) - if (cs_item_q[i].size() && uninstantiate) begin + if (uninstantiate) begin `DV_CHECK_RANDOMIZE_WITH_FATAL(cs_item, cs_item.acmd == csrng_pkg::UNI;) `downcast(cs_item_clone, cs_item.clone()); cs_item_q[i].push_back(cs_item_clone); end + end - // Print cs_items + // Print cs_items + for (int i = 0; i < NUM_HW_APPS; i++) begin foreach (cs_item_q[i][j]) begin cmds_gen += 1; `uvm_info(`gfn, $sformatf("cs_item_q[%0d][%0d]: %s", i, j, cs_item_q[i][j].convert2string()), UVM_DEBUG) @@ -83,22 +88,6 @@ wait (cmds_sent == cmds_gen); join - // TODO: add other commands - // //generate cmd - // send_cmd_req(.acmd(csrng_pkg::GEN), .clen(4'h0), .flags(4'h0), .glen(19'h1)); - // genbits = ctr_drbg_generate(); - - // //reseed cmd - // send_cmd_req(.acmd(csrng_pkg::RES), .clen(4'h0), .flags(4'h0), .glen(19'h0)); - // ctr_drbg_reseed(384'hbeefdead); - - // //update cmd - // cmd_data_q.push_back(32'hdeadbeef); - // send_cmd_req(.acmd(csrng_pkg::UPD), .clen(4'h1), .flags(4'h0), .glen(19'h0), .data_q(cmd_data_q)); - // csrng_update(384'hdeadbeef); - - // send_cmd_req(.acmd(csrng_pkg::UNI), .clen(4'h0), .flags(4'h0), .glen(19'h0)); - // Check internal state if (cfg.chk_int_state) begin for (int i = 0; i < NUM_HW_APPS; i++)