fix const params, logic, casting
[RRG-proxmark3.git] / fpga / lf_edge_detect.v
blob27d7f6901ecad8c6957bc6ff36d5719607d3b574
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 module lf_edge_detect(
18 input clk,
19 input [7:0] adc_d,
20 input [7:0] lf_ed_threshold,
22 output [7:0] max,
23 output [7:0] min,
24 output [7:0] low_threshold,
25 output [7:0] high_threshold,
26 output [7:0] lowz_threshold,
27 output [7:0] highz_threshold,
28 output edge_state,
29 output edge_toggle
32 min_max_tracker tracker(
33 .clk (clk),
34 .adc_d (adc_d),
35 .threshold (lf_ed_threshold),
36 .min (min),
37 .max (max)
40 // auto-tune
41 assign high_threshold = (max + min) / 2 + (max - min) / 4;
42 assign highz_threshold = (max + min) / 2 + (max - min) / 8;
43 assign lowz_threshold = (max + min) / 2 - (max - min) / 8;
44 assign low_threshold = (max + min) / 2 - (max - min) / 4;
46 // heuristic to see if it makes sense to try to detect an edge
47 wire enabled =
48 (high_threshold > highz_threshold)
49 & (highz_threshold > lowz_threshold)
50 & (lowz_threshold > low_threshold)
51 & ((high_threshold - highz_threshold) > 8)
52 & ((highz_threshold - lowz_threshold) > 16)
53 & ((lowz_threshold - low_threshold) > 8);
55 // Toggle the output with hysteresis
56 // Set to high if the ADC value is above the threshold
57 // Set to low if the ADC value is below the threshold
58 reg is_high = 0;
59 reg is_low = 0;
60 reg is_zero = 0;
61 reg trigger_enabled = 1;
62 reg output_edge = 0;
63 reg output_state;
65 always @(posedge clk)
66 begin
67 is_high <= (adc_d >= high_threshold);
68 is_low <= (adc_d <= low_threshold);
69 is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold));
70 end
72 // all edges detection
73 always @(posedge clk)
74 if (enabled)
75 begin
76 // To enable detecting two consecutive peaks at the same level
77 // (low or high) we check whether or not we went back near 0 in-between.
78 // This extra check is necessary to prevent from noise artifacts
79 // around the threshold values.
80 if (trigger_enabled & (is_high | is_low))
81 begin
82 output_edge <= ~output_edge;
83 trigger_enabled <= 0;
84 end
85 else
86 trigger_enabled <= trigger_enabled | is_zero;
87 end
89 // edge states
90 always @(posedge clk)
91 if (enabled)
92 begin
93 if (is_high)
94 output_state <= 1'd1;
95 else if (is_low)
96 output_state <= 1'd0;
97 end
99 assign edge_state = output_state;
100 assign edge_toggle = output_edge;
102 endmodule