Knowledge gaps
I have been working with FPGAs for just about 10 years now. And I just realized that I have never done a CDC FIFO. Well... Maybe back in uni as some paper exercise.
It's such a weird gap too. Since it's like the first answer anyone gives whenever you want to transfer a lot of data across clock domains. But I just haven't needed a hardware FIFO for that yet.
So I spent the afternoon implementing one from scratch and shoving every edge case I could think of at it. Just as a learning exercise.
Have you found any weird gaps in your own knowledge?
14
u/DominantlyWeak 15h ago
That's interesting because it's something I find/found myself doing often, what industry are you in?
3
u/chgentso 12h ago
Wait, so you really write async FIFOs from scratch often? Are you just using them often, perhaps, and I misunderstood?
3
u/Allan-H 11h ago
I always write my async FIFOs from scratch. It keeps my skills sharp, in a way that wouldn't happen if I used a FIFO from a library or used an agentic AI to write one for me. It also allows me to use new features that can't be found in any library FIFO, such as one described in this thread.
5
u/timonix 15h ago
Defense. Signal processing. That sorta thing.
16
u/SecondToLastEpoch 15h ago
And you don't use CDC fifos often? I used them all the time in that space.
4
u/hukt0nf0n1x 11h ago
A lot of my friends who work signal processing try really hard to keep everything in one clock domain. Now that I think of it, even my multi-clock designs were primarily on one clock.
3
u/timonix 15h ago
I use Fifos within a clock domain pretty often. They are a very useful construct.
But I have never used one as for CDC. It has always been double/triple buffered memory instead. Which works very well.
2
u/IllustriousFault6218 14h ago
What is a double buffered memory and how do you use it for cdc?
7
u/timonix 14h ago
Easiest implementation I can think of right of the bat
Dual port Bram. It natively supports different clock speeds on its ports. For example
The writer writes to adress 0x000 to 0x0FF
While the reader reads from 0x100 to 0x1FF
So they read and write from different places. When they are done, they swap.
You still need some way to get the "ok you are good to go" across. For example an interrupt, or some other register space. There are many ways to skin a cat so to say
13
1
u/SecondToLastEpoch 11h ago edited 11h ago
What is the advantage of this over using a fifo? This sounds like a FIFO with extra steps. Why deal with addressing manually over a simpler FIFO interface?
4
u/electro_mullet Altera User 9h ago edited 9h ago
They're handy for reordering data. A simple contrived example would be reversing an array, or something like doing a mirror flip on a row of pixels in a video stream. Write in backwards starting from address 0xFF down to 0x00. Read out normally from address 0x00 up to 0xFF.
I can't say I've personally seen them used for CDC so much as data processing on a single domain, but they are ultimately both just ways to address a shared memory from two different RAM ports. Whether they're on different clock domains just adds a layer of synchronization.
3
4
u/Mateorabi 13h ago
Now read the Sunburst white paper to find out what you missed.
Note a simulation is unlikely to find cdc errors due to “perfect” capture on edges etc and meta stability not being modeled. The idea that one wire can have different values at different FF inputs isn’t something sim tracks.
5
1
u/_MyUserName_WasTaken 6h ago
My friends working in ASIC are always using CDC in their designs. In my 5 YoE, I never worked on a multiple clock domains design. Maybe on a block design level between different IPs and I usually use Xilinx Async FIFO IP. But never in RTL. I work I DSP.
1
u/_solitarybraincell_ 3h ago
Hijacking this thread (sorry lol) as a very amateur ASIC frontend designer. What are some essential white papers/material to read? I know some of the sunburst papers, but that's about it.
1
15
u/OnYaBikeMike 13h ago edited 12h ago
I've been doing this long enough that I now realize all my knowledge has gaps.
Today it was how best to use the DSP preadder and cascade features in a relatively slowly clocked design.
Last week it was how to implement and validate filters that give fractional delays
Last week before it was learning that UltraScale Block RAM has optional output registers, so can have latency 0. I was really confused when looking at resource utilization for a design, how was this possible?
Before that it was looking at jitter when using an MMCM or PLL to drive the clock for a high speed ADC.
It keeps you humble, I guess...