異步dcfifo的讀寫


異步dcfifo的原理

    Dcfifo即是Double clk fifo,意思是雙時鍾的fifo。或許你現在還不知道什么是fifo,那我就先從fifo(就是同步fifo,不過同步fifo在實際運用中比較少)開始說起吧!

scfifo的原理

一般的fifo是單時鍾(讀寫同步),就是讀寫用同一個時鍾信號,其框圖如下:

端口說明如下:

    官方的DCFIFO資料中有這樣一個時序圖,如下

    上圖是寫操作,下圖是讀操作,通過圖可以看到讀寫的時鍾頻率是不一樣,不過這一點沒有關系,這里把讀寫的時鍾假設為相同,就是同步fifo

    寫操作中,wrreq信號為寫申請信號,在寫時鍾的上升沿有效,將wrreq置高后就可以往fifo送數據,在寫滿fifo后並在時鍾的上升沿,wrfull寫滿信號有效,表明fifo已經寫滿了,不能再往fifo內部寫如數據,否則就會數據丟失,寫了也是白費。如果要對fifo重新寫入數據,這時可以通過fifo的異步清零aclr進行操作,aclr為高電平有效,能立刻將fifo內部的數據全部清零,這樣就可以再往fifo寫數據。

    讀操作中,rdreq信號為讀申請信號,在讀時鍾的上升沿有效,將rdreq置高后就可以從fifo讀數據,在讀空fifo后並在時鍾的上升沿,rdempty讀空信號有效,表明fifo已經讀空了,不能再從fifo內部讀如數據。

    當然,fifo中還有一些可以選擇調用的信號,可以根據需要進行調用,這里就不作介紹了。

dcfifo的原理

端口說明如下:

    相信在了解了scfifo之后,已經知道fifo的原理了,dcfifoscfifo的區別就在與讀寫時鍾是否同步。

    

    上圖的分析上面已經講解過了,不同的是,在dcfifo中讀寫時鍾是不一致的,這也是很關鍵的一點,也是dcfifo運用比較多的一點。

    FPGA設計中經常性地會強調"同步"的問題,假設在A模塊中采用的時鍾頻率是100M,在B模塊中采用的時鍾頻率是50M,如果AB要進行數據交換,由於兩者的時鍾不一樣,所以就存在一個同步性的問題,一保證兩者數據交換不會出現錯誤。要解決這個問題,就是解決跨時域操作的問題,跨時域交換數據最常用的就是采用dcfifo做為中間橋梁。假設為A模塊往B模塊送數據,則A模塊以100M的時鍾作為dcfifowrclk,往fifo寫數據,而B模塊則以50M的時鍾頻率作為dcfifordclk,從fifo讀數據,這就解決了跨時域交換數據的問題,當然這里面還有一些細節問題,不過相信你已經知道dcfifo的最大用處了。

異步dcfifo的調用過程

點擊tools,選擇調用宏功能模塊的菜單,彈出下面的菜單;

選擇新建一個新的宏功能模塊,點擊next,彈出下面的菜單;

memory complier中選擇FIFO,然后設置輸出文件的名稱也是這個宏功能模塊的名稱,然后彈出FIFO的設置向導窗口;

設置fifo的位寬、深度、同步和異步的選擇,這里選擇如上圖所示,選擇后點擊next

fifo的潛伏期設置,這里選擇最低的潛伏期,點擊next

選擇fifo的接口信號,這里選擇寫端口的usedw、異步清零信號aclr,點擊next

選擇fifo的模式,這里選擇正常模式,存儲資源的類型選擇M4K,點擊next

點擊Finish,調用fifo完成,接下來就是設計模塊,將這個dcfifo調用起來;

 

讀寫dcfifo的控制模塊設計

模塊框圖

    該設計主要分為4個模塊和PLL倍頻模塊(提供100M的工作時鍾),其中,fifo_ctrl為控制模塊,負責控制對dcfifoasy_fifo)進行讀寫操作,與write_fiforead_fifo采用反饋的方式進行控制,具體方法為先控制write_fifoasy_fifo進行寫操作,write_fifo寫如完成后,向fifo_ctrl反饋一個寫入完成信號,fifo_ctrl便關閉對fifo的寫操作,向read_fifo發送讀使能的信號,read_fifo便在控制信號的控制下對fifo進行讀操作,將讀出的數據顯示在LED上,讀完成后便發送讀完成信號給fifo_ctrlfifo_ctrl在判斷讀操作完成后便重新對fifo進行寫操作,以此循環。

    其中,對asy_fifo的寫時鍾為100M(由PLL提供),讀asy_fifo的時鍾為50M(由外部晶振提供)。

各模塊設計原理

    這里采用至上而下的方法對整個工程進行設計:

頂層模塊

頂層設計如下

    

fifo控制模塊

    fifo的控制模塊根據讀寫的反饋信號,進行控制狀態的跳轉,同時輸出控制信號。

    上電后,控制狀態為空閑態,接着轉入到寫狀態,同時將現態的信號作為控制信號輸出到write_fiforead_fifo,在輸出寫控制信號后便對從write_fifo反饋的寫入數量的信號進行判斷,當寫入了256個數據之后,便轉到讀狀態,同時將讀控制信號發送到read_fifo模塊,read_fifo模塊接收到讀信號之后便進行讀操作,讀完成后便反饋讀完成信號read_over,當read_over有效后,控制模塊的控制狀態便轉到空閑態,以此循環。

fifo寫模塊

    fifo寫模塊負責對fifo進行寫操作,實際點就是發送寫申請信號和發送數據,關鍵是什么時候進行寫申請和什么時候發送什么數據,這就要聽從fifo_ctrlctrl_signal信號,即是對ctrl_signal進行譯碼操作,配合着輸出對fifo的寫信號wrreq

    

    將輸入的100Mclk直接輸入到fifo的讀時鍾,將wrusedwfifo的當前存儲數量)輸出到wrdata_num反饋給fifo_ctrl

    ctrl_signalWRITE時,寫申請信號wrreq_reg有效,同時用wrdata_cnt對寫入的數據數進行計數,當wrdata_cnt等於255時,fifo_ctrl將控制信號轉為讀狀態,這時ctrl_signalREADwrreq_reg被清零,寫操作停止,進入讀操作階段。

fifo讀模塊

fifo讀模塊負責對fifo進行讀操作,實際點就是發送讀申請信號和讀取數據,關鍵是什么時候進行讀申請和什么時候接收什么數據,這就要聽從fifo_ctrlctrl_signal信號,即是對ctrl_signal進行譯碼操作,配合着輸出對fifo的讀申請信號rdreq

 

    讀申請信號產生模塊,這個模塊根據ctrl_signal信號對fifo進行讀申請,在READ狀態時讀申請信號rdreq_reg有效,其他狀態無效。

讀完成信號產生模塊,在ctrl_signalREAD時開始計數,判斷讀取的次數是否達到256次,當達到256次時read_over輸出高電平,同時read_over反饋到fifo_ctrl模塊,這是current_state跳轉到IDLE狀態,然后進行新一輪的寫讀操作。

實驗效果

    實驗的工程文件為"asy_fifo",其源代碼文件如下:

    為了驗證實驗結果,實驗中調用signaltap將從fifo中讀取的數據調出來進行觀察,

結果如下:

 

大西瓜FPGA-->https://daxiguafpga.taobao.com

 

博客資料、代碼、圖片、文字等屬大西瓜FPGA所有,切勿用於商業! 若引用資料、代碼、圖片、文字等等請注明出處,謝謝!

 

每日推送不同科技解讀,原創深耕解讀當下科技,敬請關注微信公眾號“科乎”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM