fpgadesign.io #5 - Pulses, CDC and Synchronizers
Two readers sent back complete designs for last issue's pulse question. π
Between them they covered both halves of it β so this issue is the answer, built out of those answers.
β‘ Concept of the Week: A synchronizer doesn't make a pulse survive
The question was: catch a single-cycle 200 MHz pulse in a 50 MHz domain, exactly once. No misses, no duplicates.
Almost everyone starts with a two-flop synchronizer. Reasonable. But look at the numbers first.
At 200 MHz, a one-cycle pulse is 5 ns wide. At 50 MHz, the destination looks once every 20 ns.
A 5 ns pulse fits inside a 20 ns gap with room to spare.
Nothing goes metastable. Nothing is marginal. There is just no destination clock edge while the signal is high, so the destination samples a 0, then another 0, and the event is gone. Five flip-flops on the receive side wouldn't help. The problem happened before the first one.
A synchronizer fixes metastability. It does nothing about sampling. π€
The fix is width. Hold a signal for at least 1.5 destination clock periods and you're guaranteed to be sampled β 30 ns here, six source cycles. Two structures do that for you. A toggle synchronizer turns the pulse into a level, crosses the level, and rebuilds the pulse on the far side: cheap, but open loop, so it can miss if your events bunch up. A req/ack handshake makes the source hold req until the destination confirms: it can't miss, and you pay for that in latency.
π― Interview Question of the Week
Q: "You put a two-flop synchronizer on a control signal crossing into a slower domain. It still drops events in hardware. What did you miss?"
How to approach it: don't say "add a third flop." That's the reflex answer, and here it's wrong.
Separate the two failure modes out loud. Metastability is the flop catching a transition. Sampling is the destination never looking while the signal was asserted. A synchronizer only addresses the first, and the question is about the second.
Then do the arithmetic in front of the interviewer and name the number: hold it for at least 1.5 destination clock periods. That number is what separates someone who has read about CDC from someone who has debugged it.
(This is Ch5 Β§5.10 in the book. Q.155 asks it almost word for word.)
π§© Design Question of the Week
This one is harder than usual. That's deliberate β readers keep saying the difficult ones are the good ones.
Design a 4-client round-robin arbiter for a shared bus.
Each client asserts req[i]. Once granted, a client holds the bus for a variable number of cycles and asserts last on its final cycle. One-hot grant[i], one grant per clock.
The requirements are where it gets interesting:
- No rotation mid-burst. Once a client is granted, it keeps the bus until
last. - Zero bubble cycles. When the current burst ends and another request is pending, the next client must be granted on the very next cycle. Not one cycle later.
- No starvation, ever. A client that keeps asking must eventually be granted, no matter what the other three do.
- A client that drops
reqbefore being granted must not cost anyone a cycle.
And the part most people skip: a fixed priority encoder that always starts at bit 0 will pass a casual testbench and quietly starve client 3 in the lab.
So there are two questions here, not one. How do you build it β and how would you convince a reviewer it can't starve?
Reply with your approach. Every email gets read, and every one gets an answer. π
π Author's Note
The CDC bugs that survive simulation and only surface in hardware nearly all come from the same place: treating "it's synchronized" as "it's safe." A synchronizer is a metastability filter, not a delivery guarantee. Before adding flops, ask the cheaper question first β is the signal even wide enough for the receiving clock to see it? Ten seconds of arithmetic, and it saves weeks of lab time.
π ICYMI on LinkedIn
β‘ Is arbitration even needed? Detecting whether more than one bit is set, without a population count. ~|x handles the empty case; x & (x-1) handles the rest. Directly relevant to this issue's design question.
π₯ This made my day. A reader wrote in about the book, unprompted, asking for nothing. Worth a read if you've ever wondered whether writing a technical book is worth the trouble. β [LINK]
π‘ On the Radar
π AMD moves Vivado to tiered licensing in 2026.1 β five tiers now: Basic (free, annual renewal), Core and Pro as subscriptions, Enterprise and Gold as perpetual. The part worth knowing is what landed in the free tier: all 7 Series plus low-end UltraScale and UltraScale+, on Windows and Linux. If you learn or prototype on your own hardware, the free tier just got more useful than it was.
π· Altera expands DDR5 support across the Agilex portfolio β Quartus Prime Pro 26.1.1 brings DDR5-6400 and LPDDR5-6400 to Agilex 7 M-Series and LPDDR5 to Agilex 3, up to 204.8 GB/s aggregate on the top configurations. Memory bandwidth is quietly becoming the number that decides FPGA-versus-GPU arguments at the edge, so this is a bigger deal than a tooling release usually is.
π One small ask
If you've read Demystifying the Digital Design Interview, please consider leaving a review on Amazon.
Reviews are what decide whether the book gets shown to the next engineer searching for interview prep. There's no publisher and no ad budget behind this β it moves on word of mouth and on what readers say about it. A few honest sentences about what you found useful genuinely keeps the whole effort going.
Until next time, Milind
π Get the book Β· π LinkedIn Β· βοΈ Email