以前很少用到仿真,這次在仿真的過程中,遇到了某個警告,于是轉過頭又去研究了FIFO中的Safety Circuit的作用。
FIFO在FPGA中用的很多,常用于做少量數據的緩存和同步數據時鐘域, 本文將介紹Memory Collision Error on RAMB36E1錯誤及相應的解決方案,其中涉及到Vivodo FIFO IP核的Safety Circuit設置。
事情是這樣的,在某個設計中,我需要用異步FIFO同步數據的時鐘域,在這個工程中,讀寫會持續進行,雖然讀時鐘速率是寫時鐘速率的N倍,但是讀使能N個讀時鐘周期才會拉高一次,所以兩邊速率可以說是一致;在寫入一半的數據后,讀過程也開始了,兩邊一讀一寫,FIFO內部的數據量不增不減。
在仿真的過程中,我遇到了下圖的仿真警告提示。
之所以說不是錯誤而是警告,是因為這個提示并沒有影響最終的結果。仿真依舊在運行,直到結束。
隨后搜集了一番資料,在參考資料1(AR34859)中,解決方案是對FIFO內部的Block RAM,在雙端口模式下,使用WRITE_FIRST或NO_CHANGE模式;
在資料2(Xilinx Memeory Resource pdf)的17頁,介紹了Block RAM寫模式,幾種模式中,區別主要在
- WRITE_FIRST: 寫入的數據會馬上出現在數據輸出端口
- READ_FIRST: 寫入數據的同時,數據輸出端口的數據還是該地址保存的前一個數據
- NO_CHANGE: 在寫入數據的時候,數據輸出端口的數據會一直保持前一次讀出的數據不變。
最后,官方給出了避免Conflict的建議。雖然,FIFO內部確實使用了Block RAM,但Xilinx對其加密了,無法看到內部的實現細節;官方應該不至于在FIFO Block RAM的設置上有這種錯誤,感覺問題并不是出現在這。
把FIFO單獨拿出來做仿真測試時,卻怎么也無法復原這個BUG。于是找到參考資料3(FIFO IP核手冊),在Reset相關章節發現了一點玄機。
FIFO Asynchronous Reset Timing Without Safety Circuit
在異步FIFO里,只能選擇異步復位,而FIFO內部會把輸入的異步復位信號同步到各自的時鐘域;根據上圖,復位信號拉低后,還是有一段時間不能對FIFO有讀寫操作,那么怎么知道是哪段時間呢。IP核的設置里面,可以設置在復位狀態下,FULL的輸出狀態,設置為1,這樣就可以根據FULL防止寫入,復位后EMPTY為1,也可以防止讀取。
而在我對FIFO的操作中,我好心的把異步復位信號同步到RD時鐘域下,然后輸入到FIFO的RST端口,但是卻沒有注意到這個地方。
我取消了異步復位信號的同步,直接輸入到FIFO的RST,復位與寫使能之間的時間隔得足夠長,警告果然消失了。
這里,再介紹另一種方法,選中上圖的Enable Safety Circuit,在Safety Circuit啟用下,時序圖又變成這樣:
FIFO Asynchronous Reset Timing With Safety Circuit
在復位后,需要等待WR_RST_BUSY從1到0后,才能進行其他的操作(包括復位和寫);同理,讀取數據也需要等待RD_RST_BUSY從1到0。
此外,Enable Safety Circuit會同步FIFO內部的BRAM輸入信號和輸出信號,具體可以看看參考資料4(AR42571);文檔也提到了,復位信號最好保持MAX(3, C_SYNCHRONIZER_STAGE)個慢時鐘周期,兩次復位中間要間隔6個慢時鐘周期。
-
FPGA設計
+關注
關注
9文章
428瀏覽量
26489 -
RAM
+關注
關注
8文章
1367瀏覽量
114541 -
FIFO存儲
+關注
關注
0文章
103瀏覽量
5965 -
RST
+關注
關注
0文章
31瀏覽量
7382 -
BRAM
+關注
關注
0文章
41瀏覽量
10942
發布評論請先 登錄
相關推薦
評論