零基礎學(xué)FPGA (十八) 談可編程邏輯設計思想與技巧!對您肯定有用!
今天給大家帶來(lái)的是我們在FPGA設計中經(jīng)常要遇到的設計技巧與思想,即乒乓操作,串并轉換,流水線(xiàn)操作和跨時(shí)鐘域信號的同步問(wèn)題。
本文引用地址:http://dyxdggzs.com/article/273855.htm之前也看過(guò)一些書(shū),也在網(wǎng)上找過(guò)一些資料,不過(guò)小墨發(fā)現大部分都是理論講解,僅僅是給一個(gè)框圖就沒(méi)事了,或者是好幾個(gè)網(wǎng)站的資料都是一樣的,都是復制的一個(gè)地方的,僅僅是講解,沒(méi)有實(shí)例,要不就是某個(gè)網(wǎng)站提供源碼,但是要注冊,還要花什么積分,沒(méi)有積分還得要錢(qián)...很不利于初學(xué)者的學(xué)習(人與人之間怎么就不能多點(diǎn)信任呢~還要錢(qián)...)。所以小墨想寫(xiě)這么一篇文章來(lái)介紹一下這4種思想,理論部分書(shū)上多得是,我就不過(guò)多的解釋?zhuān)饕o大家講一些實(shí)例型的幫大家理解。
一、乒乓操作
乒乓操作主要用于數據流的處理,是用面積換取速度的體現之一,要知道面積與速度的互換貫穿FPGA設計的始終,下面先給一個(gè)框圖

我先來(lái)解釋一下乒乓操作的過(guò)程:
首先數據需要通過(guò)一個(gè)2選一數據選擇器,在第一個(gè)時(shí)鐘周期將數據緩存到緩存模塊1,常用的緩存模塊可以是fifo,雙口RAM(DPRAM),單口RAM(SPRAM),第二個(gè)時(shí)鐘周期的時(shí)候,數據流開(kāi)始往緩存模塊2里面寫(xiě)數據,與此同時(shí),預處理模塊會(huì )從緩存模塊1里面讀取數據,到了第三個(gè)時(shí)鐘周期數據流再往緩存模塊1里面寫(xiě)數據,與此同時(shí),預處理模塊2開(kāi)始從緩存模塊2讀取數據,周而復始...這樣,輸入數據流和輸出數據流按節拍來(lái)回切換,可以使數據沒(méi)有停頓的進(jìn)行傳輸,使傳輸速率大大提高。
小墨同學(xué)發(fā)現,在給這個(gè)框圖配實(shí)例的時(shí)候,幾乎所有的網(wǎng)站都是這個(gè)解釋?zhuān)矣眉t字標出,個(gè)人感覺(jué)解釋的不怎么樣,還有些地方是錯的
假設端口 A 的輸入數據流的速率為 100Mbps ,乒乓操作的緩沖周期是 10ms 。以下分析各個(gè)節點(diǎn)端口的數據速率。
A 端口處輸入數據流速率為 100Mbps ,在第 1 個(gè)緩沖周期 10ms 內,通過(guò) “ 輸入數據選擇單元 ” ,從 B1 到達 DPRAM1 。 B1 的數據速率也是 100Mbps , DPRAM1 要在 10ms 內寫(xiě)入 1Mb 數據。同理,在第 2 個(gè) 10ms ,數據流被切換到 DPRAM2 ,端口 B2 的數據速率也是 100Mbps , DPRAM2 在第 2 個(gè) 10ms 被寫(xiě)入 1Mb 數據。在第 3 個(gè) 10ms ,數據流又切換到 DPRAM1 , DPRAM1 被寫(xiě)入 1Mb 數據。
仔細分析就會(huì )發(fā)現到第 3 個(gè)緩沖周期時(shí),留給 DPRAM1 讀取數據并送到 “ 數據預處理模塊 1” 的時(shí)間一共是 20ms 。有的工程師困惑于 DPRAM1 的讀數時(shí)間為什么是 20ms ,這個(gè)時(shí)間是這樣得來(lái)的:首先,在在第 2 個(gè)緩沖周期向 DPRAM2 寫(xiě)數據的 10ms 內, DPRAM1 可以進(jìn)行讀操作;另外,在第 1 個(gè)緩沖周期的第 5ms 起 ( 絕對時(shí)間為 5ms 時(shí)刻 ) , DPRAM1 就可以一邊向 500K 以后的地址寫(xiě)數據,一邊從地址 0 讀數,到達 10ms 時(shí), DPRAM1 剛好寫(xiě)完了 1Mb 數據,并且讀了 500K 數據,這個(gè)緩沖時(shí)間內 DPRAM1 讀了 5ms ;在第 3 個(gè)緩沖周期的第 5ms 起 ( 絕對時(shí)間為 35ms 時(shí)刻 ) ,同理可以一邊向 500K 以后的地址寫(xiě)數據一邊從地址 0 讀數,又讀取了 5 個(gè) ms ,所以截止 DPRAM1 第一個(gè)周期存入的數據被完全覆蓋以前, DPRAM1 最多可以讀取 20ms 時(shí)間,而所需讀取的數據為 1Mb ,所以端口 C1 的數據速率為: 1Mb/20ms=50Mbps 。因此, “ 數據預處理模塊 1” 的最低數據吞吐能力也僅僅要求為 50Mbps 。同理, “ 數據預處理模塊 2” 的最低數據吞吐能力也僅僅要求為 50Mbps 。換言之,通過(guò)乒乓操作, “ 數據預處理模塊 ” 的時(shí)序壓力減輕了,所要求的數據處理速率僅僅為輸入數據速率的 1/2 。
雖然各個(gè)網(wǎng)站上都是這么解釋的,但是個(gè)人感覺(jué)解釋的不怎么樣,下面我用我自己的理解給大家解釋一下這個(gè)例子
先看我給大家畫(huà)的一個(gè)圖,雖然畫(huà)的不怎么樣

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

到了第三個(gè)時(shí)鐘周期,也就是從第20ms開(kāi)始數據流往緩存模塊1寫(xiě)數據,到第25ms時(shí),預處理模塊開(kāi)始從緩存模塊讀數據,直到35ms時(shí)才讀完,這樣我們來(lái)算一下,在第一個(gè)時(shí)鐘周期讀了5K數據,注意我上面畫(huà)的時(shí)鐘周期數,就是那個(gè)半圓形的,
在第三個(gè)時(shí)鐘周期讀了5k數據,注意每個(gè)時(shí)鐘周期只有5K,另外5K到了下一個(gè)時(shí)鐘周期了,所以我們不考慮,我們只考慮緩存模塊1的速率。再看一下時(shí)間,從第10ms讀完第一個(gè)5K,到第30ms讀完第2個(gè)5k,共用了20ms,讀了1M數據,所以速率為1M/20ms=50M/s。
下面再給大家講一個(gè)實(shí)例,具體代碼我會(huì )附在文章后面

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

根據剛才講的,控制緩存器的讀寫(xiě),這里只列些部分代碼,具體代碼請大家在文章后面下載
下面附上仿真時(shí)序圖,我在testbench中將數據設為從0 遞增的,可以看到仿真波形中是將奇偶數分開(kāi)的,證明我們代碼是正確的

二、串并轉換
串并轉換總的來(lái)說(shuō)就是將串行輸入信號轉換為并行輸出,也是用面積換取速度的一種方法,串并轉換總的來(lái)說(shuō)比較簡(jiǎn)單,小墨就只給大家講一下我自己寫(xiě)的代碼吧
首先要先對串入信號進(jìn)行采集,加入我們是8位一輸出,每進(jìn)來(lái)一位數據,我們便將原數據左移一位,保證數據是高位在前

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

三、流水線(xiàn)操作
流水線(xiàn)操作是高速設計中的一種常用手段,如果摸個(gè)設計的處理流程分為若干個(gè)步驟,而且數據處理是單向流的,也就是沒(méi)有反饋或者迭代運算,前一個(gè)步驟是后一個(gè)步驟的輸出,我們就可以采用流水線(xiàn)設計的方法來(lái)提高設計速率。
舉個(gè)例子,假如我們要計算A+B+C的值,如果不用流水線(xiàn)操作的話(huà),那么需要先計算A+B的值,再計算A+B+C的值,需要兩個(gè)時(shí)鐘周期,如果我用了流水線(xiàn)操作那么我需要在兩個(gè)always塊中分別計算sum1= A+B,sum2= sum1+C,由于兩個(gè)always塊是并行的,輸出數據只需要等待一個(gè)時(shí)鐘周期,以后就可以有數據源源不斷的輸出,就像流水線(xiàn)一樣,從而提高系統速率
下面我們來(lái)設計一個(gè)實(shí)例,假如我要采集一系列的32位數據,要對它進(jìn)行處理,處理方式假如是,先對這個(gè)數據進(jìn)行加16運算,再進(jìn)行壓縮為16位數據運算,再進(jìn)行減10運算
,最后進(jìn)行取低8位運算,采用流水線(xiàn)設計的話(huà),輸出結果只需要等待幾個(gè)時(shí)鐘周期,以后就會(huì )有源源不斷地數據輸出,流程框圖如下,代碼請在后面下載

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

四、跨時(shí)鐘域信號同步
先來(lái)看一張圖

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

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

即采用兩級寄存器,這兩級寄存器均有FPGA的時(shí)鐘控制,具體操作就是將不同域的信號都先賦值給第一級寄存器,再在另一個(gè)always塊中把第一級寄存器的值賦給第二級寄存器,如果是信號是高脈沖,那么就把第二級寄存器取反與第一級寄存器相與,便會(huì )得到一個(gè)高的脈沖采樣信號,用這個(gè)信號在檢測其他域信號的到來(lái),如果是信號是低脈沖,那么就把第一級寄存器取反與第二級寄存器相與,同樣得到一個(gè)高的脈沖采樣信號,用這個(gè)信號在檢測其他域信號的到來(lái),小墨同學(xué)把它記為“上2下1”原則,方便記憶~
具體代碼在前面鍵盤(pán)部分已經(jīng)有所講解,這里就不副代碼了
寫(xiě)了好幾個(gè)小時(shí),手都敲酸了,還望各位大神多多指教,有什么講的不對的地方還請指出,一起進(jìn)步~
fpga相關(guān)文章:fpga是什么
塵埃粒子計數器相關(guān)文章:塵埃粒子計數器原理 脈沖點(diǎn)火器相關(guān)文章:脈沖點(diǎn)火器原理
評論