From 1d603c73b7ada6d5846047f7873dce95b07286ee Mon Sep 17 00:00:00 2001 From: morgan Date: Fri, 26 Apr 2024 13:07:02 +0800 Subject: [PATCH] DDMTD: replace 1st edge to median edge deglitcher --- src/gateware/ddmtd.py | 60 +++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/gateware/ddmtd.py b/src/gateware/ddmtd.py index 2b8ed535..2d038081 100644 --- a/src/gateware/ddmtd.py +++ b/src/gateware/ddmtd.py @@ -51,26 +51,52 @@ class DDMTDSampler(Module): ] -class DDMTDDeglitcherFirstEdge(Module): - def __init__(self, input_signal, blind_period=400): +class DDMTDDeglitcherMedianEdge(Module): + def __init__(self, counter, input_signal, stable_0_period=100, stable_1_period=100): + self.tag = Signal(len(counter)) self.detect = Signal() - rising = Signal() - input_signal_r = Signal() + + stable_0_counter = Signal(reset=stable_0_period - 1, max=stable_0_period) + stable_1_counter = Signal(reset=stable_1_period - 1, max=stable_1_period) # # # - self.sync.helper += [ - input_signal_r.eq(input_signal), - rising.eq(input_signal & ~input_signal_r) - ] - - blind_counter = Signal(max=blind_period) - self.sync.helper += [ - If(blind_counter != 0, blind_counter.eq(blind_counter - 1)), - If(input_signal_r, blind_counter.eq(blind_period - 1)), - self.detect.eq(rising & (blind_counter == 0)) - ] + # Based on CERN's median edge deglitcher FSM + # https://white-rabbit.web.cern.ch/documents/Precise_time_and_frequency_transfer_in_a_White_Rabbit_network.pdf (p.72) + fsm = ClockDomainsRenamer("helper")(FSM(reset_state="WAIT_STABLE_0")) + self.submodules += fsm + fsm.act("WAIT_STABLE_0", + If(stable_0_counter != 0, + NextValue(stable_0_counter, stable_0_counter - 1) + ).Else( + NextValue(stable_0_counter, stable_0_period - 1), + NextState("WAIT_EDGE") + ), + If(input_signal, + NextValue(stable_0_counter, stable_0_period - 1) + ), + ) + fsm.act("WAIT_EDGE", + If(input_signal, + NextValue(self.tag, counter), + NextState("GOT_EDGE") + ) + ) + fsm.act("GOT_EDGE", + If(stable_1_counter != 0, + NextValue(stable_1_counter, stable_1_counter - 1) + ).Else( + NextValue(stable_1_counter, stable_1_period - 1), + self.detect.eq(1), + NextState("WAIT_STABLE_0") + ), + If(~input_signal, + NextValue(self.tag, self.tag + 1), + NextValue(stable_1_counter, stable_1_period - 1) + ), + ) + class DDMTD(Module): def __init__(self, counter, input_signal): @@ -81,13 +107,13 @@ class DDMTD(Module): # # # - deglitcher = DDMTDDeglitcherFirstEdge(input_signal) + deglitcher = DDMTDDeglitcherMedianEdge(counter, input_signal) self.submodules += deglitcher self.sync.helper += [ self.h_tag_update.eq(0), If(deglitcher.detect, self.h_tag_update.eq(1), - self.h_tag.eq(counter) + self.h_tag.eq(deglitcher.tag) ) ] \ No newline at end of file