| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // Description: sysrst_ctrl combo action Module |
| // |
| module sysrst_ctrl_comboact import sysrst_ctrl_reg_pkg::*; ( |
| input clk_aon_i, |
| input rst_aon_ni, |
| input clk_i, |
| input rst_ni, |
| |
| input cfg_intr_en, |
| input cfg_bat_disable_en, |
| input cfg_ec_rst_en, |
| input cfg_gsc_rst_en, |
| input combo_det, |
| input ec_rst_l_i, |
| |
| input sysrst_ctrl_reg2hw_ec_rst_ctl_reg_t ec_rst_ctl_i, |
| |
| output combo_intr_pulse, |
| output bat_disable_o, |
| output gsc_rst_o, |
| output ec_rst_l_o |
| ); |
| |
| logic [15:0] cfg_ec_rst_timer; |
| logic load_ec_rst_timer; |
| logic [15:0] cfg_ec_rst_timer_d; |
| |
| logic combo_det_q; |
| logic combo_gsc_pulse; |
| logic combo_bat_disable_pulse; |
| logic bat_disable_q, bat_disable_d; |
| logic gsc_rst_q, gsc_rst_d; |
| logic combo_ec_rst_pulse; |
| logic ec_rst_l_q, ec_rst_l_d; |
| |
| logic [15:0] timer_cnt_d, timer_cnt_q; |
| logic timer_cnt_clr, timer_cnt_en; |
| |
| logic ec_rst_l_int, ec_rst_l_det; |
| |
| //delay the level signal to generate a pulse |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_combo_det |
| if (!rst_aon_ni) begin |
| combo_det_q <= 1'b0; |
| end else begin |
| combo_det_q <= combo_det; |
| end |
| end |
| |
| //bat_disable logic |
| assign combo_bat_disable_pulse = cfg_bat_disable_en && (combo_det_q == 1'b0) && |
| (combo_det == 1'b1); |
| |
| assign bat_disable_d = combo_bat_disable_pulse ? 1'b1 : bat_disable_q; |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_combo_bat_disable |
| if (!rst_aon_ni) begin |
| bat_disable_q <= 1'b0; |
| end else begin |
| bat_disable_q <= bat_disable_d; |
| end |
| end |
| |
| assign bat_disable_o = bat_disable_q; |
| |
| //Interrupt logic |
| assign combo_intr_pulse = cfg_intr_en && (combo_det_q == 1'b0) && (combo_det == 1'b1); |
| |
| //ec_rst_logic |
| //synchronize between cfg(24MHz) and always-on(200KHz) |
| prim_fifo_async #( |
| .Width(16), |
| .Depth(2) |
| ) i_cfg_ec_rst_pulse ( |
| .clk_wr_i (clk_i), |
| .rst_wr_ni (rst_ni), |
| .wvalid_i (ec_rst_ctl_i.qe), |
| .wready_o (), |
| .wdata_i (ec_rst_ctl_i.q), |
| .wdepth_o (), |
| |
| .clk_rd_i (clk_aon_i), |
| .rst_rd_ni (rst_aon_ni), |
| .rvalid_o (load_ec_rst_timer), |
| .rready_i (1'b1), |
| .rdata_o (cfg_ec_rst_timer_d), |
| .rdepth_o () |
| ); |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_cfg_ec_rst_timer_reg |
| if (!rst_aon_ni) begin |
| cfg_ec_rst_timer <= '0; |
| end else if (load_ec_rst_timer) begin |
| cfg_ec_rst_timer <= cfg_ec_rst_timer_d; |
| end |
| end |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_ec_rst_l_int |
| if (!rst_aon_ni) begin |
| ec_rst_l_int <= 1'b1;//active low signal |
| end else begin |
| ec_rst_l_int <= ec_rst_l_i; |
| end |
| end |
| |
| //ec_rst_l_i high->low detection |
| assign ec_rst_l_det = (ec_rst_l_int == 1'b1) && (ec_rst_l_i == 1'b0); |
| |
| //combo with EC RST CFG enable |
| assign combo_ec_rst_pulse = cfg_ec_rst_en && (combo_det_q == 1'b0) && (combo_det == 1'b1); |
| |
| //GSC reset will also reset EC |
| assign ec_rst_l_d = (combo_ec_rst_pulse | combo_gsc_pulse | ec_rst_l_det) ? 1'b0 : |
| timer_cnt_clr ? 1'b1 : ec_rst_l_q; |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_combo_ec_rst_l |
| if (!rst_aon_ni) begin |
| ec_rst_l_q <= 1'b0;//asserted when power-on-reset is asserted |
| end else begin |
| ec_rst_l_q <= ec_rst_l_d; |
| end |
| end |
| |
| assign timer_cnt_en = (ec_rst_l_q == 1'b0); |
| |
| assign timer_cnt_clr = (ec_rst_l_q == 1'b0) && (timer_cnt_q == cfg_ec_rst_timer); |
| |
| assign timer_cnt_d = (timer_cnt_en) ? timer_cnt_q + 1'b1 : timer_cnt_q; |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: timer_cnt_regs |
| if (!rst_aon_ni) begin |
| timer_cnt_q <= '0; |
| end |
| else if (timer_cnt_clr) begin |
| timer_cnt_q <= '0; |
| end else begin |
| timer_cnt_q <= timer_cnt_d; |
| end |
| end |
| |
| assign ec_rst_l_o = ec_rst_l_q; |
| |
| //gsc_rst_logic |
| assign combo_gsc_pulse = cfg_gsc_rst_en && (combo_det_q == 1'b0) && (combo_det == 1'b1); |
| |
| assign gsc_rst_d = combo_gsc_pulse ? 1'b1 : gsc_rst_q; |
| |
| always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin: i_combo_gsc_rst |
| if (!rst_aon_ni) begin |
| gsc_rst_q <= 1'b0; |
| end else begin |
| gsc_rst_q <= gsc_rst_d; |
| end |
| end |
| |
| assign gsc_rst_o = gsc_rst_q; |
| |
| endmodule |