FIFO和雙端口RAM都是高級存儲器.
FIFO是英文First In First Out 的縮寫,是一種先進先出的數據緩存器,他與普通存儲器的區別是沒有外部讀寫地址線,這樣使用起來非常簡單,但缺點就是只能順序寫入數據,順序的讀出數據,其數據地址由內部讀寫指針自動加1完成,不能像普通存儲器那樣可以由地址線決定讀取或寫入某個指定的地址。
2.什么情況下用FIFO?
FIFO一般用於不同時鍾域之間的數據傳輸,比如FIFO的一端時AD數據采集,另一端時計算機的PCI總線,假設其AD采集的速率為16位 100K SPS,那么每秒的數據量為100K×16bit=1.6Mbps,而PCI總線的速度為33MHz,總線寬度32bit,其最大傳輸速率為1056Mbps,在兩個不同的時鍾域間就可以采用FIFO來作為數據緩沖。另外對於不同寬度的數據接口也可以用FIFO,例如單片機位8位數據輸出,而DSP可能是16位數據輸入,在單片機與DSP連接時就可以使用FIFO來達到數據匹配的目的。
3.FIFO的一些重要參數
FIFO的寬度:也就是英文資料里常看到的THE WIDTH,它只的是FIFO一次讀寫操作的數據位,就像MCU有8位和16位,ARM 32位等等,FIFO的寬度在單片成品IC中是固定的,也有可選擇的,如果用FPGA自己實現一個FIFO,其數據位,也就是寬度是可以自己定義的。
FIFO的深度:THE DEEPTH,它指的是FIFO可以存儲多少個N位的數據(如果寬度為N)。如一個8位的FIFO,若深度為8,它可以存儲8個8位的數據,深度為12 ,就可以存儲12個8位的數據,FIFO的深度可大可小,個人認為FIFO深度的計算並無一個固定的公式。在FIFO實際工作中,其數據的滿/空標志可以控制數據的繼續寫入或讀出。在一個具體的應用中也不可能由一些參數算數精確的所需FIFO深度為多少,這在寫速度大於讀速度的理想狀態下是可行的,但在實際中用到的FIFO深度往往要大於計算值。一般來說根據電路的具體情況,在兼顧系統性能和FIFO成本的情況下估算一個大概的寬度和深度就可以了。而對於寫速度慢於讀速度的應用,FIFO的深度要根據讀出的數據結構和讀出數據的由那些具體的要求來確定。
滿標志:FIFO已滿或將要滿時由FIFO的狀態電路送出的一個信號,以阻止FIFO的寫操作繼續向FIFO中寫數據而造成溢出(overflow)。
空標志:FIFO已空或將要空時由FIFO的狀態電路送出的一個信號,以阻止FIFO的讀操作繼續從FIFO中讀出數據而造成無效數據的讀出(underflow)。
讀時鍾:讀操作所遵循的時鍾,在每個時鍾沿來臨時讀數據。
寫時鍾:寫操作所遵循的時鍾,在每個時鍾沿來臨時寫數據。
讀指針:指向下一個讀出地址。讀完后自動加1。
寫指針:指向下一個要寫入的地址的,寫完自動加1。
讀寫指針其實就是讀寫的地址,只不過這個地址不能任意選擇,而是連續的。
4.FIFO的分類
根均FIFO工作的時鍾域,可以將FIFO分為 同步FIFO(synchronous)和異步FIFO( Asynchronous)。同步FIFO是指讀時鍾和寫時鍾為同一個時鍾。在時鍾沿來臨時同時發生讀寫操作。異步FIFO是指讀寫時鍾不一致,讀寫時鍾是互相獨立的。
5.FIFO設計的難點
FIFO設計的難點在於怎樣判斷FIFO的空/滿狀態。為了保證數據正確的寫入或讀出,而不發生益處或讀空的狀態出現,必須保證FIFO在滿的情況下,不能進行寫操作。在空的狀態下不能進行讀操作。怎樣判斷FIFO的滿/空就成了FIFO設計的核心問題。由於同步FIFO幾乎很少用到,這里只描述異步FIFO的空/滿標志產生問題。
在用到觸發器的設計中,不可避免的會遇到亞穩態的問題(關於亞穩態這里不作介紹,可查看相關資料)。在涉及到觸發器的電路中,亞穩態無法徹底消除,只能想辦法將其發生的概率將到最低。其中的一個方法就是使用格雷碼。格雷碼在相鄰的兩個碼元之間只由一位變換(二進制碼在很多情況下是很多碼元在同時變化)。這就會避免計數器與時鍾同步的時候發生亞穩態現象。但是格雷碼有個缺點就是只能定義2^n的深度,而不能像二進制碼那樣隨意的定義FIFO的深度,因為格雷碼必須循環一個2^n,否則就不能保證兩個相鄰碼元之間相差一位的條件,因此也就不是真正的各雷碼了。第二就是使用冗余的觸發器,假設一個觸發器發生亞穩態的概率為P,那么兩個及聯的觸發器發生亞穩態的概率就為P的平方。但這回導致延時的增加。亞穩態的發生會使得FIFO出現錯誤,讀/寫時鍾采樣的地址指針會與真實的值之間不同,這就導致寫入或讀出的地址錯誤。由於考慮延時的作用,空/滿標志的產生並不一定出現在FIFO真的空/滿時才出現。可能FIFO還未空/滿時就出現了空/滿標志。這並沒有什么不好,只要保證FIFO不出現overflow or underflow 就OK了。
很多關於FIFO的文章其實討論的都是空/滿標志的不同算法問題。
在Vijay A. Nebhrajani的《異步FIFO結構》一文中,作者提出了兩個關於FIFO空/滿標志的算法。第一個算法:構造一個指針寬度為N+1,深度為2^N字節的FIFO(為便方比較將格雷碼指針轉換為二進制指針)。當指針的二進制碼中最高位不一致而其它N位都相等時,FIFO為滿(在Clifford E. Cummings的文章中以格雷碼表示是前兩位均不相同,而后兩位LSB相同為滿,這與換成二進制表示的MSB不同其他相同為滿是一樣的)。當指針完全相等時,FIFO為空。這也許不容易看出,舉個例子說明一下:一個深度為8字節的FIFO怎樣工作(使用已轉換為二進制的指針)。FIFO_WIDTH=8,FIFO_DEPTH= 2^N = 8,N = 3,指針寬度為N+1=4。起初rd_ptr_bin和wr_ptr_bin均為“0000”。此時FIFO中寫入8個字節的數據。wr_ptr_bin =“1000”,rd_ptr_bin=“0000”。當然,這就是滿條件。現在,假設執行了8次的讀操作,使得rd_ptr_bin =“1000”,這就是空條件。另外的8次寫操作將使wr_ptr_bin 等於“0000”,但rd_ptr_bin 仍然等於“1000”,因此FIFO為滿條件。顯然起始指針無需為“0000”。假設它為“0100”,並且FIFO為空,那么8個字節會使wr_ptr_bin =“1100”,, rd_ptr_bin 仍然為“0100”。這又說明FIFO為滿。在Vijay A. Nebhrajani的這篇《異步FIFO結構》文章中說明了怎樣運用格雷碼來設置空滿的條件,但沒有說清為什么深度為8的FIFO其讀寫指針要用3+1位的格雷碼來實現,而3+1位的格雷碼可以表示16位的深度,而真實的FIFO只有8位,這是怎么回事?而這個問題在Clifford E. Cummings的文章中得以解釋。三位格雷碼可表示8位的深度,若在加一位最為MSB,則這一位加其他三位組成的格雷碼並不代表新的地址,也就是說格雷碼的0100表示表示7,而1100仍然表示7,只不過格雷碼在經過一個以0位MSB的循環后進入一個以1為MSB的循環,然后又進入一個以0位MSB的循環,其他的三位碼仍然是格雷碼,但這就帶來一個問題,在0100的循環完成后,進入1000,他們之間有兩位發生了變換,而不是1位,所以增加一位MSB的做法使得該碼在兩處:0100~1000,1100~0000有兩位碼元發生變化,故該碼以不是真正的格雷碼。增加的MSB是為了實現空滿標志的計算。Vijay A. Nebhrajani的文章用格雷碼轉二進制,再轉格雷碼的情況下提出空滿條件,僅過兩次轉換,而Clifford E. Cummings的文章中直接在格雷碼條件下得出空滿條件。其實二者是一樣的,只是實現方式不同罷了。
第二種算法:Clifford E. Cummings的文章中提到的STYLE #2。它將FIFO地址分成了4部分,每部分分別用高兩位的MSB 00 、01、 11、 10決定FIFO是否為going full 或going empty (即將滿或空)。如果寫指針的高兩位MSB小於讀指針的高兩位MSB則FIFO為“幾乎滿”,
若寫指針的高兩位MSB大於讀指針的高兩位MSB則FIFO為“幾乎空”。
在Vijay A. Nebhrajani的《異步FIFO結構》第三部分的文章中也提到了一種方法,那就是方向標志與門限。設定了FIFO容量的75%作為上限,設定FIFO容量的25%為下限。當方向標志超過門限便輸出滿/空標志,這與Clifford E. Cummings的文章中提到的STYLE #2可謂是異曲同工。他們都屬於保守的空滿判斷。其實這時輸出空滿標志FIFO並不一定真的空/滿。
說到此,我們已經清楚地看到,FIFO設計最關鍵的就是產生空/滿標志的算法的不同產生了不同的FIFO。但無論是精確的空滿還是保守的空滿都是為了保證FIFO工作的可靠。
FIFO存儲器是系統的緩沖環節,如果沒有FIFO存儲器,整個系統就不可能正常工作,它主要有幾方面的功能:
1)對連續的數據流進行緩存,防止在進機和存儲操作時丟失數據;
2)數據集中起來進行進機和存儲,可避免頻繁的總線操作,減輕CPU的負擔;
3)允許系統進行DMA操作,提高數據的傳輸速度。這是至關重要的一點,如果不采用DMA操作,數據傳輸將達不到傳輸要求,而且大大增加CPU的負擔,無法同時完成數據的存儲工作。
常用芯片(IDT,CYPRESS)
IDT7203,IDT72V01L35J(RMB23),CY7C425(RMB80),CY7C4205,
我用過IDT7203,1024x9的,在西安賣60多.
雙端口RAM
雙端口RAM是一種特殊的數據存貯芯片,具有兩套完全獨立的數據線、地址線、讀寫控制線,允許兩個CPU對雙端口RAM的同一單元進行存取;具有兩套完全獨立的中斷邏輯,實現兩個CPU間的握手控制信號;具有兩套完全獨立的“忙”邏輯,保證兩個CPU同時對同一單元進行讀寫操作的正確性。
如IDT7007,CY7C08D53,cy7c024
在對產品可靠性要求高的系統中,往往需要硬件冗余。有些設備不僅要求其在各種惡劣的天氣下工作,而且要求長期不間斷工作。為提高可靠性往往采用雙CPU系統。平時主單片機系統工作,並將所處理的數據存儲在外存,一旦主CPU系統出現故障,副CPU可切換上來,並利用公共外存的數據繼續工作,而不需要人工干預。這時雙端口RAM做為外存就是兩個CPU之間信息傳遞的最好渠道。
數據獲取及交換是多CPU系統的重要組成部分。在這類系統中,數據交換要求的通信速率往往很高,傳統的並行接口和串行接口設計無論在通信速率還是在可靠性方面都不易滿足要求。而雙端口RAM(Dual Port RAM,簡稱DPRAM)具有通信速率高、接口設計簡單等特點,是一個較好的實現方案,在設計中得到廣泛的應用。
雙端口 RAM 的優點是通訊速度快, 實時性強。該器件允許兩個端口獨立地對存儲器單元進行存取操作, 且由於存儲器內部特殊的單元電路設計, 端口雙方同時對同一個單元進行讀操作時無需仲裁邏輯; 但當兩端同時對同一單元進行讀/ 寫或寫/ 寫操作時, 仍會發生競爭。解決讀/ 寫沖突的一個簡單辦法是執行冗余的讀周期, 也可使用“郵箱”傳送狀態信息方式進行軟件仲裁。
對於單個的微處理器而言,雙端口RAM同普通的RAM沒有什么明顯的區別,只有多個微處理器對同一地址進行工作時,才會出現競爭。對於問題的解決,雙端口RAM提供的硬件判優工作方式。