Skip to content

Unreliable locking on the receiver #8

Description

@alesuiss

Hello,

Disclaimer: I'm a relative newbie to FPGAs, so it's very possible that there might be something wrong with my design. Sorry for my confused ignorance :-)

I'm having an issue where the receiver sometimes locks "wrong", with the decoder sticking in DECODE state but producing bad data & clock signals. Unplugging and replugging the fiber (or doing the same electronically) generally fixes it.

I noticed that when this happens, the bit_time value is incoherent (with random values in the many dozens where it seems to be 7 @ 100MHz whenever it works correctly). So I came up with the following patch, simply checking whether the bit_time has a sane value before switching to the DECODE state; it seems to make locking reliable for me, but I'm guessing that it might be a "wrong" solution and not addressing the root cause.

Cheers,
Arthur

diff --git a/adat/nrzidecoder.py b/adat/nrzidecoder.py
index 88ba3ec..5c51e7c 100644
--- a/adat/nrzidecoder.py
+++ b/adat/nrzidecoder.py
@@ -72,6 +72,8 @@ class NRZIDecoder(Elaboratable):
         """Waits for the ten zero bits of the SYNC section to determine the length of an ADAT bit"""
         sync = m.d.sync
         bit_time_44100 = math.ceil(110 * (self.clk_freq/self.adat_freq(44100) / 100))
+        bit_time_48000 = math.floor(90 * (self.clk_freq/self.adat_freq(48000) / 100))
+        bit_time = sync_counter.divided_counter_out
 
         # as long as the input does not change, count up
         # else reset
@@ -85,7 +87,7 @@ class NRZIDecoder(Elaboratable):
             # and got an edge, then we reset the counter on each edge
             with m.Else():
                 # when the counter is bigger than 3/4 of the old max, then we have a sync frame
-                with m.If(sync_counter.counter_out > 7 * bit_time_44100):
+                with m.If((sync_counter.counter_out > 7 * bit_time_44100) & (bit_time >= bit_time_48000) & (bit_time <= bit_time_44100)):
                     sync += sync_counter.active_in.eq(0) # stop counting, we found it
                     m.next = "DECODE"
                 with m.Else():

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions