blob: 8dd8979c1041dc8b61f383505d28c97c474f010d [file] [log] [blame]
// 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