diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv index bfd43e0766810..6c1d60ea19ef4 100644 --- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv +++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_if.sv @@ -287,9 +287,9 @@ interface otp_ctrl_if(input clk_i, input rst_ni); (pwr_otp_idle_o == 0 || $rose(lc_prog_err)) within lc_prog_req[*1:$]) // During fatal alert, check if otp outputs revert back to default value. - // Wait two clock cycles until error propogates to each FSM states and regs. + // Wait three clock cycles until error propogates to each FSM states and regs. `define OTP_FATAL_ERR_ASSERT(NAME, SEQ) \ - `ASSERT(FatalErr``NAME``, alert_reqs |-> ##2 SEQ) + `ASSERT(FatalErr``NAME``, alert_reqs |-> ##3 SEQ) `OTP_FATAL_ERR_ASSERT(LcDataValid_A, lc_data_o.valid == 0 && lc_data_o.error == 1) `OTP_FATAL_ERR_ASSERT(LcDataState_A, lc_data_o.state == diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl.sv index c6cbd5a491306..848fab4237ba0 100644 --- a/hw/ip/otp_ctrl/rtl/otp_ctrl.sv +++ b/hw/ip/otp_ctrl/rtl/otp_ctrl.sv @@ -1292,7 +1292,22 @@ end // Output complete hardware config partition. // Actual mapping to other IPs is done via the intersignal topgen feature, // selection of fields can be done using the otp_hw_cfg_t struct fields. - assign otp_broadcast_o = named_broadcast_assign(part_init_done, part_buf_data); + otp_broadcast_t otp_broadcast; + assign otp_broadcast = named_broadcast_assign(part_init_done, part_buf_data); + + // Make sure the broadcast valid is flopped before sending it out. + lc_ctrl_pkg::lc_tx_t otp_broadcast_valid_q; + prim_lc_sender u_prim_lc_sender_otp_broadcast_valid ( + .clk_i, + .rst_ni, + .lc_en_i(otp_broadcast.valid), + .lc_en_o(otp_broadcast_valid_q) + ); + + always_comb begin : p_broadcast_valid + otp_broadcast_o = otp_broadcast; + otp_broadcast_o.valid = otp_broadcast_valid_q; + end // Root keys logic otp_keymgr_key_valid_d, otp_keymgr_key_valid_q; // need to latch valid