forked from pulp-platform/common_cells
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcc_serial_deglitch.sv
More file actions
61 lines (51 loc) · 2.55 KB
/
Copy pathcc_serial_deglitch.sv
File metadata and controls
61 lines (51 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Copyright 2026 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
// Authors:
// - Philippe Sauter <phsauter@iis.ee.ethz.ch>
//
// Description: Serial Line Deglitcher
// Update output only after d_i has remained stable for Threshold cycles.
// The output q_o changes to the current level of d_i only after
// d_i has remained stable at that level for at least
// Threshold consecutive enabled (en_i) clock cycles.
// restart_i synchronously resets the history and immediately sets q_o to current d_i.
// clr_i synchronously resets all state (history and output) to their reset values.
`include "common_cells/registers.svh"
`include "common_cells/assertions.svh"
module cc_serial_deglitch #(
parameter int unsigned Threshold = 4
)(
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic clr_i, // Synchronous clear active high
input logic restart_i,
input logic en_i,
input logic d_i,
output logic q_o
);
localparam int unsigned CntWidth = cc_pkg::idx_width(Threshold + 1);
logic [CntWidth-1:0] count_q, count_d;
logic mismatch, stable_edge;
logic count_load, count_clear;
logic q_d;
assign mismatch = (d_i != q_o);
assign count_d = count_q + CntWidth'(1);
// Update when the mismatch counter reaches Threshold.
assign stable_edge = en_i && mismatch && (count_d == CntWidth'(Threshold));
// Clear if signal is not different/stable or when updating the output.
assign count_clear = clr_i || restart_i || (en_i && !mismatch) || stable_edge;
assign count_load = en_i && mismatch && !stable_edge;
assign q_d = (restart_i || stable_edge) ? d_i : q_o;
`FFLARNC(count_q, count_d, count_load, count_clear, '0, clk_i, rst_ni)
`FFARNC(q_o, q_d, clr_i, 1'b0, clk_i, rst_ni)
`ifndef COMMON_CELLS_ASSERTS_OFF
`ASSERT_INIT(ThresholdGtZero, Threshold >= 1, "cc_serial_deglitch: Threshold must be >= 1")
`endif
endmodule