流水線設(shè)計(jì)
基本概念
流水線處理源自現(xiàn)代工業(yè)生產(chǎn)裝配線上的流水作業(yè),是指將待處理的任務(wù)分解為相對(duì)獨(dú)立的,、可以順序執(zhí)行的而又相互關(guān)聯(lián)的一個(gè)個(gè)子任務(wù),。流水線處理是高速設(shè)計(jì)中的一個(gè)常用設(shè)計(jì)手段,如果某個(gè)設(shè)計(jì)的處理流程分為若干步驟,,并且整個(gè)數(shù)據(jù)處理是“單流向”的,,即沒有反饋或者迭代運(yùn)算,前一個(gè)步驟的輸出是下一個(gè)步驟的輸入,,那么可以考慮采用流水線設(shè)計(jì)方法來提高系統(tǒng)頻率,。流水線設(shè)計(jì)結(jié)構(gòu)如圖所示。
其基本結(jié)構(gòu)是將適當(dāng)劃分的n個(gè)操作步驟單流向串聯(lián)起來。流水線操作的最大特點(diǎn)是數(shù)據(jù)流在各個(gè)步驟的處理從時(shí)間上看是連續(xù)的順序操作,,與此同時(shí)各個(gè)步驟又是同時(shí)并行的在運(yùn)作,。
在處理器架構(gòu)上,一個(gè)單核處理器只能一次處理一個(gè)任務(wù),,是順序的執(zhí)行,,如要實(shí)現(xiàn)并行操作需要多個(gè)處理器來執(zhí)行。
FPGA中典型的流水線設(shè)計(jì)
流水線處理采用面積換取速度的思想,,可以大大提高電路的工作頻率,,尤其對(duì)于圖像處理任務(wù)中的二維卷積運(yùn)算、FIR及FFT濾波器等,,采用流水線設(shè)計(jì)可以保證一個(gè)時(shí)鐘輸出一個(gè)像素,,相對(duì)于全并行處理電路占用資源又不會(huì)太多。對(duì)于大部分的圖像處理任務(wù)而言,,處理過程基本上也是一個(gè)“串行”的處理思路,。因此,流水線設(shè)計(jì)無疑是最好的設(shè)計(jì)方式,。如下圖所示是一個(gè)典型的圖像處理任務(wù)流程圖,。
并行陣列
在并行陣列型電路中,多組并行排列的子電路同時(shí)接收整體數(shù)據(jù)的多個(gè)部分進(jìn)行并行計(jì)算,。并行陣列型電路中的子電路本身可以是簡(jiǎn)單的組合電路,,也可以是復(fù)雜的時(shí)序電路例如上面提到的流水線型電路。如果受邏輯資源限制,,無法同時(shí)處理全部數(shù)據(jù),,那么也可以依次處理部分?jǐn)?shù)據(jù)直到完成全部數(shù)據(jù)的處理。
和流水線共享電路的思路不同,,并行陣列電路對(duì)于每個(gè)處理數(shù)據(jù)都生成一個(gè)處理電路,,這無疑更大地提高了電路的處理速度,但是也帶來了更大的資源消耗,,是用面積換取速度原則的又一體現(xiàn)。如果系統(tǒng)設(shè)計(jì)對(duì)資源消耗相對(duì)不敏感,,但是又需要較快的處理速度時(shí),,那么我們會(huì)選擇并行結(jié)構(gòu)來完成。
并行陣列的一個(gè)典型應(yīng)用是多通道像素同時(shí)進(jìn)行處理,,對(duì)一個(gè)串行輸入的RGB通道或是YCbCr通道的視頻流,,首先做一個(gè)串并轉(zhuǎn)換,接著復(fù)制處理邏輯對(duì)三個(gè)通道同時(shí)做處理,。這樣理論上可以得到3倍的速度提升,。
計(jì)算技術(shù)
計(jì)算技術(shù)也是圖像處理的核心技術(shù)之一。在軟件算法設(shè)計(jì)和調(diào)試完成之后,需要將軟件的算法映射到FPGA中去,,由于軟件和硬件的設(shè)計(jì)差異性,,相當(dāng)一部分算法在映射前需要通過等效轉(zhuǎn)換,近似計(jì)算等硬件計(jì)算技術(shù)來轉(zhuǎn)換成硬件易于實(shí)現(xiàn)的方式,,從而達(dá)到邏輯資源消耗和時(shí)序,,以及誤差與消耗的平衡。本節(jié)將介紹幾種常用的硬件計(jì)算技術(shù),。
算法轉(zhuǎn)換
在乘法和除法運(yùn)算中,,經(jīng)常會(huì)遇到乘數(shù)、被乘數(shù)或分子與分母是常數(shù)的情況,。直接調(diào)用乘法器或除法器當(dāng)然可以解決這個(gè)問題,,但是這會(huì)消耗一定的DSP運(yùn)算單元,而DSP單元往往是FPGA里面比較少的資源,。對(duì)于定常數(shù),,可以通過一定的轉(zhuǎn)換將其轉(zhuǎn)換為移位和加法運(yùn)算,從而減少乘法器和除法器的使用,。下面列舉幾個(gè)常用的例子,。
乘法運(yùn)算的實(shí)現(xiàn):
dout = din × 255
轉(zhuǎn)換后:
dout = din ×(256-1)=(din《8)-din
除法運(yùn)算的實(shí)現(xiàn):
在這里擴(kuò)展了10bit的位寬,這個(gè)位寬約大,,精度約高,,但也會(huì)消耗相對(duì)更多的資源,實(shí)際應(yīng)用中根據(jù)精度需求進(jìn)行選擇,。
近似計(jì)算
與算法轉(zhuǎn)換不同的是,,算法轉(zhuǎn)換是不會(huì)帶來任何原理的誤差,而近似則會(huì)帶來一定的計(jì)算誤差,。通常情況下,,在誤差允許的范圍內(nèi),采用近似計(jì)算帶來的明顯優(yōu)勢(shì)是計(jì)算復(fù)雜度的降低及資源消耗的降低,。在FPGA中常見的近似計(jì)算是截?cái)唷?/p>
截?cái)嗑褪怯梦粩?shù)較少的近似值來代替位數(shù)較多或無限位數(shù)的數(shù)時(shí),,要有一定的取舍法則。在數(shù)值計(jì)算中,,為了適應(yīng)各種不同的情況,,須采用不同的截取方法。
經(jīng)常使用的截?cái)喾椒ň褪撬纳嵛迦?。?shí)際上,,對(duì)于FPGA來講,處理的都是二進(jìn)制數(shù)據(jù),。因此,,在小數(shù)位的第一位的值是0還是1決定了是否對(duì)結(jié)果進(jìn)行進(jìn)位。
同樣,以除法的例子為例:
將位寬擴(kuò)展10bit后,,再進(jìn)行近似運(yùn)算,,近似運(yùn)算直接去掉了小數(shù)部分,引入的誤差僅為0.04/210,。如果din是圖像中的一個(gè)像素,,其最大值為256,誤差僅為0.01,,該近似運(yùn)算幾乎不影響圖像像素,。相對(duì)無損失的運(yùn)算轉(zhuǎn)換,大大減輕了運(yùn)算量,。
增量更新
增量更新是指在進(jìn)行更新操作時(shí),,只更新需要改變的地方,不需要更新或者已經(jīng)更新過的地方則不會(huì)重復(fù)更新,,增量更新與完全更新相對(duì),。增量更新在流水線處理中,特別是二維卷積處理中特別有用,。這是由于在兩個(gè)連續(xù)的卷積窗口中有大量的相同元素,。
假定要計(jì)算連續(xù)5個(gè)數(shù)據(jù)流的和,在上一個(gè)時(shí)刻,,這5個(gè)待計(jì)算的數(shù)值是a0,a1,a2,a3,a4, 在本時(shí)刻待計(jì)算的數(shù)值是a1,a2,a3,a4,a5,。中間有4個(gè)值是相同元素。如此如果每次計(jì)算都將5個(gè)數(shù)重新相加,,就有點(diǎn)浪費(fèi)資源,。正確的做法是加上一個(gè)新值,再減去一個(gè)最老的值,。
對(duì)應(yīng)的增量計(jì)算方法如下圖所示,,當(dāng)然5個(gè)數(shù)值求和,可以擴(kuò)展到10個(gè)數(shù)值求和,,但增量運(yùn)算的運(yùn)算量不變:
浮點(diǎn)計(jì)算
大部分運(yùn)算可以通過擴(kuò)位和近似的方式轉(zhuǎn)換為定點(diǎn)運(yùn)算,。但有些算法在設(shè)計(jì)在設(shè)計(jì)的過程中就涉及大量的浮點(diǎn)運(yùn)算,在轉(zhuǎn)換為定點(diǎn)運(yùn)算時(shí)比較麻煩,,會(huì)帶來龐大的工作量,。此外,在某些應(yīng)用中,,定點(diǎn)算法是不可行的,,動(dòng)態(tài)范圍要求使用浮點(diǎn)算法的一個(gè)常見的例子是矩陣求逆運(yùn)算,。本節(jié)將介紹如何使用FPGA來實(shí)現(xiàn)浮點(diǎn)運(yùn)算以便減少移植的工作量,。
浮點(diǎn)數(shù)的定義
浮點(diǎn)數(shù)(float)是屬于有理數(shù)中某特定子集的數(shù)的數(shù)字表示,在計(jì)算機(jī)中用以近似表示任意某個(gè)實(shí)數(shù)。具體來說,,這個(gè)實(shí)數(shù)由一個(gè)整數(shù)或定點(diǎn)數(shù)(即尾數(shù))乘以某個(gè)基數(shù)(計(jì)算機(jī)中通常是2)的整數(shù)次冪得到,,這種表示方法類似于基數(shù)為10的科學(xué)記數(shù)法。
IEEE二進(jìn)制浮點(diǎn)數(shù)算術(shù)標(biāo)準(zhǔn)(IEEE 754)是20世紀(jì)80年代以來最廣泛使用的浮點(diǎn)數(shù)運(yùn)算標(biāo)準(zhǔn),,為許多CPU與浮點(diǎn)運(yùn)算器所采用,。這個(gè)標(biāo)準(zhǔn)定義了表示浮點(diǎn)數(shù)的格式(包括負(fù)零-0)與反常值(denormal number)),一些特殊數(shù)值(無窮(Inf)與非數(shù)值(NaN)),,以及這些數(shù)值的“浮點(diǎn)數(shù)運(yùn)算符”,;它也指明了四種數(shù)值舍入規(guī)則和五種例外狀況(包括例外發(fā)生的時(shí)機(jī)與處理方式)。
IEEE 754規(guī)定了四種表示浮點(diǎn)數(shù)值的方式:?jiǎn)尉_度(32位),、雙精確度(64位),、延伸單精確度(43比特以上,很少使用)與延伸雙精確度(79比特以上,,通常以80位實(shí)現(xiàn)),。只有32位模式有強(qiáng)制要求,其他都是選擇性的,。大部分編程語言都有提供IEEE浮點(diǎn)數(shù)格式與算術(shù),,但有些將其列為非必需的。例如,,IEEE 754在問世之前就有的C語言,,現(xiàn)在有包括IEEE算術(shù),但不算作強(qiáng)制要求(C語言的float通常是指IEEE單精確度,,而double是指雙精確度),。
1)單精度浮點(diǎn)數(shù)
單精度浮點(diǎn)數(shù)用32位二進(jìn)制表示,其中最高位Bit[31],MSB為符號(hào)位,,即sign域,。Bit[30:23]為exponent域,這8位數(shù)據(jù)表示指數(shù),;最低的23位Bit[22:0]為fracTIon域,,用于表示浮點(diǎn)數(shù)的小數(shù)部分。
2)雙精度浮點(diǎn)數(shù)
單精度浮點(diǎn)數(shù)用64位二進(jìn)制表示,,其中最高位Bit[63],MSB為符號(hào)位,,即sign域。Bit[62:52]為exponent域,,這11位數(shù)據(jù)表示指數(shù),;最低的52位Bit[51:0]為fracTIon域,用于表示浮點(diǎn)數(shù)的小數(shù)部分
用FPGA實(shí)現(xiàn)浮點(diǎn)運(yùn)算
乘法:對(duì)于乘法運(yùn)算,、位數(shù)相乘及指數(shù)相加,,若位數(shù)結(jié)果大于2,,則需要重新規(guī)范化,將其右移一位并且增加指數(shù),。由于乘積的位數(shù)可能會(huì)比表示位多,,因此,需要進(jìn)行舍位處理,。兩個(gè)指數(shù)的和包括兩個(gè)偏移量,,因此必須減掉一個(gè)。輸出值的符號(hào)位是輸入符號(hào)位的異或,。需要附加的邏輯來檢測(cè)下溢出,、上移除及處理其他的錯(cuò)誤情況,例如,,處理無窮大和非數(shù),。
除法:除法與懲罰類似,只是尾數(shù)相除,,指數(shù)相減并且在重新規(guī)范化時(shí)可能包含左移,。
加法和減法:實(shí)現(xiàn)要更加復(fù)雜。與原碼表示相同,,實(shí)際操作的執(zhí)行取決于輸入的符號(hào),。指數(shù)必須相同,因?yàn)閿?shù)必須要對(duì)齊,。根據(jù)指數(shù)位的差值,,將較小的指數(shù)右移相應(yīng)的位數(shù)。
浮點(diǎn)操作相對(duì)于定點(diǎn)操作無疑要消耗更多的資源,,這不是因?yàn)楦↑c(diǎn)操作有多復(fù)雜,,而是因?yàn)樘幚懋惓r(shí)需要很多邏輯,尤其是在需要符合IEEE標(biāo)準(zhǔn)時(shí),。大部分FPGA在進(jìn)行浮點(diǎn)運(yùn)算時(shí),,為符合IEEE 754標(biāo)準(zhǔn),每次運(yùn)算都需要去歸一化和歸一化步驟,,導(dǎo)致了極大的性能瓶頸,。因?yàn)檫@些歸一化和去歸一化步驟一般通過FPGA中的大規(guī)模桶形移位寄存器實(shí)現(xiàn),需要大量的邏輯和布線資源,。通常一個(gè)單精度浮點(diǎn)加法器需要500個(gè)查找表(LUT),,單精度浮點(diǎn)要占用30%的LUT,指數(shù)和自然對(duì)數(shù)等更復(fù)雜的數(shù)學(xué)函數(shù)需要大約1000個(gè)LUT,。因此,,隨著DSP算法越來越復(fù)雜,F(xiàn)PGA性能會(huì)明顯劣化,,對(duì)占用80%~90%邏輯資源的FPGA會(huì)造成嚴(yán)重的布線擁塞,,阻礙FPGA的快速互連,,最終會(huì)影響時(shí)序收斂。
存儲(chǔ)器映射
一般情況下,,我們希望當(dāng)數(shù)據(jù)流過FPGA時(shí),F(xiàn)PGA盡可能多地處理數(shù)據(jù),,并且減少FPGA和外部設(shè)備之間的數(shù)據(jù)傳輸,,采用流水線處理架構(gòu)則可以很好地減少對(duì)存儲(chǔ)器的頻繁讀寫。然而在某些情況下,,一個(gè)圖像處理算法需要像素之間的行列同步或是幀同步,,這個(gè)時(shí)候就必須要緩存部分圖像或者是整幅圖像。
在軟件處理中,,這個(gè)緩存通常情況下是放在內(nèi)存中,,需要的時(shí)候從內(nèi)存進(jìn)行讀取。在FPGA中,,可以選擇將緩存放在FPGA內(nèi)部或者外部,。
幀緩存
對(duì)于幀緩存,通常情況下會(huì)將其放在片外進(jìn)行讀寫,。對(duì)于幀緩存,,在成本不夠敏感的情況下,最好使用靜態(tài)存儲(chǔ)器(SRAM),,尤其是用于需要頻繁和隨機(jī)地訪問這些幀緩存的地方,。
靜態(tài)存儲(chǔ)器:相對(duì)于動(dòng)態(tài)存儲(chǔ)器來說,通常情況下讀寫接口時(shí)序相對(duì)簡(jiǎn)單,,讀寫速度要快,,并且功耗相對(duì)較低。但是,,由于靜態(tài)存儲(chǔ)器每一位要使用6個(gè)晶體管,,而動(dòng)態(tài)存儲(chǔ)器每位只使用一個(gè)晶體管,因此靜態(tài)存儲(chǔ)器的價(jià)格要貴得多,。這也限制了它在成本敏感場(chǎng)合的應(yīng)用,。
一個(gè)幀緩存控制電路要包括讀地址發(fā)生器、寫地址發(fā)生器及讀寫控制時(shí)序,。一般情況下,,這個(gè)寫地址即為輸入幀數(shù)據(jù)流ImageDin的行列地址,而讀地址為輸出流Frame_buffer的行列地址,。以SRAM為基礎(chǔ)的幀緩存電路如圖所示,。
動(dòng)態(tài)存儲(chǔ)器:如果系統(tǒng)對(duì)于讀取速度沒有嚴(yán)格要求的緩存應(yīng)用,那么動(dòng)態(tài)存儲(chǔ)器無疑是更好的選擇,。雖然動(dòng)態(tài)存儲(chǔ)器存取速度較慢,,從主機(jī)提供地址到數(shù)據(jù)輸出可能需要若干個(gè)時(shí)鐘,,但是當(dāng)動(dòng)態(tài)存儲(chǔ)器工作在突發(fā)模式時(shí),也可以提供較大的帶寬,,這對(duì)于圖像處理這樣的大數(shù)據(jù)應(yīng)用場(chǎng)合非常有用,。
動(dòng)態(tài)存儲(chǔ)器的接口設(shè)計(jì)相對(duì)比較復(fù)雜,這是由于動(dòng)態(tài)存儲(chǔ)器必須要間隔一段時(shí)間對(duì)其進(jìn)行刷新來保持當(dāng)前的存儲(chǔ)器內(nèi)容,。此外,,與靜態(tài)存儲(chǔ)器不同,動(dòng)態(tài)存儲(chǔ)器的行列地址通常是分開的,。因此對(duì)動(dòng)態(tài)存儲(chǔ)器的尋址工作需要分別進(jìn)行行列尋址工作,。通常情況下,我們會(huì)直接采用FPGA廠家提供的IP核來實(shí)現(xiàn)外部的存儲(chǔ)器驅(qū)動(dòng),,這樣可以大大提高開發(fā)的效率,。
行緩存
行緩存通常情況下會(huì)放在片內(nèi)。每一個(gè)行緩存有效地將輸入延遲了一行,。用階數(shù)為圖像寬度的移位寄存器是可以方便地實(shí)現(xiàn)這種延遲,。
移位寄存器:首先,移位寄存器是由一連串的移位寄存器來實(shí)現(xiàn)的,,每個(gè)位都適用一個(gè)寄存器,,而每個(gè)邏輯單元都只有一個(gè)寄存器,因此,,采用移位寄存器的方式將會(huì)占用大量的邏輯資源,,特別是在圖像寬度比較大的時(shí)候,用內(nèi)部資源來實(shí)現(xiàn)行緩存往往是不明智的選擇,。
片上RAM:設(shè)計(jì)行緩存時(shí),,通常會(huì)選擇利用FPGA片內(nèi)的RAM塊來實(shí)現(xiàn)。采用RAM作為行緩存,,就需要設(shè)計(jì)寫入和讀出地址產(chǎn)生電路,。寫入地址就是輸入圖像行的列地址,讀出地址就是輸出圖像行的列地址,。若采用FIFO作為行緩存,,則順序?qū)懭肱c讀出即可。
行緩存的理想工作狀態(tài):流狀態(tài)是行緩存的理想工作狀態(tài),,也就是除了緩存裝載和卸載,,緩存內(nèi)部的數(shù)據(jù)流入和流出是平衡的,這樣才不至于破壞系統(tǒng)的流水線,。輸入圖像數(shù)據(jù)的到來時(shí)刻是由上一級(jí)時(shí)序所控制,,輸出圖像的數(shù)據(jù)流則與行緩存息息相關(guān)。
考慮一個(gè)3×3的窗口濾波器——每個(gè)輸出結(jié)果是窗口內(nèi)九個(gè)像素值的一個(gè)函數(shù),。如果沒有高速緩存,,每個(gè)窗口位置必須讀九個(gè)像素(對(duì)流處理來說是每個(gè)時(shí)鐘周期),,并且當(dāng)窗口掃描整個(gè)圖像時(shí),每個(gè)像素需要讀取九次,。在連續(xù)的時(shí)鐘周期內(nèi)需要使用水平相鄰的像素,,因此可以用寄存器緩存和延遲像素。這就能將每個(gè)時(shí)鐘周期讀取的像素?cái)?shù)量減少到三個(gè),。行緩沖緩存了之前行中的像素值,,避免了對(duì)這些行中像素的再次讀取。一個(gè)3×3的濾波器占據(jù)了三行:一個(gè)當(dāng)前行和兩個(gè)之前行,,在當(dāng)前行中讀取新數(shù)據(jù),因此需要兩個(gè)行緩沖來緩存之前兩行的像素值,。
異步緩存
異步緩存主要應(yīng)用在跨時(shí)鐘的場(chǎng)合,。對(duì)于一些設(shè)計(jì),在不同的部分使用不同的時(shí)鐘是不可避免的,。這個(gè)問題主要出現(xiàn)在視頻輸入,、視頻輸出及與外部的異步接口等場(chǎng)合。
一般來說,,外部的視頻輸入數(shù)據(jù)流都會(huì)附帶一個(gè)視頻流的參考時(shí)鐘,,而這個(gè)時(shí)鐘與本地邏輯時(shí)鐘是異步的。同時(shí),,處理完的視頻流要進(jìn)行顯示,,顯示驅(qū)動(dòng)電路的時(shí)鐘與本地系統(tǒng)時(shí)鐘往往也是不同的。系統(tǒng)與外部的一些異步接口,,例如異步存儲(chǔ)器等,,都是跨時(shí)鐘域的場(chǎng)合。
異步時(shí)鐘帶來的一個(gè)問題就是有效的讀寫速率不一致,。一般情況下,,這種場(chǎng)合是讀取速度要小于寫入速度。解決異步時(shí)鐘的一個(gè)方法就是建立異步緩存器,,用一個(gè)異步FIFO即可實(shí)現(xiàn),。使用FIFO需要注意的問題就是溢出問題,需要使FIFO的讀寫匹配,,在FIFO裝滿之前,,需要把FIFO讀走。
FIFO的讀寫時(shí)序比較簡(jiǎn)單,,內(nèi)部結(jié)構(gòu)圖如圖所示,。
對(duì)于異步時(shí)鐘域,用異步FIFO作異步緩存,,還能有效解決壓穩(wěn)態(tài)的問題,。尤其是對(duì)于不同頻不同相位的異步時(shí)鐘域,,只能用異步緩存來進(jìn)行同步,這是由于需要緩存來進(jìn)行帶寬匹配,,在這里FIFO是一個(gè)不錯(cuò)的選擇,。
亞穩(wěn)態(tài)問題:
亞穩(wěn)態(tài)狀態(tài)下,對(duì)于任何噪聲諸如環(huán)境,,只要系統(tǒng)中有異步元件,,亞穩(wěn)態(tài)就是無法避免的。亞穩(wěn)態(tài)主要發(fā)生在異步信號(hào)檢測(cè),、跨時(shí)鐘域信號(hào)傳輸及復(fù)位電路等常用設(shè)計(jì)中,。對(duì)于壓穩(wěn)態(tài),一般的處理方法是三拍處理,,使用三級(jí)寄存器同步后,,亞穩(wěn)態(tài)出現(xiàn)的給概率基本為0。
在一些對(duì)系統(tǒng)穩(wěn)定性要求更高的場(chǎng)合(例如軍工領(lǐng)域),,可能還會(huì)要求更多拍處理,,以便進(jìn)一步提高系統(tǒng)穩(wěn)定性。但這種同步方式僅僅適用于同頻的異步時(shí)鐘域或?qū)τ谏倭垮e(cuò)誤不敏感的功能單元,。對(duì)于異步時(shí)鐘域根可靠的方式還是使用兩組異步時(shí)鐘來進(jìn)行異步緩存,。
更多信息可以來這里獲取==>>電子技術(shù)應(yīng)用-AET<<