新聞中心

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

零基礎學FPGA (十八) 談可編程邏輯設計思想與技巧!對您肯定有用!

—— 零基礎學FPGA (二十) 談可編程邏輯設計思想與技巧!對您肯定有用!
作者: 時間:2015-05-08 來源:網絡 收藏

  今天給大家?guī)淼氖俏覀冊?a class="contentlabel" href="http://butianyuan.cn/news/listbylabel/label/FPGA">FPGA設計中經常要遇到的設計技巧與思想,即乒乓操作,串并轉換,流水線操作和跨時鐘域信號的同步問題。

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

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

  一、乒乓操作

  乒乓操作主要用于數據流的處理,是用面積換取速度的體現之一,要知道面積與速度的互換貫穿設計的始終,下面先給一個框圖

  

360桌面截圖20150107131605.jpg

 

  我先來解釋一下乒乓操作的過程:

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

  小墨同學發(fā)現,在給這個框圖配實例的時候,幾乎所有的網站都是這個解釋,我用紅字標出,個人感覺解釋的不怎么樣,還有些地方是錯的

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

  A 端口處輸入數據流速率為 100Mbps ,在第 1 個緩沖周期 10ms 內,通過 “ 輸入數據選擇單元 ” ,從 B1 到達 DPRAM1 。 B1 的數據速率也是 100Mbps , DPRAM1 要在 10ms 內寫入 1Mb 數據。同理,在第 2 個 10ms ,數據流被切換到 DPRAM2 ,端口 B2 的數據速率也是 100Mbps , DPRAM2 在第 2 個 10ms 被寫入 1Mb 數據。在第 3 個 10ms ,數據流又切換到 DPRAM1 , DPRAM1 被寫入 1Mb 數據。

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

  雖然各個網站上都是這么解釋的,但是個人感覺解釋的不怎么樣,下面我用我自己的理解給大家解釋一下這個例子

  先看我給大家畫的一個圖,雖然畫的不怎么樣

  

360桌面截圖20150107133820.jpg

 

  這里我們只計算緩存模塊1的速率

  首先看第一個周期10ms,數據流往緩存模塊1里面寫數據,到第5ms時,預處理模塊1開始從緩存模塊1里面讀數據,到10ms時,緩存模塊1寫了1M數據,讀了5K數據,下面切換到第二個周期,由于在第二個周期的時候預處理模塊1還可以從緩存模塊1里面讀數據,所以到第15ms時,緩存模塊1里面的數據被讀完

  

360桌面截圖20150107134724.jpg

 

  到了第三個時鐘周期,也就是從第20ms開始數據流往緩存模塊1寫數據,到第25ms時,預處理模塊開始從緩存模塊讀數據,直到35ms時才讀完,這樣我們來算一下,在第一個時鐘周期讀了5K數據,注意我上面畫的時鐘周期數,就是那個半圓形的,

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

  下面再給大家講一個實例,具體代碼我會附在文章后面

  

360桌面截圖20150107140510.jpg

 

  用state來控制乒乓操作的來回切換

  

360桌面截圖20150107140642.jpg

 

  根據剛才講的,控制緩存器的讀寫,這里只列些部分代碼,具體代碼請大家在文章后面下載

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

  

360桌面截圖20150101215834.jpg

 

  二、串并轉換

  串并轉換總的來說就是將串行輸入信號轉換為并行輸出,也是用面積換取速度的一種方法,串并轉換總的來說比較簡單,小墨就只給大家講一下我自己寫的代碼吧

  首先要先對串入信號進行采集,加入我們是8位一輸出,每進來一位數據,我們便將原數據左移一位,保證數據是高位在前

  

360桌面截圖20150107141144.jpg

 

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

  

360桌面截圖20150106213842.jpg

 

  三、流水線操作

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

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

  下面我們來設計一個實例,假如我要采集一系列的32位數據,要對它進行處理,處理方式假如是,先對這個數據進行加16運算,再進行壓縮為16位數據運算,再進行減10運算

  ,最后進行取低8位運算,采用流水線設計的話,輸出結果只需要等待幾個時鐘周期,以后就會有源源不斷地數據輸出,流程框圖如下,代碼請在后面下載

  

360桌面截圖20150107122947.jpg

 

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

  

360桌面截圖20150107122821.jpg

 

  四、跨時鐘域信號同步

  先來看一張圖

  

360桌面截圖20150107144544.jpg

 

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

  

360桌面截圖20150107145637.jpg

 

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

  

360桌面截圖20150107145722.jpg

 

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

  具體代碼在前面鍵盤部分已經有所講解,這里就不副代碼了

  寫了好幾個小時,手都敲酸了,還望各位大神多多指教,有什么講的不對的地方還請指出,一起進步~

fpga相關文章:fpga是什么


塵埃粒子計數器相關文章:塵埃粒子計數器原理
脈沖點火器相關文章:脈沖點火器原理


評論


相關推薦

技術專區(qū)

關閉