hw/ip/prim/rtl/prim_filter_ctr.sv Cov: 100%
1: // Copyright 2018 lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Indentifier: Apache-2.0
4: //
5: // Primitive counter-based input filter, with enable.
6: // Configurable number of cycles. Cheaper version of filter for
7: // large values of #Cycles
8: //
9: // when in reset, stored value is zero
10: // when enable is false, output is input
11: // when enable is true, output is stored value,
12: // new input must be opposite value from stored value for
13: // #Cycles before switching to new value.
14:
15: module prim_filter_ctr #(parameter int unsigned Cycles = 4) (
16: input clk_i,
17: input rst_ni,
18: input enable_i,
19: input filter_i,
20: output filter_o
21: );
22:
23: localparam int unsigned CTR_WIDTH = $clog2(Cycles);
24: localparam logic [CTR_WIDTH-1:0] CYCLESM1 = (CTR_WIDTH)'(Cycles-1);
25:
26: logic [CTR_WIDTH-1:0] diff_ctr_q, diff_ctr_d;
27: logic filter_q, stored_value_q, update_stored_value;
28:
29: always_ff @(posedge clk_i or negedge rst_ni) begin
30: if (!rst_ni) begin
31: filter_q <= 1'b0;
32: end else begin
33: filter_q <= filter_i;
34: end
35: end
36:
37: always_ff @(posedge clk_i or negedge rst_ni) begin
38: if (!rst_ni) begin
39: stored_value_q <= 1'b0;
40: end else if (update_stored_value) begin
41: stored_value_q <= filter_i;
42: end
43: end
44:
45: always_ff @(posedge clk_i or negedge rst_ni) begin
46: if (!rst_ni) begin
47: diff_ctr_q <= {CTR_WIDTH{1'b0}};
48: end else begin
49: diff_ctr_q <= diff_ctr_d;
50: end
51: end
52:
53: // always look for differences, even if not filter enabled
54: assign diff_ctr_d =
55: (filter_i != filter_q) ? '0 : // restart
56: (diff_ctr_q == CYCLESM1) ? CYCLESM1 : // saturate
57: (diff_ctr_q + 1'b1); // count up
58: assign update_stored_value = (diff_ctr_d == CYCLESM1);
59:
60: assign filter_o = enable_i ? stored_value_q : filter_i;
61:
62: endmodule
63:
64: