異步fifo的設計(FPGA)

2021-01-11 電子產品世界

本文首先對異步 FIFO 設計的重點難點進行分析,最後給出詳細代碼。

本文引用地址:http://www.eepw.com.cn/article/201807/383738.htm

一、FIFO簡單講解

FIFO的本質是RAM, 先進先出

重要參數:fifo深度(簡單來說就是需要存多少個數據)

fifo位寬(每個數據的位寬)

FIFO有同步和異步兩種,同步即讀寫時鐘相同,異步即讀寫時鐘不相同

同步FIFO用的少,可以作為數據緩存

異步FIFO可以解決跨時鐘域的問題,在應用時需根據實際情況考慮好fifo深度即可

本次要設計一個異步FIFO,深度為8,位寬也是8.

代碼是學習Simulation and Synthesis Techniques for Asynchronous FIFO Design Clifford E. Cummings, Sunburst Design, Inc.這篇文章的,百度搜搜很容易找到,雖然是英文的但是寫的確實值得研究。

下面我會對設計的要點進行分析,也是對自己學習過程的一個總結,希望能和大家交流共同進步。

二、設計要點解析

1、讀空信號如何產生?寫滿信號如何產生?

讀空信號:復位的時候,讀指針和寫指針相等,讀空信號有效(這裡所說的指針其實就是讀地址、寫地址)

當讀指針趕上寫指針的時候,寫指針等於讀指針意味著最後一個數據被讀完,此時讀空信號有效

寫滿信號:當寫指針比讀指針多一圈時,寫指針等於讀指針意味著寫滿了,此時寫滿信號有效

我們會發現 讀空的條件是寫指針等於讀指針,寫滿的條件也是寫指針等於讀指針,到底如何區分呢?

解決方法:將指針的位寬多定義一位

舉個例子說明:假設要設計深度為 8 的異步FIFO,此時定義讀寫指針只需要 3 位(2^3=8)就夠用了,

但是我們在設計時將指針的位寬設計成 4 位,最高位的作用就是區分是讀空還是寫滿,具體理論 1 如下

當最高位相同,其餘位相同認為是讀空

當最高位不同,其餘位相同認為是寫滿

注意:理論1試用的是二進位數之間的空滿比較判斷。

但是這篇文章中確不是這樣比較的,而是用的理論2,這裡我解釋一下

由於文章在設計中判斷是讀指針是否等於寫指針的時候,用的是讀寫指針的格雷碼形式(為什麼用格雷碼後面解釋),此時若用上面的理論1就會出問題,因為格雷碼是鏡像對稱的,若只根據最高位是否相同來區分是讀空還是寫滿是有問題的,詳情我會慢慢說,請看圖 1

綠色框起來的是0--15的格雷碼,用紅線將格雷碼分為上下兩部分

通過觀察格雷碼相鄰位每次只有1位發生變化,且上下兩部分,除了最高位相反,其餘位全都關於紅線鏡像對稱,

7 --> 8 ,格雷碼從 0100 --> 1100 ,只有最高位發生變化其餘位相同

6 --> 9 , 格雷碼從 0101 --> 1101 , 只有最高位發生變化其餘位相同

以此類推,為什麼要說鏡像對稱呢?

試想如果讀指針指向 8,寫指針指向 7 ,我們可以知道此時此刻並不是讀空狀態也不是寫滿狀態

但是如果在此刻套用理論 1 來判斷,看會出現什麼情況,我們來套一下

7的格雷碼與8的格雷碼的最高位不同,其餘位相同,所以判斷出為寫滿。這就出現誤判了,同樣套用在 6 和 9,5 和 10等也會出現誤判。

因此用格雷碼判斷是否為讀空或寫滿時應使用理論 2,看最高位和次高位是否相等,具體如下:

當最高位和次高位相同,其餘位相同認為是讀空

當最高位和次高位不同,其餘位相同認為是寫滿

補:理論2這個判斷方法適用於用格雷碼判斷比較空滿

在實際設計中如果不想用格雷碼比較,就可以利用格雷碼將讀寫地址同步到一個時鐘域後再將格雷碼再次轉化成二進位數再用理論1進行比較就好了。。

圖 1

2、由於是異步FIFO的設計,讀寫時鐘不一樣,在產生讀空信號和寫滿信號時,會涉及到跨時鐘域的問題,如何解決?

跨時鐘域的問題:上面我們已經提到要通過比較讀寫指針來判斷產生讀空和寫滿信號

但是讀指針是屬於讀時鐘域的,寫指針是屬於寫時鐘域的,而異步FIFO的讀寫時鐘域不同,是異步的,

要是將讀時鐘域的讀指針與寫時鐘域的寫指針不做任何處理直接比較肯定是錯誤的,因此我們需要進行同步處理以後仔進行比較

解決方法:兩級寄存器同步 + 格雷碼

同步的過程有兩個:

(1)將寫時鐘域的寫指針同步到讀時鐘域,將同步後的寫指針與讀時鐘域的讀指針進行比較產生讀空信號

(2)將讀時鐘域的讀指針同步到寫時鐘域,將同步後的讀指針與寫時鐘域的寫指針進行比較產生寫滿信號

同步的思想就是用兩級寄存器同步,簡單說就是打兩拍,相信有點基礎的早都爛熟於心,就不再多做解釋,不懂的可以看看代碼結合理解。

只是這樣簡單的同步就可以了嗎?no no no ,可怕的亞穩態還在等著你。

我們如果直接用二進位編碼的讀寫指針去完成上述的兩種同步是不行的,使用格雷碼更合適,為什麼呢?

因為二進位編碼的指針在跳變的時候有可能是多位數據一起變化,如二進位的7-->8 即 0111 --> 1000 ,在跳變的過程中 4 位全部發生了改變,這樣很容易產生毛刺,例如:

異步FIFO的寫指針和讀指針分屬不同時鐘域,這樣指針在進行同步過程中很容易出錯,比如寫指針在從0111到1000跳變時4位同時改變,這樣讀時鐘在進行寫指針同步後得到的寫指針可能是0000-1111的某個值,一共有2^4個可能的情況,而這些都是不可控制的,你並不能確定會出現哪個值,那出錯的概率非常大,怎麼辦呢?到了格雷碼發揮作用的時候了,而格雷碼的編碼特點是相鄰位每次只有 1 位發生變化, 這樣在進行指針同步的時候,只有兩種可能出現的情況:1.指針同步正確,正是我們所要的;2.指針同步出錯,舉例假設格雷碼寫指針從000->001,將寫指針同步到讀時鐘域同步出錯,出錯的結果只可能是000->000,因為相鄰位的格雷碼每次只有一位變化,這個出錯結果實際上也就是寫指針沒有跳變保持不變,我們所關心的就是這個錯誤會不會導致讀空判斷出錯?答案是不會,最多是讓空標誌在FIFO不是真正空的時候產生,而不會出現空讀的情形。所以gray碼保證的是同步後的讀寫指針即使在出錯的情形下依然能夠保證FIFO功能的正確性。在同步過程中的亞穩態不可能消除,但是我們只要保證它不會影響我們的正常工作即可。

3、由於設計的時候讀寫指針用了至少兩級寄存器同步,同步會消耗至少兩個時鐘周期,勢必會使得判斷空或滿有所延遲,這會不會導致設計出錯呢?

異步FIFO通過比較讀寫指針進行滿空判斷,但是讀寫指針屬於不同的時鐘域,所以在比較之前需要先將讀寫指針進行同步處理,

將寫指針同步到讀時鐘域再和讀指針比較進行FIFO空狀態判斷,因為在同步寫指針時需要時間,而在這個同步的時間內有可能還會寫入新的數據,因此同步後的寫指針一定是小於或者等於當前實際的寫指針,所以此時判斷FIFO為空不一定是真空,這樣更加保守,一共不會出現空讀的情況,雖然會影響FIFO的性能,但是並不會出錯,同理將讀指針同步到寫時鐘域再和寫指針比較進行FIFO滿狀態判斷,同步後的讀指針一定是小於或者等於當前的讀指針,所以此時判斷FIFO為滿不一定是真滿,這樣更保守,這樣可以保證FIFO的特性:FIFO空之後不能繼續讀取,FIFO滿之後不能繼續寫入。總結來說異步邏輯轉到同步邏輯不可避免需要額外的時鐘開銷,這會導致滿空趨於保守,但是保守並不等於錯誤,這麼寫會稍微有性能損失,但是不會出錯。

舉個例子:大多數情形下,異步FIFO兩端的時鐘不是同頻的,或者讀快寫慢,或者讀慢寫快,慢的時鐘域同步到快的時鐘域不會出現漏掉指針的情況,但是將指針從快的時鐘域同步到慢的時鐘域時可能會有指針遺漏,舉個例子以讀慢寫快為例,進行滿標誌判斷的時候需要將讀指針同步到寫時鐘域,因為讀慢寫快,所以不會有讀指針遺漏,同步消耗時鐘周期,所以同步後的讀指針滯後(小於等於)當前讀地址,所以可能滿標誌會提前產生,滿並非真滿。進行空標誌判斷的時候需要將寫指針同步到讀指針 ,因為讀慢寫快,所以當讀時鐘同步寫指針 的時候,必然會漏掉一部分寫指針,我們不用關心那到底會漏掉哪些寫指針,我們在乎的是漏掉的指針會對FIFO的空標誌產生影響嗎?比如寫指針從0寫到10,期間讀時鐘域只同步捕捉到了3、5、8這三個寫指針而漏掉了其他指針。當同步到8這個寫指針時,真實的寫指針可能已經寫到10 ,相當於在讀時鐘域還沒來得及覺察的情況下,寫時鐘域可能偷偷寫了數據到FIFO去,這樣在判斷它是不是空的時候會出現不是真正空的情況,漏掉的指針也沒有對FIFO的邏輯操作產生影響。

4、多位二進位碼如何轉化為格雷碼

二進位碼轉換成二進位格雷碼,其法則是保留二進位碼的最高位作為格雷碼的最高位,而次高位格雷碼為二進位碼的高位與次高位相異或,而格雷碼其餘各位與次高位的求法相類似。

我再換種更簡單的描述

二進位數 1 0 1 1 0

二進位數右移1位,空位補0 0 1 0 1 1

異或運算 1 1 1 0 1

這樣就可以實現二進位到格雷碼的轉換了,總結就是移位並且異或,verilog代碼實現就一句:assign wgraynext = (wbinnext>>1) ^ wbinnext;

是不是非常簡單。

三、代碼解析

異步FIFO的信號接口:

wclk wrst_n winc wdata //寫時鐘、寫復位、寫請求、寫數據 這幾個與寫有關的全部與wclk同步

rclk rrst_n rinc rdata //讀時鐘、讀 復位、讀 請求、讀 數據 這幾個與讀有關的全部與rclk同步

wfull //寫滿 與wclk同步

rempty // 讀空 與rclk同步

本次代碼共分為6個module

1、fifo.v 是頂層模塊,作用是將各個小模塊例化聯繫起來

module fifo

#(

parameter DSIZE = 8,

parameter ASIZE = 4

)

(

output [DSIZE-1:0] rdata,

output wfull,

output rempty,

input [DSIZE-1:0] wdata,

input winc, wclk, wrst_n,

input rinc, rclk, rrst_n

);

wire [ASIZE-1:0] waddr, raddr;

wire [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;

// synchronize the read pointer into the write-clock domain

sync_r2w sync_r2w

(

.wq2_rptr (wq2_rptr),

.rptr (rptr ),

.wclk (wclk ),

.wrst_n (wrst_n )

);

// synchronize the write pointer into the read-clock domain

sync_w2r sync_w2r

(

.rq2_wptr(rq2_wptr),

.wptr(wptr),

.rclk(rclk),

.rrst_n(rrst_n)

);

//this is the FIFO memory buffer that is accessed by both the write and read clock domains.

//This buffer is most likely an instantiated, synchronous dual-port RAM.

//Other memory styles can be adapted to function as the FIFO buffer.

fifomem

#(DSIZE, ASIZE)

fifomem

(

.rdata(rdata),

.wdata(wdata),

.waddr(waddr),

.raddr(raddr),

.wclken(winc),

.wfull(wfull),

.wclk(wclk)

);

//this module is completely synchronous to the read-clock domain and contains the FIFO read pointer and empty-flag logic.

rptr_empty

#(ASIZE)

rptr_empty

(

.rempty(rempty),

.raddr(raddr),

.rptr(rptr),

.rq2_wptr(rq2_wptr),

.rinc(rinc),

.rclk(rclk),

.rrst_n(rrst_n)

);

//this module is completely synchronous to the write-clock domain and contains the FIFO write pointer and full-flag logic

wptr_full

#(ASIZE)

wptr_full

(

.wfull(wfull),

.waddr(waddr),

.wptr(wptr),

.wq2_rptr(wq2_rptr),

.winc(winc),

.wclk(wclk),

.wrst_n(wrst_n)

);

endmodule

2、fifomem.v 生成存儲實體,FIFO 的本質是RAM,因此在設計存儲實體的時候有兩種方法:用數組存儲數據或者調用RAM的IP核

module fifomem

#(

parameter DATASIZE = 8, // Memory data word width

parameter ADDRSIZE = 4 // 深度為8即地址為3位即可,這裡多定義一位的原因是用來判斷是空還是滿,詳細在後文講到

) // Number of mem address bits

(

output [DATASIZE-1:0] rdata,

input [DATASIZE-1:0] wdata,

input [ADDRSIZE-1:0] waddr, raddr,

input wclken, wfull, wclk

);

`ifdef RAM //可以調用一個RAM IP核

// instantiation of a vendor's dual-port RAM

my_ram mem

(

.dout(rdata),

.din(wdata),

.waddr(waddr),

.raddr(raddr),

.wclken(wclken),

.wclken_n(wfull),

.clk(wclk)

);

`else //用數組生成存儲體

// RTL Verilog memory model

localparam DEPTH = 1 reg [DATASIZE-1:0] mem [0:DEPTH-1]; //生成2^4個位寬位8的數組

assign rdata = mem[raddr];

always @(posedge wclk) //當寫使能有效且還未寫滿的時候將數據寫入存儲實體中,注意這裡是與wclk同步的

if (wclken !wfull)

mem[waddr] = wdata;

`endif

endmodule

3、sync_r2w.v 將 rclk 時鐘域的格雷碼形式的讀指針同步到 wclk 時鐘域,簡單來講就是用兩級寄存器同步,即打兩拍

module sync_r2w

#(

parameter ADDRSIZE = 4

)

(

output reg [ADDRSIZE:0] wq2_rptr, //讀指針同步到寫時鐘域

input [ADDRSIZE:0] rptr, // 格雷碼形式的讀指針,格雷碼的好處後面會細說

input wclk, wrst_n

);

reg [ADDRSIZE:0] wq1_rptr;

always @(posedge wclk or negedge wrst_n)

if (!wrst_n) begin

wq1_rptr = 0;

wq2_rptr = 0;

end

else begin

wq1_rptr= rptr;

wq2_rptr=wq1_rptr;

end

endmodule

4、sync_w2r.v 將 wclk 時鐘域的格雷碼形式的寫指針同步到 rclk 時鐘域

module sync_w2r

#(parameter ADDRSIZE = 4)

(

output reg [ADDRSIZE:0] rq2_wptr, //寫指針同步到讀時鐘域

input [ADDRSIZE:0] wptr, //格雷碼形式的寫指針

input rclk, rrst_n

);

reg [ADDRSIZE:0] rq1_wptr;

always @(posedge rclk or negedge rrst_n)

if (!rrst_n)begin

rq1_wptr = 0;

rq2_wptr = 0;

end

else begin

rq1_wpt = wptr;

rq2_wptr = rq1_wptr;

end

endmodule

5、rptr_empty.v 將 sync_w2r.v 同步後的寫指針與 rclk 時鐘域的讀指針進行比較生成都空信號

module rptr_empty

#(

parameter ADDRSIZE = 4

)

(

output reg rempty,

output [ADDRSIZE-1:0] raddr, //二進位形式的讀指針

output reg [ADDRSIZE :0] rptr, //格雷碼形式的讀指針

input [ADDRSIZE :0] rq2_wptr, //同步後的寫指針

input rinc, rclk, rrst_n

);

reg [ADDRSIZE:0] rbin;

wire [ADDRSIZE:0] rgraynext, rbinnext;

// GRAYSTYLE2 pointer

//將二進位的讀指針與格雷碼進位的讀指針同步

always @(posedge rclk or negedge rrst_n)

if (!rrst_n) begin

rbin = 0;

rptr = 0;

end

else begin

rbin=rbinnext; //直接作為存儲實體的地址

rptr=rgraynext;//輸出到 sync_r2w.v模塊,被同步到 wrclk 時鐘域

end

// Memory read-address pointer (okay to use binary to address memory)

assign raddr = rbin[ADDRSIZE-1:0]; //直接作為存儲實體的地址,比如連接到RAM存儲實體的讀地址端。

assign rbinnext = rbin + (rinc ~rempty); //不空且有讀請求的時候讀指針加1

assign rgraynext = (rbinnext>>1) ^ rbinnext; //將二進位的讀指針轉為格雷碼

// FIFO empty when the next rptr == synchronized wptr or on reset

assign rempty_val = (rgraynext == rq2_wptr); //當讀指針等於同步後的寫指針,則為空。

always @(posedge rclk or negedge rrst_n)

if (!rrst_n)

rempty = 1'b1;

else

rempty = rempty_val;

endmodule

6、wptr_full.v 將 sync_r2w.v 同步後的讀指針與wclk 時鐘域的寫指針進行比較生成寫滿信號

module wptr_full

#(

parameter ADDRSIZE = 4

)

(

output reg wfull,

output [ADDRSIZE-1:0] waddr,

output reg [ADDRSIZE :0] wptr,

input [ADDRSIZE :0] wq2_rptr,

input winc, wclk, wrst_n

);

reg [ADDRSIZE:0] wbin;

wire [ADDRSIZE:0] wgraynext, wbinnext;

// GRAYSTYLE2 pointer

always @(posedge wclk or negedge wrst_n)

if (!wrst_n)

{wbin, wptr} = 0;

else

{wbin, wptr} = {wbinnext, wgraynext};

// Memory write-address pointer (okay to use binary to address memory)

assign waddr = wbin[ADDRSIZE-1:0];

assign wbinnext = wbin + (winc ~wfull);

assign wgraynext = (wbinnext>>1) ^ wbinnext; //二進位轉為格雷碼

//

assign wfull_val = (wgraynext=={~wq2_rptr[ADDRSIZE:ADDRSIZE-1],wq2_rptr[ADDRSIZE-2:0]}); //當最高位和次高位不同其餘位相同時則寫指針超前於讀指針一圈,即寫滿。後面會詳細解釋。

always @(posedge wclk or negedge wrst_n)

if (!wrst_n)

wfull = 1'b0;

else

wfull = wfull_val;

endmodule

7、測試文件

`timescale 1ns /1ns

module test();

reg [7:0] wdata;

reg winc, wclk, wrst_n;

reg rinc, rclk, rrst_n;

wire [7:0] rdata;

wire wfull;

wire rempty;

fifo

u_fifo (

.rdata(rdata),

.wfull(wfull),

.rempty(rempty),

.wdata (wdata),

.winc (winc),

.wclk (wclk),

.wrst_n(wrst_n),

.rinc(rinc),

.rclk(rclk),

.rrst_n(rrst_n)

);

localparam CYCLE = 20;

localparam CYCLE1 = 40;

//時鐘周期,單位為ns,可在此修改時鐘周期。

//生成本地時鐘50M

initial begin

wclk = 0;

forever

#(CYCLE/2)

wclk=~wclk;

end

initial begin

rclk = 0;

forever

#(CYCLE1/2)

rclk=~rclk;

end

//產生復位信號

initial begin

wrst_n = 1;

#2;

wrst_n = 0;

#(CYCLE*3);

wrst_n = 1;

end

initial begin

rrst_n = 1;

#2;

rrst_n = 0;

#(CYCLE*3);

rrst_n = 1;

end

always @(posedge wclk or negedge wrst_n)begin

if(wrst_n==1'b0)begin

winc = 0;

rinc = 0;

end

else begin

winc = $random;

rinc = $random;

end

end

always @(posedge rclk or negedge rrst_n)begin

if(rrst_n==1'b0)begin

rinc = 0;

end

else begin

rinc = $random;

end

end

always@(*)begin

if(winc == 1)

wdata= $random ;

else

wdata = 0;

end

endmodule

8、仿真結果

由於截圖篇幅的限制請自己驗證仿真。

相關焦點

  • 一種節能型可升級異步FIFO的FPGA實現
    現代數字系統中,異步FIFO是一種被廣泛應用於跨時鐘域進行數據傳輸的有效方式。異步FIFO主要應用於兩種不同時鐘域的數據傳輸,這意味著數據的寫入在一個時鐘域,而數據的讀出卻在另一個時鐘域,兩個時鐘完全異步[1]。
  • FIFO 同步、異步以及Verilog代碼實現
    FIFO的分類根均FIFO工作的時鐘域,可以將FIFO分為同步FIFO和異步FIFO。同步FIFO是指讀時鐘和寫時鐘為同一個時鐘。在時鐘沿來臨時同時發生讀寫操作。異步FIFO是指讀寫時鐘不一致,讀寫時鐘是互相獨立的。FIFO設計的難點 FIFO設計的難點在於怎樣判斷FIFO的空/滿狀態。
  • 基於FPGA的高速異步FIFO的設計與實現
    多時鐘帶來的一個問題就是,如何設計異步時鐘之間的接口電路。異步FIFO(First In First Out)是解決這個問題的一種簡便、快捷的解決方案。使用異步FIFO可以在兩個不同時鐘系統之間快速而方便地傳輸實時數據.在網絡接口、圖像處理等方面,異步FIFO都得到廣泛的應用。異步FIFO是一種先進先出的電路,使用在數據接口部分,用來存儲、緩衝在兩個異步時鐘之間的數據傳輸。
  • 基於FPGA與DDR2 SDRAM的大容量異步FIFO緩存設計
    因此根據FIFO的基本原理,通過採用Xilinx FPGA器件和Micron公司的256MB DDR2 SDRAM MT4HTF3264HY-667設計並實現了一種異步FIFO。該FIFO具有價格相對便宜、高數據帶寬、容量大、數據位寬可以根據需要進行相應靈活配置等特點,具有較高的工程實用價值。
  • 異步FIFO的VHDL設計
    FIFO的接口信號包括異步的寫時鐘(wr_clk)和讀時鐘(rd_clk)、與寫時鐘同步的寫有效(wren)和寫數據(wr_data)、與讀時鐘同步的讀有效(rden)和讀數據(rd_data)。為了實現正確的讀寫和避免FIFO的上溢或下溢,通常還應該給出與讀時鐘和寫時鐘同步的FIFO的空標誌(empty)和滿標誌(full)以禁止讀寫操作。 1 異步FIFO功能描述
  • 雷射告警系統的異步FIFO設計
    本文採用Verilog HDL語言設計了一種異步FIFO(時鐘周期和相位相互獨立),它不僅提供數據緩衝,而且能夠實現不同時鐘域間的轉換等功能。本系統採用Xilinx公司Spartan-Ⅲ系列晶片XC3S1500,設計完成異步FIFO緩存,包括採集控制電路、FFT數據處理、時鐘控制信號、接口電路等。雷射告警接收系統的數據採樣和處理框圖如圖1所示。
  • 詳解FPGA四大設計要點
    對於FPGA來說,要儘可能避免異步設計,儘可能採用同步設計。對於控制信號,可以採用雙採樣;對於數據信號,可以採用異步fifo.需要注意的是,異步fifo不是萬能的,一個異步fifo也只能解決一定範圍內的頻差問題。4)儘可能將FPGA內部的PLL、DLL利用起來,這會給你的設計帶來大量的好處。
  • 集成電路FPGA設計的四點建議
    雖然理論上FPGA可以支持500MHz,但在實際設計中,很難實現200MHz以上的工作頻率。FPGA的設計要點之一:時鐘樹對於FPGA,應避免異步設計,儘量採用同步設計。同步設計的第一個關鍵是時鐘樹。對於控制信號,可以使用雙採樣;對於數據信號,可以使用異步fifo,需要注意的是,異步fifo不是萬能,異步fifo只能解決範圍內的頻差問題。4) 儘量在FPGA內部使用PLL,DLL,這將給您的設計帶來很多好處。
  • FPGA設計的高速FIFO電路技術
    在大容量高速採集系統項目的開發過程中,FPGA作為可編程邏輯器件,設計靈活、可操作性強,是高速數字電路設計的核心器件。由於FPGA內嵌存儲器的容量有限,通常不能夠滿足實際設計電路的需求,需要外接SRAM、SDRAM、磁碟陣列等大容量存儲設備。A/D輸出的數據流速度快,經過FPGA降速後,位數寬,速度仍然很高,不能直接存儲到外部存儲器。
  • 一種讀寫深度可配置的異步FIFO設計
    引言 隨著設計複雜度的不斷提高,現代電子信息設計中,單一時鐘驅動已無法滿足設計與應用的需求。基於多時鐘驅動的設計已經越來越普遍,在異步時鐘域的設計中,跨時鐘域數據信號傳輸是必須考慮的一個問題。
  • FPGA異步時鐘設計中的同步策略
    1 引言   基於FPGA的數字系統設計中大都推薦採用同步時序的設計,也就是單時鐘系統。但是實際的工程中,純粹單時鐘系統設計的情況很少,特別是設計模塊與外圍晶片的通信中,跨時鐘域的情況經常不可避免。
  • 9年FPGA工作經驗,轉行了,苦海無涯……
    工作了9年的fpga,總要總結…… 其實說我的fpga經驗,也是一坨屎。三年的,用altera的c3和c4 做led控制卡。2年的用lattice的MACHXO-XO2和ECP2做了視頻和網絡光端機,3年的XILINX的SPARTAN 6 做了視頻ISP處理,現在一年的xilinx的ZYNQ做機器視覺。
  • PCI總線接口設計及專用接口晶片的應用
    接口電路實現比較困難,目前實現pci接口的方法主要有:利用cpld或fpga 可編程邏輯器件和利用專門的pci接口晶片等多種方法實現。pci接口晶片具有設計簡單、功能強大、可靠性好等特點,從而大大減少了開發人員的工作量。在 實際工作中我們綜合各方面的因素,在本文選擇了pci9054。
  • 有名管道(FIFO)的用法
    如下所示:-rwxr-xr-x 1 root root 7368 2008-10-29 09:05 create_fifo-rw-r--r-- 1 root root 380 2008-10-29 09:05 create_fifo.cprw-r--r-- 1 root root 0 2009-06-12 14:18 myfifo-rwxr-xr-x
  • 一種基於FPGA的視頻圖像畫面分割器設計
    研究的主要特色在於構建了以FPGA為核心器件的視頻畫面分割的硬體平臺,首先,將DVI視頻信號,經視頻解碼晶片轉換為數字視頻圖像信號後送入異步FIFO緩衝。然後,根據畫面分割需要進行視頻圖像數據抽取,並將抽取的視頻圖像數據按照一定的規則存儲到圖像存儲器。
  • 淺析FPGA中異步復位同步釋放的原理
    打開APP 淺析FPGA中異步復位同步釋放的原理 發表於 2019-08-21 17:51:49 FPGA有同步復位和異步復位兩種
  • 異步FIFO在DSP圖像採集系統中的應用
    1 系統設計整體架構 本系統是基於DSP的數字圖像處理系統,總體結構設計如圖1所示。首先CCD攝像機拍攝視頻圖像,輸出標準PAL制式視頻信號,輸入到視頻解碼晶片TVP5150中,TVP5150將模擬圖像信號轉換為數字圖像信號送入FIFO中,本系統採用AL422B。
  • 細說應用異步設計
    (2)是一種應用的多線程處理方式應用中的異步處理不用阻塞當前線程來等待處理完成,而是允許後續操作,直到其他線程將它處理完成,再通知當前線程。本文主要taol系統間的異步架構設計,具體系統內的多線程/進程的異步設計開發不在本次範圍。
  • MPU6050移植讀取數據時出現FIFO溢出問題解析
    */   if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more))   return -1;   /* Parse DMP packet.
  • FPGA設計開發軟體ISE使用技巧之:創建設計工程
    6.4 創建設計工程本文引用地址:http://www.eepw.com.cn/article/269335.htm  本節將重點講述如何在ISE下創建一個新的工程。要完成一個設計,第一步要做的就是新建一個工程。