2017-08-07 169 views
1

我正試圖將模塊與由Xilinx CORE Generator生成的異步FIFO進行接口。但是,我觀察到AFIFO輸入端口提供的數據(雖然正確)在6-7個時鐘週期的延遲之後開始出現在dout上。這是預期的嗎?或者我做錯了什麼?我所做的是斷言AFIFO的write_enable引腳,提供輸入數據,然後在下一個週期斷言read_enable引腳。但仍存在延遲問題。任何幫助表示讚賞。在異步FIFO中寫入延遲後讀取?

編輯:我附上我的代碼的一部分。

always @ (posedge clk1, posedge rst)//faster clock domain 
begin 
    if (rst) 
     wr_en<= 1'b 0; 

    else 
     begin 
      if (data_wrt) 
       begin 
       wr_en<= 1'b 1;       
       end 
      else 
       wr_en<= 1'b 0; 
     end 
end 
always @ (negedge clk2, posedge rst)//slower clock domain 
    begin 
     if (rst) 
      rd_en<= 1'b 0; 

     else 
      begin 
       if (wr_en) 
        begin 
        rd_en<= 1'b 1;        
        end 
       else 
        rd_en<= 1'b 0;    
      end 

    end 
AFIFO AFIFO1(//AFIFO module instantiation 
    .din(data_in), 
    .rd_clk(clk2), 
    .rd_en(rd_en), 
    .rst(reset), 
    .wr_clk(clk1), 
    .wr_en(wr_en), 
    .dout(data_out), 
    .empty(empty), 
    .full(full) 
    ); 

AFIFO Input Output

AFIFO2

+1

任何代碼片段? – Serge

+0

如果你的'clk2'比'clk1'慢,你的'rd_en'觸發器可能會丟失一些使能信號(在'if(wr_en)'塊中)。 –

+0

那我該怎麼辦? – Candy

回答

2

什麼是時鐘的關係?假設您看到6-7 clk1(快速時鐘)週期中的延遲,這看起來像您期望的一樣,具體取決於時鐘關係clk1/clk2。

也就是說,異步FIFO的要點通常是充當從一個時鐘域到另一個時鐘域的同步器。只要未滿,寫時鐘域(clk1)就會將數據寫入AFIFO。只要AFIFO不爲空,讀時鐘域(clk2)就會讀取新數據。你在這裏做的是打破這種用法。

您正在使用由clk1生成的wr_en來控制由clk2提供時鐘的rd_en。所以現在在兩個時鐘域中都使用wr_en,並且會導致metastability

因此,總之,您沒有正確使用AFIFO。嘗試改爲在AFIFO爲!empty時,始終將clk2邏輯設置爲rd_en

+0

我已經用AFIFO上傳了我的模擬屏幕截圖。 – Candy

+0

在這張圖片中,有一些東西看起來有點奇怪。首先我會說,你看到的延遲比我想象的要大得多。六個慢時鐘週期似乎過多。這可能是在FIFO發生器中可控的。其次,'empty'和'data_out'似乎不與clk2同步,而是延遲了1/4週期。然而,這可能是模擬延遲,也是FIFO發生器的一部分。 最後,當它不應該被啓用時,你仍然啓用'rd_en'。只要'empty'很高,'rd_en'不應該高。 – Hida

+0

我也上傳了第二張截圖,當AFIFO爲空時,rd_en被激活。現在我在data_out上出錯了第一個值!在模擬時出現以下警告:錯誤:C:/Xilinx/verilog/src/simprims/X_RAMB16_S36_S36.v(2655):$ setup(posedge DIA [1] && dia_enable:127784 ps,posedge CLKA:127972 ps,484 ps); #時間:127972 ps迭代次數:3實例:/tb/uut/\AFIFO1/BU2/U0/grf.rf/mem/gbm.gbmg.gbmga.ngecc.bmg/blk_mem_generator/valid.cstr/ramloop[0]。 ram.r/v2_noinit.ram/dp36x36.ram \ – Candy

2

我想你想通過異步FIFO將一些數據同步到clk1以同步到clk2。首先,你不需要通過clk2直接採樣與clk1同步的信號。就像使用clk1產生的wr_en來控制由clk2計時的rd_en一樣,它會引起亞穩態.FIFO總是用來求解亞穩態問題。所以不需要做第二個總是阻塞的問題。

所以問題是如何正確使用異步FIFO。 您應該閱讀Xilinx FIFO生成器產品指南(如PG057)。您應該瞭解FIFO的理論和使用方法。否則使用FIFO時您會感到非常痛苦。

我的建議如下。 對於寫入操作,您需要使用almost_full和full信號來避免溢出。您可以在PG057中看到它(圖3-2)。您需要使用almost_full,因爲如果wr_en連續,則完整信號比aviod溢出慢1個時鐘。 對於讀取操作,您需要同時使用almost_empty和空信號。 然後,您可以正確轉換時鐘區域。

原諒我的英語。