| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| module pinmux_wkup |
| import pinmux_pkg::*; |
| import pinmux_reg_pkg::*; |
| #( |
| parameter int Cycles = 4 |
| ) ( |
| input clk_i, |
| input rst_ni, |
| input wkup_en_i, |
| input filter_en_i, |
| input wkup_mode_e wkup_mode_i, |
| input [WkupCntWidth-1:0] wkup_cnt_th_i, |
| input pin_value_i, |
| // Wakeup request pulse signal |
| output logic aon_wkup_pulse_o |
| ); |
| |
| //////////////////////////// |
| // Optional Signal Filter // |
| //////////////////////////// |
| |
| // This uses a lower value for filtering than GPIO since the always-on clock is slower. If the |
| // filter is disabled, this reduces to a plain 2-stage flop synchronizer. |
| logic filter_out_d, filter_out_q; |
| prim_filter #( |
| .AsyncOn(1), // Instantiate 2-stage synchronizer |
| .Cycles(Cycles) |
| ) u_prim_filter ( |
| .clk_i, |
| .rst_ni, |
| .enable_i(filter_en_i), |
| .filter_i(pin_value_i), |
| .filter_o(filter_out_d) |
| ); |
| |
| ////////////////////// |
| // Pattern Matching // |
| ////////////////////// |
| |
| logic rising, falling; |
| assign falling = ~filter_out_d & filter_out_q; |
| assign rising = filter_out_d & ~filter_out_q; |
| |
| logic cnt_en, cnt_eq_th; |
| logic [WkupCntWidth-1:0] cnt_d, cnt_q; |
| assign cnt_d = (cnt_eq_th) ? '0 : (cnt_en) ? cnt_q + 1'b1 : '0; |
| |
| assign cnt_eq_th = (cnt_q >= wkup_cnt_th_i); |
| |
| always_comb begin : p_mode |
| aon_wkup_pulse_o = 1'b0; |
| cnt_en = 1'b0; |
| if (wkup_en_i) begin |
| unique case (wkup_mode_i) |
| Negedge: begin |
| aon_wkup_pulse_o = falling; |
| end |
| Edge: begin |
| aon_wkup_pulse_o = rising | falling; |
| end |
| HighTimed: begin |
| cnt_en = filter_out_d; |
| aon_wkup_pulse_o = cnt_eq_th; |
| end |
| LowTimed: begin |
| cnt_en = ~filter_out_d; |
| aon_wkup_pulse_o = cnt_eq_th; |
| end |
| // Default to rising |
| default: begin |
| aon_wkup_pulse_o = rising; |
| end |
| endcase |
| end |
| end |
| |
| always_ff @(posedge clk_i or negedge rst_ni) begin : p_aon_pattern |
| if (!rst_ni) begin |
| filter_out_q <= 1'b0; |
| cnt_q <= '0; |
| end else begin |
| filter_out_q <= filter_out_d; |
| cnt_q <= cnt_d; |
| end |
| end |
| |
| endmodule : pinmux_wkup |