[keymgr/dv] Add sideload key check 1. Add sideload key check in interface in order to check the duration as well 2. create a `get_err_code` function and simpilfy some logic in scb 3. store generated meaningful key in interface to compare with invalid keys generated by error cases 4. fix some typos in cfgen_vseq and lc_disable_vseq Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/ip/keymgr/dv/env/keymgr_env.core b/hw/ip/keymgr/dv/env/keymgr_env.core index 1dbfc73..00c41f8 100644 --- a/hw/ip/keymgr/dv/env/keymgr_env.core +++ b/hw/ip/keymgr/dv/env/keymgr_env.core
@@ -11,8 +11,8 @@ - lowrisc:dv:cip_lib - lowrisc:dv:keymgr_kmac_agent files: - - keymgr_if.sv - keymgr_env_pkg.sv + - keymgr_if.sv - keymgr_env_cfg.sv: {is_include_file: true} - keymgr_env_cov.sv: {is_include_file: true} - keymgr_virtual_sequencer.sv: {is_include_file: true}
diff --git a/hw/ip/keymgr/dv/env/keymgr_env_pkg.sv b/hw/ip/keymgr/dv/env/keymgr_env_pkg.sv index 9f1a494..7e3652a 100644 --- a/hw/ip/keymgr/dv/env/keymgr_env_pkg.sv +++ b/hw/ip/keymgr/dv/env/keymgr_env_pkg.sv
@@ -24,6 +24,7 @@ parameter uint DIGEST_SHARE_WORD_NUM = keymgr_pkg::KeyWidth / TL_DW; typedef virtual keymgr_if keymgr_vif; + typedef bit [keymgr_pkg::Shares-1:0][keymgr_pkg::KeyWidth-1:0] key_shares_t; typedef enum { IntrOpDone, NumKeyMgrIntr
diff --git a/hw/ip/keymgr/dv/env/keymgr_if.sv b/hw/ip/keymgr/dv/env/keymgr_if.sv index 35fbc3c..cc511b4 100644 --- a/hw/ip/keymgr/dv/env/keymgr_if.sv +++ b/hw/ip/keymgr/dv/env/keymgr_if.sv
@@ -17,12 +17,25 @@ keymgr_pkg::hw_key_req_t hmac_key; keymgr_pkg::hw_key_req_t aes_key; - keymgr_pkg::hw_key_req_t kmac_key_exp; - keymgr_pkg::hw_key_req_t hmac_key_exp; - keymgr_pkg::hw_key_req_t aes_key_exp; + keymgr_pkg::hw_key_req_t kmac_key_exp = '0; + keymgr_pkg::hw_key_req_t hmac_key_exp = '0; + keymgr_pkg::hw_key_req_t aes_key_exp = '0; - // indicate keymgr entered disabled directly. kmac_key are wiped, don't check output it - bit direct_to_disabled; + // connect KDF interface for assertion check + wire keymgr_pkg::kmac_data_req_t kmac_data_req; + wire keymgr_pkg::kmac_data_rsp_t kmac_data_rsp; + + // indicate if check the key is same as expected or shouldn't match to any meaningful key + bit is_kmac_key_good = 0; + bit is_hmac_key_good = 0; + bit is_aes_key_good = 0; + + // when kmac sideload key is generated, kmac may be used to do other OP, but once the OP is done, + // it should automatically switch back to sideload key + bit is_kmac_sideload_avail = 0; + keymgr_env_pkg::key_shares_t kmac_sideload_key_shares; + + keymgr_env_pkg::key_shares_t keys_a_array[string][string]; string msg_id = "keymgr_if"; @@ -31,7 +44,7 @@ // the key manager comes out of reset. // The power/reset manager ensures that // this sequencing is correct. - keymgr_en = lc_ctrl_pkg::Off; + keymgr_en = lc_ctrl_pkg::lc_tx_t'($urandom); // async delay as these signals are from different clock domain #($urandom_range(1000, 0) * 1ns); @@ -40,7 +53,6 @@ otp_hw_cfg.data.device_id = 'hF0F0; otp_key = otp_ctrl_pkg::OTP_KEYMGR_KEY_DEFAULT; flash = flash_ctrl_pkg::KEYMGR_FLASH_DEFAULT; - direct_to_disabled = 0; endtask // randomize otp, lc, flash input data @@ -74,35 +86,105 @@ flash = local_flash; endtask - task automatic update_exp_key(bit [keymgr_pkg::Shares-1:0][keymgr_pkg::KeyWidth-1:0] key_shares, - keymgr_pkg::keymgr_key_dest_e dest = keymgr_pkg::Kmac); + // update kmac key for comparison during KDF + function automatic void update_kdf_key(keymgr_env_pkg::key_shares_t key_shares, + keymgr_pkg::keymgr_working_state_e state, + bit good_key = 1); + + kmac_key_exp <= '{1'b1, key_shares[0], key_shares[1]}; + is_kmac_key_good = good_key; + endfunction + + // store internal key once it's available and use to compare if future OP is invalid + function automatic void store_internal_key(keymgr_env_pkg::key_shares_t key_shares, + keymgr_pkg::keymgr_working_state_e state); + + keys_a_array[state.name]["Internal"] = key_shares; + endfunction + + // update sideload key for comparison + // if it's good key, store it to compare for future invalid OP + function automatic void update_sideload_key(keymgr_env_pkg::key_shares_t key_shares, + keymgr_pkg::keymgr_working_state_e state, + keymgr_pkg::keymgr_key_dest_e dest = keymgr_pkg::Kmac, + bit good_key = 1); case (dest) keymgr_pkg::Kmac: begin - kmac_key_exp = '{1'b1, key_shares[0], key_shares[1]}; + kmac_key_exp <= '{1'b1, key_shares[0], key_shares[1]}; + is_kmac_key_good <= good_key; + is_kmac_sideload_avail <= 1; + kmac_sideload_key_shares <= key_shares; end keymgr_pkg::Hmac: begin - hmac_key_exp = '{1'b1, key_shares[0], key_shares[1]}; + hmac_key_exp <= '{1'b1, key_shares[0], key_shares[1]}; + is_hmac_key_good <= good_key; end keymgr_pkg::Aes: begin - aes_key_exp = '{1'b1, key_shares[0], key_shares[1]}; + aes_key_exp <= '{1'b1, key_shares[0], key_shares[1]}; + is_aes_key_good <= good_key; end default: `uvm_fatal("keymgr_if", $sformatf("Unexpect dest type %0s", dest.name)) endcase - endtask - task automatic enter_disabled_directly(); - direct_to_disabled = 1; - endtask - // TODO kmac_key only last until done signal is set. Fix this later - //`ASSERT(KmacKeyStable, $stable(kmac_key_exp) && $stable(direct_to_disabled) |=> $stable(kmac_key), - // clk, !rst_n) - //`ASSERT(KmacKeyUpdate, !$stable(kmac_key_exp) |=> kmac_key == kmac_key_exp, - // clk, !rst_n && !direct_to_disabled) + if (good_key) keys_a_array[state.name][dest.name] = key_shares; + endfunction - `ASSERT(HmacKeyStable, $stable(hmac_key_exp) |=> $stable(hmac_key), clk, !rst_n) - `ASSERT(HmacKeyUpdate, !$stable(hmac_key_exp) |=> hmac_key == hmac_key_exp, clk, !rst_n) + // if kmac sideload key is available, switch to it after an operation is completed + // if not available, de-assert valid after done is asserted + initial begin + forever begin + @(posedge clk); + if (kmac_data_rsp.done) begin + if (is_kmac_sideload_avail) begin + kmac_key_exp <= '{1'b1, kmac_sideload_key_shares[0], kmac_sideload_key_shares[1]}; + is_kmac_key_good <= 1; + end else begin + kmac_key_exp.valid <= 0; + end + end // kmac_data_rsp.done + end // forever + end - `ASSERT(AesKeyStable, $stable(aes_key_exp) |=> $stable(aes_key), clk, !rst_n) - `ASSERT(AesKeyUpdate, !$stable(aes_key_exp) |=> aes_key == aes_key_exp, clk, !rst_n) + // check if key is invalid, it should not match to any of the meaningful keys + initial begin + fork + forever begin + @(posedge clk); + if (!is_kmac_key_good) check_invalid_key(kmac_key, "KMAC"); + end + forever begin + @(posedge clk); + if (!is_hmac_key_good) check_invalid_key(hmac_key, "HMAC"); + end + forever begin + @(posedge clk); + if (!is_aes_key_good) check_invalid_key(aes_key, "AES"); + end + join + end + function automatic void check_invalid_key(keymgr_pkg::hw_key_req_t act_key, string key_name); + if (rst_n && act_key.valid) begin + foreach (keys_a_array[i, j]) begin + `DV_CHECK_NE({act_key.key_share1, act_key.key_share0}, keys_a_array[i][j], + $sformatf("%s key at state %s from %s", key_name, i, j), , msg_id) + end + end + endfunction + + `define KM_ASSERT(NAME, SEQ) \ + `ASSERT(NAME, SEQ, clk, !rst_n || keymgr_en != lc_ctrl_pkg::On) + + `KM_ASSERT(CheckKmacKey, is_kmac_key_good && kmac_key_exp.valid -> kmac_key == kmac_key_exp) + + `KM_ASSERT(CheckKmacKeyValid, kmac_key_exp.valid == kmac_key.valid) + + // TODO update hmac and aes checker later + //`KM_ASSERT(HmacKeyStable, $stable(hmac_key_exp) |=> $stable(hmac_key)) + //`KM_ASSERT(HmacKeyUpdate, !$stable(hmac_key_exp) |=> hmac_key == hmac_key_exp) + + //`KM_ASSERT(AesKeyStable, $stable(aes_key_exp) |=> $stable(aes_key)) + //`KM_ASSERT(AesKeyUpdate, !$stable(aes_key_exp) |=> aes_key == aes_key_exp) + + `undef KM_ASSERT endinterface
diff --git a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv index abd0fb8..21d3119 100644 --- a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv +++ b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
@@ -44,7 +44,7 @@ keymgr_pkg::keymgr_op_status_e current_op_status; // HW internal key, used for OP in current state - bit [keymgr_pkg::Shares-1:0][keymgr_pkg::KeyWidth-1:0] current_internal_key; + key_shares_t current_internal_key; // preserve value at TL read address phase and compare it at read data phase keymgr_pkg::keymgr_op_status_e addr_phase_op_status; @@ -60,9 +60,6 @@ bit [keymgr_pkg::AdvDataWidth-1:0] adv_data_a_array[keymgr_pkg::keymgr_working_state_e]; bit [keymgr_pkg::IdDataWidth-1:0] id_data_a_array[keymgr_pkg::keymgr_working_state_e]; bit [keymgr_pkg::GenDataWidth-1:0] sw_data_a_array[keymgr_pkg::keymgr_working_state_e]; - bit [keymgr_pkg::GenDataWidth-1:0] hw_data_a_array[keymgr_pkg::keymgr_working_state_e]; - bit [keymgr_pkg::Shares-1:0][keymgr_pkg::KeyWidth-1:0] - internal_key_a_array[keymgr_pkg::keymgr_working_state_e]; `uvm_component_new @@ -106,6 +103,8 @@ // there must be a OP which causes the KMAC data req `DV_CHECK_EQ(current_op_status, keymgr_pkg::OpWip) + if (cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On) return; + case (op) keymgr_pkg::OpAdvance: begin case (current_state) @@ -142,10 +141,10 @@ case (update_result) UpdateInternalKey: begin - `uvm_info(`gfn, $sformatf("Keymgr State from %0s to %0s", current_state.name, - get_next_state(current_state)), UVM_LOW) current_internal_key = {item.rsp_digest_share1, item.rsp_digest_share0}; - internal_key_a_array[current_state] = current_internal_key; + cfg.keymgr_vif.store_internal_key(current_internal_key, current_state); + `uvm_info(`gfn, $sformatf("Update internal key 0x%0h for state %s", current_internal_key, + current_state.name), UVM_MEDIUM) end UpdateSwOut: begin bit [keymgr_pkg::Shares-1:0][DIGEST_SHARE_WORD_NUM-1:0][TL_DW-1:0] sw_share_output; @@ -159,8 +158,17 @@ `uvm_info(`gfn, $sformatf("Predict %0s = 0x%0h", csr_name, sw_share_output[i][j]), UVM_MEDIUM) end - // TODO - UpdateHwOut: begin + end + UpdateHwOut: begin + key_shares_t key_shares = {item.rsp_digest_share1, item.rsp_digest_share0}; + bit good_key = (get_err_code() == 0); + keymgr_pkg::keymgr_key_dest_e dest = keymgr_pkg::keymgr_key_dest_e'( + `gmv(ral.control.dest_sel)); + + if (dest != keymgr_pkg::None) begin + cfg.keymgr_vif.update_sideload_key(key_shares, current_state, dest, good_key); + `uvm_info(`gfn, $sformatf("Update sideload key 0x%0h for %s", key_shares, dest.name), + UVM_MEDIUM) end end default: `uvm_info(`gfn, "KMAC result isn't updated to any output", UVM_MEDIUM) @@ -170,55 +178,47 @@ void'(ral.intr_state.predict(.value(1 << int'(IntrOpDone)))); endfunction + // update current_state, current_op_status, err_code, alert and return update_result for updating + // internal key, HW/SW output virtual function update_result_e process_update_after_op_done(); update_result_e update_result; - bit advance_state; keymgr_pkg::keymgr_ops_e op = get_operation(); + bit is_err = (get_err_code() > 0); + + if (is_err) current_op_status <= keymgr_pkg::OpDoneFail; + else current_op_status <= keymgr_pkg::OpDoneSuccess; + + process_error_n_alert(); case (current_state) - keymgr_pkg::StInit: begin - current_op_status = keymgr_pkg::OpDoneSuccess; + keymgr_pkg::StInit, keymgr_pkg::StCreatorRootKey, keymgr_pkg::StOwnerIntKey, + keymgr_pkg::StOwnerKey: begin case (op) - keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable: begin - advance_state = 1; + keymgr_pkg::OpAdvance: begin + // if it's StOwnerKey, it advacens to OpDisable. Key is just random value + if (current_state == keymgr_pkg::StOwnerKey) update_result = NotUpdate; + else update_result = UpdateInternalKey; + current_state = get_next_state(current_state); end - default: begin // gen-id/sw/hw - current_op_status = keymgr_pkg::OpDoneFail; - trigger_error(keymgr_pkg::ErrInvalidOp); - update_result = NotUpdate; + keymgr_pkg::OpDisable: begin + update_result = UpdateInternalKey; + current_state = keymgr_pkg::StDisabled; end - endcase - end - keymgr_pkg::StCreatorRootKey, keymgr_pkg::StOwnerIntKey, keymgr_pkg::StOwnerKey: begin - current_op_status = keymgr_pkg::OpDoneSuccess; - - case (op) - keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable: begin - advance_state = 1; - end - keymgr_pkg::OpGenId: begin - update_result = UpdateSwOut; - end - keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut: begin - // for gen-sw/hw, key_version is used as kmac data. If it's bigger than max - // version, status will be failed - if (get_current_max_version() < `gmv(ral.key_version)) begin - current_op_status = keymgr_pkg::OpDoneFail; - trigger_error(keymgr_pkg::ErrInvalidIn); + keymgr_pkg::OpGenId, keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut: begin + // If any error, no update for output + if (is_err) begin update_result = NotUpdate; + end else if (op == keymgr_pkg::OpGenHwOut) begin + update_result = UpdateHwOut; end else begin - if (op == keymgr_pkg::OpGenSwOut) update_result = UpdateSwOut; - else update_result = UpdateHwOut; + update_result = UpdateSwOut; end end default: `uvm_fatal(`gfn, $sformatf("Unexpected operation: %0d", op.name)) endcase end keymgr_pkg::StDisabled: begin - cfg.keymgr_vif.update_exp_key(current_internal_key); - current_op_status = keymgr_pkg::OpDoneFail; - trigger_error(keymgr_pkg::ErrInvalidOp); case (op) keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable: begin update_result = NotUpdate; @@ -235,13 +235,6 @@ default: `uvm_fatal(`gfn, $sformatf("Unexpected current_state: %0d", current_state)) endcase - if (advance_state) begin - cfg.keymgr_vif.update_exp_key(current_internal_key); - update_result = UpdateInternalKey; - if (op == keymgr_pkg::OpAdvance) current_state = get_next_state(current_state); - else current_state = keymgr_pkg::StDisabled; - end - return update_result; endfunction @@ -338,16 +331,45 @@ keymgr_pkg::keymgr_ops_e op = get_operation(); current_op_status = keymgr_pkg::OpWip; + `uvm_info(`gfn, $sformatf("At %s, %s is issued", current_state.name, op.name), UVM_LOW) + // In StReset, OP doesn't trigger KDF, update result here for InvalidOp and update // status at `op_status` // For other states, update result after KDF is done at process_kmac_data_rsp - if (current_state == keymgr_pkg::StReset && op != keymgr_pkg::OpAdvance) begin - current_op_status = keymgr_pkg::OpDoneFail; - // No KDF issued, done interrupt is triggered immediately - void'(ral.intr_state.predict(.value(1 << int'(IntrOpDone)))); - trigger_error(keymgr_pkg::ErrInvalidOp); - end - `uvm_info(`gfn, $sformatf("At %s, %s is issued", current_state.name, op.name), UVM_LOW) + case (current_state) + keymgr_pkg::StReset: begin + if (op == keymgr_pkg::OpAdvance) begin + current_internal_key = {cfg.keymgr_vif.otp_key.key_share1, + cfg.keymgr_vif.otp_key.key_share0}; + cfg.keymgr_vif.store_internal_key(current_internal_key, current_state); + end else begin // !OpAdvance + current_op_status = keymgr_pkg::OpDoneFail; + // No KDF issued, done interrupt is triggered immediately + void'(ral.intr_state.predict(.value(1 << int'(IntrOpDone)))); + process_error_n_alert(); + end + void'(ral.intr_state.predict(.value(1 << int'(IntrOpDone)))); + end + keymgr_pkg::StDisabled: begin + cfg.keymgr_vif.update_kdf_key(current_internal_key, current_state, .good_key(0)); + end + default: begin // other than StReset and StDisabled + bit good_key; + + // when advance from StOwnerKey, it is to StDisabled and key is random value + if (current_state == keymgr_pkg::StOwnerKey && op == keymgr_pkg::OpAdvance || + op == keymgr_pkg::OpDisable) begin + good_key = 0; + end else if (current_state == keymgr_pkg::StInit) begin + good_key = (get_err_code() == 0); + end else begin + // TODO should be "good_key = (get_err_code() == 0)", but dut acts as below #4826 + good_key = 1; + end + // update kmac key for check + cfg.keymgr_vif.update_kdf_key(current_internal_key, current_state, good_key); + end + endcase end // start end // addr_phase_write end @@ -358,10 +380,14 @@ if (addr_phase_read) begin addr_phase_working_state = current_state; end else if (data_phase_read) begin - keymgr_pkg::keymgr_working_state_e act_state; + // scb can't predict when advance from stReset is done, as it's updated internally and no + // output to indicate that, skip checking it + if (current_state != keymgr_pkg::StReset || current_op_status != keymgr_pkg::OpWip) begin + keymgr_pkg::keymgr_working_state_e act_state; - `downcast(act_state, item.d_data) - `DV_CHECK_EQ(act_state, addr_phase_working_state) + `downcast(act_state, item.d_data) + `DV_CHECK_EQ(act_state, addr_phase_working_state) + end end end "op_status": begin @@ -391,13 +417,12 @@ default: begin if (!uvm_re_match("sw_share*", csr.get_name())) begin // sw_share // if keymgr isn't On, SW output should be entropy and not match to predict value - //if (data_phase_read && cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On) begin - // if (item.d_data != 0) begin - // do_read_check = 1'b0; - // `DV_CHECK_NE(item.d_data, `gmv(csr)) - // end - //end - do_read_check = 1'b0; + if (data_phase_read && cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On) begin + if (item.d_data != 0) begin + do_read_check = 1'b0; + `DV_CHECK_NE(item.d_data, `gmv(csr)) + end + end end else begin // Not sw_share // TODO do_read_check = 1'b0; @@ -425,8 +450,45 @@ endfunction // TODO, need to check alert - virtual function void trigger_error(keymgr_pkg::keymgr_err_pos_e err_code); - void'(ral.err_code.predict(.value(1 << int'(err_code)))); + virtual function void process_error_n_alert(); + keymgr_pkg::keymgr_ops_e op = get_operation(); + bit [TL_DW-1:0] err = get_err_code(); + + void'(ral.err_code.predict(err)); + `uvm_info(`gfn, $sformatf("%s is issued and error code is 'b%0b", op.name, err), UVM_MEDIUM) + endfunction + + virtual function bit [TL_DW-1:0] get_err_code(); + keymgr_pkg::keymgr_ops_e op = get_operation(); + bit [TL_DW-1:0] err_code; + + case (current_state) + keymgr_pkg::StReset: begin + if (op != keymgr_pkg::OpAdvance) begin + err_code[keymgr_pkg::ErrInvalidOp] = 1; + end + end + keymgr_pkg::StInit: begin + if (!(op inside {keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable})) begin + err_code[keymgr_pkg::ErrInvalidOp] = 1; + end + end + keymgr_pkg::StCreatorRootKey, keymgr_pkg::StOwnerIntKey, keymgr_pkg::StOwnerKey: begin + if (op inside {keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut} && + get_invalid_input_error()) begin + err_code[keymgr_pkg::ErrInvalidIn] = 1; + end + end + keymgr_pkg::StDisabled: begin + err_code[keymgr_pkg::ErrInvalidOp] = 1; + end + default: `uvm_fatal(`gfn, $sformatf("unexpected state %s", current_state.name)) + endcase + return err_code; + endfunction + + virtual function bit get_invalid_input_error(); + return get_current_max_version() < `gmv(ral.key_version); endfunction virtual function void compare_adv_creator_data(bit exp_match, const ref byte byte_data_q[$]); @@ -519,8 +581,9 @@ foreach (sw_data_a_array[i]) begin `DV_CHECK_NE(act, sw_data_a_array[i], $sformatf("SW data at state %0s", i.name)) end - foreach (hw_data_a_array[i]) begin - `DV_CHECK_NE(act, hw_data_a_array[i], $sformatf("HW data at state %0s", i.name)) + foreach (cfg.keymgr_vif.keys_a_array[i, j]) begin + `DV_CHECK_NE(act, cfg.keymgr_vif.keys_a_array[i][j], + $sformatf("key at state %0s from %0s", i, j)) end endfunction @@ -552,8 +615,14 @@ return op; endfunction + virtual function keymgr_pkg::keymgr_working_state_e get_next_state(keymgr_pkg::keymgr_working_state_e cur); + if (cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On) return keymgr_pkg::StInvalid; + else return keymgr_env_pkg::get_next_state(cur); + endfunction + // TODO, need designer to update for #4680 virtual function void wipe_hw_keys(); + if (current_state != keymgr_pkg::StReset) current_state = keymgr_pkg::StInvalid; endfunction virtual function void reset(string kind = "HARD"); @@ -565,7 +634,7 @@ adv_data_a_array.delete(); id_data_a_array.delete(); sw_data_a_array.delete(); - hw_data_a_array.delete(); + endfunction function void check_phase(uvm_phase phase);
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfgen_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfgen_vseq.sv index 0e036c2..81c5736 100644 --- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfgen_vseq.sv +++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_cfgen_vseq.sv
@@ -26,7 +26,7 @@ // randomly add 0-100 cycle delay, backdoor check op_status again // When status is still OpWip, call write_cfgen_gated_reg and the write will be ignored while (!regular_vseq_done) begin - bit [TL_DW-1] op_status_val, cfgen_val; + bit [TL_DW-1:0] op_status_val, cfgen_val; uint delay; forever begin @@ -57,7 +57,7 @@ endtask virtual task write_cfgen_gated_reg(); - bit [TL_DW-1] val = $urandom; + bit [TL_DW-1:0] val = $urandom; `uvm_info(`gfn, "Write cfgen gated reg, and this write should be ignored", UVM_HIGH) // since it's timing sensitive, only write one of these reg
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_lc_disable_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_lc_disable_vseq.sv index c27a6e0..463937d 100644 --- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_lc_disable_vseq.sv +++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_lc_disable_vseq.sv
@@ -54,7 +54,7 @@ cfg.clk_rst_vif.wait_clks(delay_cycles); forever begin - bit [TL_DW-1] op_status_val; + bit [TL_DW-1:0] op_status_val; csr_rd(ral.op_status, op_status_val); if (op_status_val == keymgr_pkg::OpWip) break;
diff --git a/hw/ip/keymgr/dv/tb.sv b/hw/ip/keymgr/dv/tb.sv index 56c498c..a480a82 100644 --- a/hw/ip/keymgr/dv/tb.sv +++ b/hw/ip/keymgr/dv/tb.sv
@@ -25,6 +25,10 @@ keymgr_if keymgr_if(.clk(clk), .rst_n(rst_n)); keymgr_kmac_intf keymgr_kmac_intf(.clk(clk), .rst_n(rst_n)); + // connect KDF interface for assertion check + assign keymgr_if.kmac_data_req = keymgr_kmac_intf.kmac_data_req; + assign keymgr_if.kmac_data_rsp = keymgr_kmac_intf.kmac_data_rsp; + `DV_ALERT_IF_CONNECT // edn_clk, edn_rst_n and edn_if are defined and driven in below macro