Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unreliable locking on the receiver #8

Open
alesuiss opened this issue May 21, 2022 · 1 comment
Open

Unreliable locking on the receiver #8

alesuiss opened this issue May 21, 2022 · 1 comment

Comments

@alesuiss
Copy link

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():

@hansfbaier
Copy link
Collaborator

Hi Arthur,
thanks for looking into this and I don't think adding sanity checks would hurt.
To really understand the issue you might want to activate the internal logic analyzer and see what's going on
(although it looks to me as you already have done this).
Feel free to prepare a pull request with your changes.
Best regards,
Hans

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants