]>
Commit | Line | Data |
---|---|---|
1 | //----------------------------------------------------------------------------- | |
2 | // Copyright (C) 2014 iZsh <izsh at fail0verflow.com> | |
3 | // | |
4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, | |
5 | // at your option, any later version. See the LICENSE.txt file for the text of | |
6 | // the license. | |
7 | //----------------------------------------------------------------------------- | |
8 | // input clk is 24Mhz | |
9 | `include "min_max_tracker.v" | |
10 | ||
11 | module lf_edge_detect(input clk, input [7:0] adc_d, input [7:0] lf_ed_threshold, | |
12 | output [7:0] max, output [7:0] min, | |
13 | output [7:0] high_threshold, output [7:0] highz_threshold, | |
14 | output [7:0] lowz_threshold, output [7:0] low_threshold, | |
15 | output edge_state, output edge_toggle); | |
16 | ||
17 | min_max_tracker tracker(clk, adc_d, lf_ed_threshold, min, max); | |
18 | ||
19 | // auto-tune | |
20 | assign high_threshold = (max + min) / 2 + (max - min) / 4; | |
21 | assign highz_threshold = (max + min) / 2 + (max - min) / 8; | |
22 | assign lowz_threshold = (max + min) / 2 - (max - min) / 8; | |
23 | assign low_threshold = (max + min) / 2 - (max - min) / 4; | |
24 | ||
25 | // heuristic to see if it makes sense to try to detect an edge | |
26 | wire enabled = | |
27 | (high_threshold > highz_threshold) | |
28 | & (highz_threshold > lowz_threshold) | |
29 | & (lowz_threshold > low_threshold) | |
30 | & ((high_threshold - highz_threshold) > 8) | |
31 | & ((highz_threshold - lowz_threshold) > 16) | |
32 | & ((lowz_threshold - low_threshold) > 8); | |
33 | ||
34 | // Toggle the output with hysteresis | |
35 | // Set to high if the ADC value is above the threshold | |
36 | // Set to low if the ADC value is below the threshold | |
37 | reg is_high = 0; | |
38 | reg is_low = 0; | |
39 | reg is_zero = 0; | |
40 | reg trigger_enabled = 1; | |
41 | reg output_edge = 0; | |
42 | reg output_state; | |
43 | ||
44 | always @(posedge clk) | |
45 | begin | |
46 | is_high <= (adc_d >= high_threshold); | |
47 | is_low <= (adc_d <= low_threshold); | |
48 | is_zero <= ((adc_d > lowz_threshold) & (adc_d < highz_threshold)); | |
49 | end | |
50 | ||
51 | // all edges detection | |
52 | always @(posedge clk) | |
53 | if (enabled) begin | |
54 | // To enable detecting two consecutive peaks at the same level | |
55 | // (low or high) we check whether or not we went back near 0 in-between. | |
56 | // This extra check is necessary to prevent from noise artifacts | |
57 | // around the threshold values. | |
58 | if (trigger_enabled & (is_high | is_low)) begin | |
59 | output_edge <= ~output_edge; | |
60 | trigger_enabled <= 0; | |
61 | end else | |
62 | trigger_enabled <= trigger_enabled | is_zero; | |
63 | end | |
64 | ||
65 | // edge states | |
66 | always @(posedge clk) | |
67 | if (enabled) begin | |
68 | if (is_high) | |
69 | output_state <= 1'd1; | |
70 | else if (is_low) | |
71 | output_state <= 1'd0; | |
72 | end | |
73 | ||
74 | assign edge_state = output_state; | |
75 | assign edge_toggle = output_edge; | |
76 | ||
77 | endmodule |