blob: 7d209f6e42417ce03f711ea969abb9b9e6123d3d [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Description: sysrst_ctrl key-triggered interrupt Module
//
module sysrst_ctrl_keyintr
import sysrst_ctrl_pkg::*;
import sysrst_ctrl_reg_pkg::*;
(
input clk_i,
input rst_ni,
// (Optionally) inverted input signals on AON clock
input pwrb_int_i,
input key0_int_i,
input key1_int_i,
input key2_int_i,
input ac_present_int_i,
input ec_rst_l_int_i,
input flash_wp_l_int_i,
// CSRs synced to AON clock
input sysrst_ctrl_reg2hw_key_intr_ctl_reg_t key_intr_ctl_i,
input sysrst_ctrl_reg2hw_key_intr_debounce_ctl_reg_t key_intr_debounce_ctl_i,
output sysrst_ctrl_hw2reg_key_intr_status_reg_t key_intr_status_o,
// IRQ running on bus clock
output sysrst_ctrl_key_intr_o
);
localparam int NumKeyIntr = 7;
logic [NumKeyIntr-1:0] triggers, l2h_en, h2l_en;
assign triggers = {
pwrb_int_i,
key0_int_i,
key1_int_i,
key2_int_i,
ac_present_int_i,
ec_rst_l_int_i,
flash_wp_l_int_i
};
assign l2h_en = {
key_intr_ctl_i.pwrb_in_l2h.q,
key_intr_ctl_i.key0_in_l2h.q,
key_intr_ctl_i.key1_in_l2h.q,
key_intr_ctl_i.key2_in_l2h.q,
key_intr_ctl_i.ac_present_l2h.q,
key_intr_ctl_i.ec_rst_l_l2h.q,
key_intr_ctl_i.flash_wp_l_l2h.q
};
assign h2l_en = {
key_intr_ctl_i.pwrb_in_h2l.q,
key_intr_ctl_i.key0_in_h2l.q,
key_intr_ctl_i.key1_in_h2l.q,
key_intr_ctl_i.key2_in_h2l.q,
key_intr_ctl_i.ac_present_h2l.q,
key_intr_ctl_i.ec_rst_l_h2l.q,
key_intr_ctl_i.flash_wp_l_h2l.q
};
logic [NumKeyIntr-1:0] l2h_met_pulse, h2l_met_pulse;
for (genvar k = 0; k < NumKeyIntr; k++) begin : gen_keyfsm
sysrst_ctrl_detect #(
.DebounceTimerWidth(TimerWidth),
.DetectTimerWidth(1),
// This detects a positive edge
.EventType(EdgeToHigh),
.Sticky(0)
) u_sysrst_ctrl_detect_l2h (
.clk_i,
.rst_ni,
.trigger_i (triggers[k]),
.cfg_debounce_timer_i (key_intr_debounce_ctl_i.q),
// We're only using the debounce timer.
// The detection timer is set to 0 which corresponds to a 1 cycle detection window.
.cfg_detect_timer_i ('0),
.cfg_enable_i (l2h_en[k]),
.event_detected_o (),
.event_detected_pulse_o(l2h_met_pulse[k])
);
sysrst_ctrl_detect #(
.DebounceTimerWidth(TimerWidth),
.DetectTimerWidth(1),
// This detects a positive edge
.EventType(EdgeToLow),
.Sticky(0)
) u_sysrst_ctrl_detect_h2l (
.clk_i,
.rst_ni,
.trigger_i (triggers[k]),
.cfg_debounce_timer_i (key_intr_debounce_ctl_i.q),
// We're only using the debounce timer.
// The detection timer is set to 0 which corresponds to a 1 cycle detection window.
.cfg_detect_timer_i ('0),
.cfg_enable_i (h2l_en[k]),
.event_detected_o (),
.event_detected_pulse_o(h2l_met_pulse[k])
);
end
// Assign to CSRs
assign {key_intr_status_o.pwrb_l2h.de,
key_intr_status_o.key0_in_l2h.de,
key_intr_status_o.key1_in_l2h.de,
key_intr_status_o.key2_in_l2h.de,
key_intr_status_o.ac_present_l2h.de,
key_intr_status_o.ec_rst_l_l2h.de,
key_intr_status_o.flash_wp_l_l2h.de} = l2h_met_pulse;
assign {key_intr_status_o.pwrb_h2l.de,
key_intr_status_o.key0_in_h2l.de,
key_intr_status_o.key1_in_h2l.de,
key_intr_status_o.key2_in_h2l.de,
key_intr_status_o.ac_present_h2l.de,
key_intr_status_o.ec_rst_l_h2l.de,
key_intr_status_o.flash_wp_l_h2l.de} = h2l_met_pulse;
// Send out aggregated interrupt pulse
assign sysrst_ctrl_key_intr_o = |l2h_met_pulse || |h2l_met_pulse;
// To write into interrupt status register
assign key_intr_status_o.pwrb_h2l.d = 1'b1;
assign key_intr_status_o.pwrb_l2h.d = 1'b1;
assign key_intr_status_o.key0_in_h2l.d = 1'b1;
assign key_intr_status_o.key0_in_l2h.d = 1'b1;
assign key_intr_status_o.key1_in_h2l.d = 1'b1;
assign key_intr_status_o.key1_in_l2h.d = 1'b1;
assign key_intr_status_o.key2_in_h2l.d = 1'b1;
assign key_intr_status_o.key2_in_l2h.d = 1'b1;
assign key_intr_status_o.ac_present_h2l.d = 1'b1;
assign key_intr_status_o.ac_present_l2h.d = 1'b1;
assign key_intr_status_o.ec_rst_l_h2l.d = 1'b1;
assign key_intr_status_o.ec_rst_l_l2h.d = 1'b1;
assign key_intr_status_o.flash_wp_l_h2l.d = 1'b1;
assign key_intr_status_o.flash_wp_l_l2h.d = 1'b1;
endmodule