]>
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 | // track min and max peak values (envelope follower) | |
9 | // | |
10 | // NB: the min value (resp. max value) is updated only when the next high peak | |
11 | // (resp. low peak) is reached/detected, since you can't know it isn't a | |
12 | // local minima (resp. maxima) until then. | |
13 | // This also means the peaks are detected with an unpredictable delay. | |
14 | // This algorithm therefore can't be used directly for realtime peak detections, | |
15 | // but it can be used as a simple envelope follower. | |
16 | module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, | |
17 | output [7:0] min, output [7:0] max); | |
18 | ||
19 | reg [7:0] min_val = 255; | |
20 | reg [7:0] max_val = 0; | |
21 | reg [7:0] cur_min_val = 255; | |
22 | reg [7:0] cur_max_val = 0; | |
23 | reg [1:0] state = 0; | |
24 | ||
25 | always @(posedge clk) | |
26 | begin | |
27 | case (state) | |
28 | 0: | |
29 | begin | |
30 | if (cur_max_val >= ({1'b0, adc_d} + threshold)) | |
31 | state <= 2; | |
32 | else if (adc_d >= ({1'b0, cur_min_val} + threshold)) | |
33 | state <= 1; | |
34 | if (cur_max_val <= adc_d) | |
35 | cur_max_val <= adc_d; | |
36 | else if (adc_d <= cur_min_val) | |
37 | cur_min_val <= adc_d; | |
38 | end | |
39 | 1: | |
40 | begin | |
41 | if (cur_max_val <= adc_d) | |
42 | cur_max_val <= adc_d; | |
43 | else if (({1'b0, adc_d} + threshold) <= cur_max_val) begin | |
44 | state <= 2; | |
45 | cur_min_val <= adc_d; | |
46 | max_val <= cur_max_val; | |
47 | end | |
48 | end | |
49 | 2: | |
50 | begin | |
51 | if (adc_d <= cur_min_val) | |
52 | cur_min_val <= adc_d; | |
53 | else if (adc_d >= ({1'b0, cur_min_val} + threshold)) begin | |
54 | state <= 1; | |
55 | cur_max_val <= adc_d; | |
56 | min_val <= cur_min_val; | |
57 | end | |
58 | end | |
59 | endcase | |
60 | end | |
61 | ||
62 | assign min = min_val; | |
63 | assign max = max_val; | |
64 | ||
65 | endmodule |