3b2fee43 |
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. |
238c503c |
14 | // This algorithm therefore can't be used directly for realtime peak detections, |
3b2fee43 |
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 |