有很多剛出社會的工程師,被指派FIFO設計工作時,心裏面一定都會想,這個這麼簡單,有沒有更難的,我可不是來這邊做這種簡單的設計。我是來學更難的東西。
其實,一個基本功好的工程師,他的FIFO design也一定是很紮實。FIFO常被用來解決很多的問題,所以FIFO的設計也牽扯到很多的問題,例如:跨clock domain的處理?serial轉parallel問題?兩邊不同的Spec要怎麼溝通?兩個存取速度不同時,要怎麼溝通?這些問題看似不同,但是其實都是同一種的本質—FIFO兩邊的步調不同。既然核心問題只有一個,那解法不就是一種就可以了?那為什麼網路上FIFO的架構有那麼多?(當然,條條道路通羅馬。我不是表達這麼多種做法不對,而是所有的做法,其本質是只有一種。了解一種做法應該就夠了,其他的都是相似的道理。)
各位看官你可以細細看,這麼多不同架構的FIFO,大都是在探討一個問題,那就是訊號在跨clock domain的處理。如果你對跨clock domain訊號處理的觀念正確了,且了解你要解決的問題是什麼,也知道自己所處理的訊號是屬於哪一種的訊號(long-pulse signal or one-pulse signal)?是連續還是不連續的處理?這些如果你都有清楚知道的話,那麼我相信,你所設計出來的FIFO,相信一定可以解決你的需求。
從宏觀的角度來說,FIFO就好像是水管,而data就像是流水一樣。FIFO design像是設計水管的接法,直到出水口的速度和流量符合你想要的結果。設計水管時,我們所會遇到的問題是什麼?
1. 當水流又強又快時,你想放慢它,你會怎麼做?
2. 當水流又慢又多時,你想加快它,你會怎麼做?
第一題的做法應該是找更粗的水管慢慢地加大,直到你想要的流速及流量。第二題的做法應該是和第一題相反的做法。
FIFO的基本解法,也不外乎是這些做法。剩下來的就是實作經驗以及跨clock domain處理的觀念建立。
那麼FIFO可以用來解決哪些問題呢 ?
FIFO可以用來解決兩邊不同interface不相容的問題。FIFO可以用來解決系統中write/read順序的問題(PCI ordering)。FIFO可以用來解決producer&consumer的write/read racing問題。FIFO可以用來做排程(scheduling)的處理。FIFO可以用來serial轉parallel,當然也可以parallel轉serial。FIFO可以用來解決的問題這麼多。這樣子,你還會認為FIFO是簡單的設計嗎?
之前討論過,FIFO核心問題只有一個,當你了解到FIFO本質時,你就會知道怎麼做FIFO。很多人不了解跨clock domain和FIFO之間的本質,所以才會有很多種不同的想法、做法,甚至想要用reset來解決同步的問題。
其實認真處理跨clock domain訊號,認真設計一個實用的FIFO,將兩個合在一起,你就可以用這個架構一輩子。