新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 牛人業(yè)話 > 零基礎(chǔ)學(xué)FPGA (十八) 談可編程邏輯設(shè)計(jì)思想與技巧!對(duì)您肯定有用!

零基礎(chǔ)學(xué)FPGA (十八) 談可編程邏輯設(shè)計(jì)思想與技巧!對(duì)您肯定有用!

—— 零基礎(chǔ)學(xué)FPGA (二十) 談可編程邏輯設(shè)計(jì)思想與技巧!對(duì)您肯定有用!
作者: 時(shí)間:2015-05-08 來(lái)源:網(wǎng)絡(luò) 收藏

  今天給大家?guī)?lái)的是我們?cè)?a class="contentlabel" href="http://m.butianyuan.cn/news/listbylabel/label/FPGA">FPGA設(shè)計(jì)中經(jīng)常要遇到的設(shè)計(jì)技巧與思想,即乒乓操作,串并轉(zhuǎn)換,流水線操作和跨時(shí)鐘域信號(hào)的同步問(wèn)題。

本文引用地址:http://m.butianyuan.cn/article/273855.htm

  之前也看過(guò)一些書(shū),也在網(wǎng)上找過(guò)一些資料,不過(guò)小墨發(fā)現(xiàn)大部分都是理論講解,僅僅是給一個(gè)框圖就沒(méi)事了,或者是好幾個(gè)網(wǎng)站的資料都是一樣的,都是復(fù)制的一個(gè)地方的,僅僅是講解,沒(méi)有實(shí)例,要不就是某個(gè)網(wǎng)站提供源碼,但是要注冊(cè),還要花什么積分,沒(méi)有積分還得要錢(qián)...很不利于初學(xué)者的學(xué)習(xí)(人與人之間怎么就不能多點(diǎn)信任呢~還要錢(qián)...)。所以小墨想寫(xiě)這么一篇文章來(lái)介紹一下這4種思想,理論部分書(shū)上多得是,我就不過(guò)多的解釋,主要給大家講一些實(shí)例型的幫大家理解。

  一、乒乓操作

  乒乓操作主要用于數(shù)據(jù)流的處理,是用面積換取速度的體現(xiàn)之一,要知道面積與速度的互換貫穿設(shè)計(jì)的始終,下面先給一個(gè)框圖

  

360桌面截圖20150107131605.jpg

 

  我先來(lái)解釋一下乒乓操作的過(guò)程:

  首先數(shù)據(jù)需要通過(guò)一個(gè)2選一數(shù)據(jù)選擇器,在第一個(gè)時(shí)鐘周期將數(shù)據(jù)緩存到緩存模塊1,常用的緩存模塊可以是fifo,雙口RAM(DPRAM),單口RAM(SPRAM),第二個(gè)時(shí)鐘周期的時(shí)候,數(shù)據(jù)流開(kāi)始往緩存模塊2里面寫(xiě)數(shù)據(jù),與此同時(shí),預(yù)處理模塊會(huì)從緩存模塊1里面讀取數(shù)據(jù),到了第三個(gè)時(shí)鐘周期數(shù)據(jù)流再往緩存模塊1里面寫(xiě)數(shù)據(jù),與此同時(shí),預(yù)處理模塊2開(kāi)始從緩存模塊2讀取數(shù)據(jù),周而復(fù)始...這樣,輸入數(shù)據(jù)流和輸出數(shù)據(jù)流按節(jié)拍來(lái)回切換,可以使數(shù)據(jù)沒(méi)有停頓的進(jìn)行傳輸,使傳輸速率大大提高。

  小墨同學(xué)發(fā)現(xiàn),在給這個(gè)框圖配實(shí)例的時(shí)候,幾乎所有的網(wǎng)站都是這個(gè)解釋,我用紅字標(biāo)出,個(gè)人感覺(jué)解釋的不怎么樣,還有些地方是錯(cuò)的

  假設(shè)端口 A 的輸入數(shù)據(jù)流的速率為 100Mbps ,乒乓操作的緩沖周期是 10ms 。以下分析各個(gè)節(jié)點(diǎn)端口的數(shù)據(jù)速率。

  A 端口處輸入數(shù)據(jù)流速率為 100Mbps ,在第 1 個(gè)緩沖周期 10ms 內(nèi),通過(guò) “ 輸入數(shù)據(jù)選擇單元 ” ,從 B1 到達(dá) DPRAM1 。 B1 的數(shù)據(jù)速率也是 100Mbps , DPRAM1 要在 10ms 內(nèi)寫(xiě)入 1Mb 數(shù)據(jù)。同理,在第 2 個(gè) 10ms ,數(shù)據(jù)流被切換到 DPRAM2 ,端口 B2 的數(shù)據(jù)速率也是 100Mbps , DPRAM2 在第 2 個(gè) 10ms 被寫(xiě)入 1Mb 數(shù)據(jù)。在第 3 個(gè) 10ms ,數(shù)據(jù)流又切換到 DPRAM1 , DPRAM1 被寫(xiě)入 1Mb 數(shù)據(jù)。

  仔細(xì)分析就會(huì)發(fā)現(xiàn)到第 3 個(gè)緩沖周期時(shí),留給 DPRAM1 讀取數(shù)據(jù)并送到 “ 數(shù)據(jù)預(yù)處理模塊 1” 的時(shí)間一共是 20ms 。有的工程師困惑于 DPRAM1 的讀數(shù)時(shí)間為什么是 20ms ,這個(gè)時(shí)間是這樣得來(lái)的:首先,在在第 2 個(gè)緩沖周期向 DPRAM2 寫(xiě)數(shù)據(jù)的 10ms 內(nèi), DPRAM1 可以進(jìn)行讀操作;另外,在第 1 個(gè)緩沖周期的第 5ms 起 ( 絕對(duì)時(shí)間為 5ms 時(shí)刻 ) , DPRAM1 就可以一邊向 500K 以后的地址寫(xiě)數(shù)據(jù),一邊從地址 0 讀數(shù),到達(dá) 10ms 時(shí), DPRAM1 剛好寫(xiě)完了 1Mb 數(shù)據(jù),并且讀了 500K 數(shù)據(jù),這個(gè)緩沖時(shí)間內(nèi) DPRAM1 讀了 5ms ;在第 3 個(gè)緩沖周期的第 5ms 起 ( 絕對(duì)時(shí)間為 35ms 時(shí)刻 ) ,同理可以一邊向 500K 以后的地址寫(xiě)數(shù)據(jù)一邊從地址 0 讀數(shù),又讀取了 5 個(gè) ms ,所以截止 DPRAM1 第一個(gè)周期存入的數(shù)據(jù)被完全覆蓋以前, DPRAM1 最多可以讀取 20ms 時(shí)間,而所需讀取的數(shù)據(jù)為 1Mb ,所以端口 C1 的數(shù)據(jù)速率為: 1Mb/20ms=50Mbps 。因此, “ 數(shù)據(jù)預(yù)處理模塊 1” 的最低數(shù)據(jù)吞吐能力也僅僅要求為 50Mbps 。同理, “ 數(shù)據(jù)預(yù)處理模塊 2” 的最低數(shù)據(jù)吞吐能力也僅僅要求為 50Mbps 。換言之,通過(guò)乒乓操作, “ 數(shù)據(jù)預(yù)處理模塊 ” 的時(shí)序壓力減輕了,所要求的數(shù)據(jù)處理速率僅僅為輸入數(shù)據(jù)速率的 1/2 。

  雖然各個(gè)網(wǎng)站上都是這么解釋的,但是個(gè)人感覺(jué)解釋的不怎么樣,下面我用我自己的理解給大家解釋一下這個(gè)例子

  先看我給大家畫(huà)的一個(gè)圖,雖然畫(huà)的不怎么樣

  

360桌面截圖20150107133820.jpg

 

  這里我們只計(jì)算緩存模塊1的速率

  首先看第一個(gè)周期10ms,數(shù)據(jù)流往緩存模塊1里面寫(xiě)數(shù)據(jù),到第5ms時(shí),預(yù)處理模塊1開(kāi)始從緩存模塊1里面讀數(shù)據(jù),到10ms時(shí),緩存模塊1寫(xiě)了1M數(shù)據(jù),讀了5K數(shù)據(jù),下面切換到第二個(gè)周期,由于在第二個(gè)周期的時(shí)候預(yù)處理模塊1還可以從緩存模塊1里面讀數(shù)據(jù),所以到第15ms時(shí),緩存模塊1里面的數(shù)據(jù)被讀完

  

360桌面截圖20150107134724.jpg

 

  到了第三個(gè)時(shí)鐘周期,也就是從第20ms開(kāi)始數(shù)據(jù)流往緩存模塊1寫(xiě)數(shù)據(jù),到第25ms時(shí),預(yù)處理模塊開(kāi)始從緩存模塊讀數(shù)據(jù),直到35ms時(shí)才讀完,這樣我們來(lái)算一下,在第一個(gè)時(shí)鐘周期讀了5K數(shù)據(jù),注意我上面畫(huà)的時(shí)鐘周期數(shù),就是那個(gè)半圓形的,

  在第三個(gè)時(shí)鐘周期讀了5k數(shù)據(jù),注意每個(gè)時(shí)鐘周期只有5K,另外5K到了下一個(gè)時(shí)鐘周期了,所以我們不考慮,我們只考慮緩存模塊1的速率。再看一下時(shí)間,從第10ms讀完第一個(gè)5K,到第30ms讀完第2個(gè)5k,共用了20ms,讀了1M數(shù)據(jù),所以速率為1M/20ms=50M/s。

  下面再給大家講一個(gè)實(shí)例,具體代碼我會(huì)附在文章后面

  

360桌面截圖20150107140510.jpg

 

  用state來(lái)控制乒乓操作的來(lái)回切換

  

360桌面截圖20150107140642.jpg

 

  根據(jù)剛才講的,控制緩存器的讀寫(xiě),這里只列些部分代碼,具體代碼請(qǐng)大家在文章后面下載

  下面附上仿真時(shí)序圖,我在testbench中將數(shù)據(jù)設(shè)為從0 遞增的,可以看到仿真波形中是將奇偶數(shù)分開(kāi)的,證明我們代碼是正確的

  

360桌面截圖20150101215834.jpg

 

  二、串并轉(zhuǎn)換

  串并轉(zhuǎn)換總的來(lái)說(shuō)就是將串行輸入信號(hào)轉(zhuǎn)換為并行輸出,也是用面積換取速度的一種方法,串并轉(zhuǎn)換總的來(lái)說(shuō)比較簡(jiǎn)單,小墨就只給大家講一下我自己寫(xiě)的代碼吧

  首先要先對(duì)串入信號(hào)進(jìn)行采集,加入我們是8位一輸出,每進(jìn)來(lái)一位數(shù)據(jù),我們便將原數(shù)據(jù)左移一位,保證數(shù)據(jù)是高位在前

  

360桌面截圖20150107141144.jpg

 

  然后再將數(shù)據(jù)并行輸出即可,下面附上仿真波形,我在testbench中給串入信號(hào)設(shè)為隨機(jī)數(shù),看仿真圖的,第一串信號(hào)為1101_1011,一位一位的移進(jìn)寄存器可以由波形的,分別是1,3,6……所以我們的代碼是正確的

  

360桌面截圖20150106213842.jpg

 

  三、流水線操作

  流水線操作是高速設(shè)計(jì)中的一種常用手段,如果摸個(gè)設(shè)計(jì)的處理流程分為若干個(gè)步驟,而且數(shù)據(jù)處理是單向流的,也就是沒(méi)有反饋或者迭代運(yùn)算,前一個(gè)步驟是后一個(gè)步驟的輸出,我們就可以采用流水線設(shè)計(jì)的方法來(lái)提高設(shè)計(jì)速率。

  舉個(gè)例子,假如我們要計(jì)算A+B+C的值,如果不用流水線操作的話,那么需要先計(jì)算A+B的值,再計(jì)算A+B+C的值,需要兩個(gè)時(shí)鐘周期,如果我用了流水線操作那么我需要在兩個(gè)always塊中分別計(jì)算sum1= A+B,sum2= sum1+C,由于兩個(gè)always塊是并行的,輸出數(shù)據(jù)只需要等待一個(gè)時(shí)鐘周期,以后就可以有數(shù)據(jù)源源不斷的輸出,就像流水線一樣,從而提高系統(tǒng)速率

  下面我們來(lái)設(shè)計(jì)一個(gè)實(shí)例,假如我要采集一系列的32位數(shù)據(jù),要對(duì)它進(jìn)行處理,處理方式假如是,先對(duì)這個(gè)數(shù)據(jù)進(jìn)行加16運(yùn)算,再進(jìn)行壓縮為16位數(shù)據(jù)運(yùn)算,再進(jìn)行減10運(yùn)算

  ,最后進(jìn)行取低8位運(yùn)算,采用流水線設(shè)計(jì)的話,輸出結(jié)果只需要等待幾個(gè)時(shí)鐘周期,以后就會(huì)有源源不斷地?cái)?shù)據(jù)輸出,流程框圖如下,代碼請(qǐng)?jiān)诤竺嫦螺d

  

360桌面截圖20150107122947.jpg

 

  我在testbench中定義輸入信號(hào)是隨機(jī)的32位信號(hào),分別進(jìn)行分級(jí)處理,每處理完一級(jí)要給下一級(jí)發(fā)使能信號(hào),并把數(shù)據(jù)送到下一級(jí),例如當(dāng)?shù)谝患?jí)使能信號(hào)到來(lái)時(shí),數(shù)據(jù)為29,29加16為45,即第一級(jí)輸出信號(hào),對(duì)45取前16位仍為45,45減10為35,35取低8位仍為35,對(duì)照波形,證明我們的設(shè)計(jì)是對(duì)的

  

360桌面截圖20150107122821.jpg

 

  四、跨時(shí)鐘域信號(hào)同步

  先來(lái)看一張圖

  

360桌面截圖20150107144544.jpg

 

  這個(gè)圖的意思就是,脈沖信號(hào)為一個(gè)時(shí)鐘信號(hào),要對(duì)其進(jìn)行計(jì)數(shù),在CPU給FPGA發(fā)送讀信號(hào)的時(shí)候,將計(jì)數(shù)器的值送至CPU的數(shù)據(jù)總線, 這里就涉及三個(gè)時(shí)鐘信號(hào),一個(gè)脈沖信號(hào),一個(gè)CPU的讀信號(hào),一個(gè)FPGA的自身時(shí)鐘,這三個(gè)時(shí)鐘是不同步的,我們這樣想,假如在脈沖計(jì)數(shù)的時(shí)鐘,cnt是自加1的,由于三個(gè)時(shí)鐘不同步,CPU的讀信號(hào)隨時(shí)都有可能來(lái),加入當(dāng)cnt自加的時(shí)候,也就是cnt = cnt +1,這是對(duì)cnt的寫(xiě)狀態(tài),突然來(lái)一個(gè)CPU的讀信號(hào),即那么就要把cnt送到數(shù)據(jù)總線,即data < = cnt,這是一個(gè)讀狀態(tài),試問(wèn),一個(gè)數(shù)據(jù)既要讀又要寫(xiě),那讀的是寫(xiě)之前的數(shù)據(jù)呢還是寫(xiě)之后的數(shù)據(jù)呢?這就是亞穩(wěn)態(tài),確切就是不確定的意思,所以,我們要將不同的時(shí)鐘盡心同步處理,即在一個(gè)時(shí)鐘的控制下進(jìn)行脈沖計(jì)數(shù)和讀操作,這樣就不會(huì)發(fā)生亞穩(wěn)態(tài)了,要知道,在一個(gè)大的系統(tǒng)中,亞穩(wěn)態(tài)的危害是很大的

  

360桌面截圖20150107145637.jpg

 

  要解決同步問(wèn)題,我們可以用FIFO,DPRAM 進(jìn)行同步,即用其他時(shí)鐘域?qū)ifo進(jìn)行寫(xiě)操作,再用FPGA對(duì)fifo進(jìn)行讀操作,但要注意是否有數(shù)據(jù)溢出,還有一種方法就是邊沿脈沖檢測(cè)法,這里我們講第二種

  

360桌面截圖20150107145722.jpg

 

  即采用兩級(jí)寄存器,這兩級(jí)寄存器均有FPGA的時(shí)鐘控制,具體操作就是將不同域的信號(hào)都先賦值給第一級(jí)寄存器,再在另一個(gè)always塊中把第一級(jí)寄存器的值賦給第二級(jí)寄存器,如果是信號(hào)是高脈沖,那么就把第二級(jí)寄存器取反與第一級(jí)寄存器相與,便會(huì)得到一個(gè)高的脈沖采樣信號(hào),用這個(gè)信號(hào)在檢測(cè)其他域信號(hào)的到來(lái),如果是信號(hào)是低脈沖,那么就把第一級(jí)寄存器取反與第二級(jí)寄存器相與,同樣得到一個(gè)高的脈沖采樣信號(hào),用這個(gè)信號(hào)在檢測(cè)其他域信號(hào)的到來(lái),小墨同學(xué)把它記為“上2下1”原則,方便記憶~

  具體代碼在前面鍵盤(pán)部分已經(jīng)有所講解,這里就不副代碼了

  寫(xiě)了好幾個(gè)小時(shí),手都敲酸了,還望各位大神多多指教,有什么講的不對(duì)的地方還請(qǐng)指出,一起進(jìn)步~

fpga相關(guān)文章:fpga是什么


塵埃粒子計(jì)數(shù)器相關(guān)文章:塵埃粒子計(jì)數(shù)器原理
脈沖點(diǎn)火器相關(guān)文章:脈沖點(diǎn)火器原理


評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉