diff --git a/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv b/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv index 82deb6eddacbd..da0f96d83f023 100644 --- a/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv +++ b/hw/ip_templates/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv @@ -21,6 +21,7 @@ class pwrmgr_escalation_timeout_vseq extends pwrmgr_base_vseq; UVM_MEDIUM) cfg.esc_clk_rst_vif.stop_clk(); cfg.clk_rst_vif.wait_clks(stop_cycles); + `uvm_info(`gfn, "Restarting escalation clock", UVM_MEDIUM) cfg.esc_clk_rst_vif.start_clk(); cfg.esc_clk_rst_vif.wait_clks(4000); end diff --git a/hw/ip_templates/pwrmgr/rtl/pwrmgr.sv b/hw/ip_templates/pwrmgr/rtl/pwrmgr.sv index 05d3944622199..363c79e4a4d00 100644 --- a/hw/ip_templates/pwrmgr/rtl/pwrmgr.sv +++ b/hw/ip_templates/pwrmgr/rtl/pwrmgr.sv @@ -184,7 +184,7 @@ module pwrmgr end localparam int EscTimeOutCnt = 128; - logic esc_timeout; + logic esc_timeout, esc_timeout_lc_d, esc_timeout_lc_q; // SEC_CM: ESC_RX.CLK.BKGN_CHK, ESC_RX.CLK.LOCAL_ESC prim_clock_timeout #( .TimeOutCnt(EscTimeOutCnt) @@ -199,6 +199,25 @@ module pwrmgr .timeout_o(esc_timeout) ); + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_esc_timeout_sync ( + .clk_i(clk_lc), + .rst_ni(rst_lc_n), + .d_i(esc_timeout), + .q_o(esc_timeout_lc_d) + ); + + always_ff @(posedge clk_lc or negedge rst_lc_n) begin + if (!rst_lc_n) begin + esc_timeout_lc_q <= '0; + end else if (esc_timeout_lc_d) begin + // once latched, do not clear until reset + esc_timeout_lc_q <= 1'b1; + end + end + //////////////////////////// /// async declarations @@ -210,7 +229,7 @@ module pwrmgr assign peri_reqs_raw.rstreqs[NumRstReqs-1:0] = rstreqs_i; assign peri_reqs_raw.rstreqs[ResetMainPwrIdx] = slow_rst_req; // SEC_CM: ESC_RX.CLK.LOCAL_ESC, CTRL_FLOW.GLOBAL_ESC - assign peri_reqs_raw.rstreqs[ResetEscIdx] = esc_rst_req_q | esc_timeout; + assign peri_reqs_raw.rstreqs[ResetEscIdx] = esc_rst_req_q | esc_timeout_lc_q; assign peri_reqs_raw.rstreqs[ResetNdmIdx] = ndm_req_valid; //////////////////////////// @@ -328,7 +347,7 @@ module pwrmgr assign hw2reg.fault_status.reg_intg_err.de = reg_intg_err; assign hw2reg.fault_status.reg_intg_err.d = 1'b1; - assign hw2reg.fault_status.esc_timeout.de = esc_timeout; + assign hw2reg.fault_status.esc_timeout.de = esc_timeout_lc_q; assign hw2reg.fault_status.esc_timeout.d = 1'b1; // The main power domain glitch automatically causes a reset, so regsitering diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv index 82deb6eddacbd..da0f96d83f023 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv @@ -21,6 +21,7 @@ class pwrmgr_escalation_timeout_vseq extends pwrmgr_base_vseq; UVM_MEDIUM) cfg.esc_clk_rst_vif.stop_clk(); cfg.clk_rst_vif.wait_clks(stop_cycles); + `uvm_info(`gfn, "Restarting escalation clock", UVM_MEDIUM) cfg.esc_clk_rst_vif.start_clk(); cfg.esc_clk_rst_vif.wait_clks(4000); end diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/rtl/pwrmgr.sv b/hw/top_earlgrey/ip_autogen/pwrmgr/rtl/pwrmgr.sv index 05d3944622199..363c79e4a4d00 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/rtl/pwrmgr.sv +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/rtl/pwrmgr.sv @@ -184,7 +184,7 @@ module pwrmgr end localparam int EscTimeOutCnt = 128; - logic esc_timeout; + logic esc_timeout, esc_timeout_lc_d, esc_timeout_lc_q; // SEC_CM: ESC_RX.CLK.BKGN_CHK, ESC_RX.CLK.LOCAL_ESC prim_clock_timeout #( .TimeOutCnt(EscTimeOutCnt) @@ -199,6 +199,25 @@ module pwrmgr .timeout_o(esc_timeout) ); + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_esc_timeout_sync ( + .clk_i(clk_lc), + .rst_ni(rst_lc_n), + .d_i(esc_timeout), + .q_o(esc_timeout_lc_d) + ); + + always_ff @(posedge clk_lc or negedge rst_lc_n) begin + if (!rst_lc_n) begin + esc_timeout_lc_q <= '0; + end else if (esc_timeout_lc_d) begin + // once latched, do not clear until reset + esc_timeout_lc_q <= 1'b1; + end + end + //////////////////////////// /// async declarations @@ -210,7 +229,7 @@ module pwrmgr assign peri_reqs_raw.rstreqs[NumRstReqs-1:0] = rstreqs_i; assign peri_reqs_raw.rstreqs[ResetMainPwrIdx] = slow_rst_req; // SEC_CM: ESC_RX.CLK.LOCAL_ESC, CTRL_FLOW.GLOBAL_ESC - assign peri_reqs_raw.rstreqs[ResetEscIdx] = esc_rst_req_q | esc_timeout; + assign peri_reqs_raw.rstreqs[ResetEscIdx] = esc_rst_req_q | esc_timeout_lc_q; assign peri_reqs_raw.rstreqs[ResetNdmIdx] = ndm_req_valid; //////////////////////////// @@ -328,7 +347,7 @@ module pwrmgr assign hw2reg.fault_status.reg_intg_err.de = reg_intg_err; assign hw2reg.fault_status.reg_intg_err.d = 1'b1; - assign hw2reg.fault_status.esc_timeout.de = esc_timeout; + assign hw2reg.fault_status.esc_timeout.de = esc_timeout_lc_q; assign hw2reg.fault_status.esc_timeout.d = 1'b1; // The main power domain glitch automatically causes a reset, so regsitering