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

Serial core in separate clock domain should have its async FIFOs reset in system clock domain #779

Closed
cr1901 opened this issue Jan 22, 2021 · 3 comments
Labels

Comments

@cr1901
Copy link
Contributor

cr1901 commented Jan 22, 2021

Not sure the best way to proceed here is. Duplicating description of problem from IRC for convenience:

(2:13:10 AM) cr1901_modern: florent: I figured out the problem I was seeing. It's relevant to orangecrab but may exist on other boards.
(2:14:53 AM) cr1901_modern: Basically, the USB clock domain on orangecrab wasn't being reset properly. This means the CDC gray code multiregs between USB and sys would not be updated with valid reset values, and the comparison to detect an empty receive queue from USB would be garbage
(2:16:00 AM) cr1901_modern: The CPU would always see a high level after reset from the RX interrupt. Since it's edge-triggered, the event never triggered, so the RX queue was never serviced
(2:17:31 AM) cr1901_modern: eventually, the RX queue fills up, and the USB core dies waiting for the RX queue to drain. Then when you send data from the CPU side, the TX queue fills up b/c the USB core refuses to drain it
(2:18:05 AM) cr1901_modern: Eventually, the BIOS dies in an infinite loop waiting for the TX queue to drain in a vicious cycle.

Clarifications

  • I misspoke slightly:
    The CPU sees a low level on the RX interrupt line after reset. This is because the RX interrupt line goes low when the RX FIFO is readable. The FIFO is considered readable if the gray counters in both clock domains don't match. And they will (most likely) not match if only one domain is reset but not the other.

    Since the RX interrupt is edge triggered (high-to-low), and the RX interrupt line goes low while the system clock domain is in reset, the interrupt is lost.

  • A software solution to this is possible; @enjoy-digital wants a gateware solution (fair enough! :D).

Potential Solution

Given two clock domains with clock signals X and Y, each with (synchronized!) reset signals A and B respectively, introduce a third clock domain "C" whose clock signal is "Y", but whose (synchronized via AsyncResetSynchronizer) reset signal is "A". The AsyncFIFO's produce domain for the RX FIFO uses clock domain "C", so that system reset also resets the gray counters.

@enjoy-digital
Copy link
Owner

Thanks for reporting and investigating on this. Would you mind testing with 01a2fc1 and litex-hub/litex-boards@23760e2?

@cr1901
Copy link
Contributor Author

cr1901 commented Jan 22, 2021

@enjoy-digital These two commits fix the issue I was seeing.

@enjoy-digital
Copy link
Owner

Thanks for the test/feedback @cr1901.

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

No branches or pull requests

2 participants