From 0185d81d46106ccbc9f54ae3b484155b90ca6bfd Mon Sep 17 00:00:00 2001 From: David Lenfesty Date: Sat, 27 May 2023 10:36:00 -0600 Subject: [PATCH] gw: minor tweaks to peak detector to improve behaviour --- gateware/sampler/peak_detector.py | 63 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/gateware/sampler/peak_detector.py b/gateware/sampler/peak_detector.py index ec556ac..72241f5 100644 --- a/gateware/sampler/peak_detector.py +++ b/gateware/sampler/peak_detector.py @@ -36,12 +36,12 @@ class PeakDetector(Module): """ def __init__(self, data_width: int): - # Create all state signals - min_val = Signal(data_width) - max_val = Signal(data_width) - diff = Signal(data_width) - triggered_time = Signal(32) - decay_counter = Signal(32) + # Create all state signals (underscored in self to be accessible in tests) + self._min_val = Signal(data_width) + self._max_val = Signal(data_width) + self._diff = Signal(data_width) + self._triggered_time = Signal(32) + self._decay_counter = Signal(32) # Control signals self.data = Signal(data_width) @@ -57,44 +57,47 @@ class PeakDetector(Module): self.sync += If(~self.enable, # Reset halfway. ADCs are 0-2V, and everything should be centered at 1V, so this is approximating the initial value - min_val.eq(int(2**data_width /2)), - max_val.eq(int(2**data_width /2)), + self._min_val.eq(int(2**data_width /2)), + self._max_val.eq(int(2**data_width /2)), self.triggered.eq(0), - decay_counter.eq(0), - triggered_time.eq(0), + self._decay_counter.eq(0), + self._triggered_time.eq(0), ) - # Constantly updating diff to simplify some statements - self.comb += diff.eq(max_val - min_val) + # Constantly updating self._diff to simplify some statements + self.comb += self._diff.eq(self._max_val - self._min_val) self.sync += If(self.enable & self.data_valid, + # Decay should run irrespective of if we have triggered, + # and before everything else so it can be overwritten + self._decay_counter.eq(self._decay_counter + 1), + # Decay threshold has been reached, apply decay to peaks + If(self._decay_counter >= self.decay_period, + self._decay_counter.eq(0), + + # Only apply decay if the values would not overlap, and we use the decay + If((self._diff >= (self.decay_value << 1)) & (self.decay_value > 0), + self._max_val.eq(self._max_val - self.decay_value), + self._min_val.eq(self._min_val + self.decay_value))), + + # Update maximum value - If(self.data > max_val, max_val.eq(self.data)), + If(self.data > self._max_val, self._max_val.eq(self.data)), # Update minimum value - If(self.data < min_val, min_val.eq(self.data)), - If(diff > self.thresh_value, + If(self.data < self._min_val, self._min_val.eq(self.data)), + If(self._diff > self.thresh_value, # We have met the threshold for triggering, start counting - triggered_time.eq(triggered_time + 1), - decay_counter.eq(0), + self._triggered_time.eq(self._triggered_time + 1), # We have triggered, so we can set the output. After this point, # nothing we do matters until enable is de-asserted and we reset # triggered. - If(triggered_time + 1 >= self.thresh_time, self.triggered.eq(1))) + If(self._triggered_time + 1 >= self.thresh_time, self.triggered.eq(1))) .Else( - # We have not met the threshold, reset timer and handle decay - triggered_time.eq(0), - decay_counter.eq(decay_counter + 1), + # We have not met the threshold, reset timer + self._triggered_time.eq(0), + ), - # Decay threshold has been reached, apply decay to peaks - If(decay_counter >= self.decay_period, - decay_counter.eq(0), - - # Only apply decay if the values would not overlap, and we use the decay - If((diff >= (self.decay_value << 1)) & (self.decay_value > 0), - max_val.eq(max_val - self.decay_value), - min_val.eq(min_val + self.decay_value))) - ) )