硬件加速器的設(shè)計(Sobel邊緣檢測)_第1頁
硬件加速器的設(shè)計(Sobel邊緣檢測)_第2頁
硬件加速器的設(shè)計(Sobel邊緣檢測)_第3頁
硬件加速器的設(shè)計(Sobel邊緣檢測)_第4頁
硬件加速器的設(shè)計(Sobel邊緣檢測)_第5頁
已閱讀5頁,還剩123頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1硬件加速器的設(shè)計

(Verilog1364-2001)

--建模、仿真、綜合、驗證和實現(xiàn)--北京航空航天大學(xué)夏宇聞2課時安排和學(xué)習(xí)方法四次講課每次3小時;下課后自己閱讀材料在助教指導(dǎo)下做實驗4小時;課堂3x4=12小時,自己看書20小時,做實驗20小時,共計52小時;理論與實踐結(jié)合的學(xué)習(xí)方法;考核方法:修改課上介紹的設(shè)計,使其具有更高的性能。3講課的主要內(nèi)容硬件加速器的一般概念為什么要研究硬件加速器設(shè)計硬件加速器基本方法:

流水線和硬件復(fù)制軟件/硬件的劃分原則算法核心(Kernel)多主設(shè)備共享內(nèi)存系統(tǒng)4講課的主要內(nèi)容

設(shè)計舉例視頻圖像邊緣檢測算法的原理卷積表算法的偽碼表示中間值和最終值的比特需求處理階段的劃分5講課的目的提醒材料上容易忽略的內(nèi)容;指出重點和關(guān)鍵點;幫助同學(xué)理解材料上的難點;自己看材料、上機練習(xí)為主;互相認識,以便交流。6一般概念在嵌入式DSP系統(tǒng)中,對處理器有很高的要求,編寫專用的嵌入式軟件,采用高檔的DSP處理器芯片有時也無法達到系統(tǒng)對算法運算速度的要求,即使能達到性能價格比太差。

不得不設(shè)計專用硬件;采用硬件復(fù)制和流水線方法;增加并行性;還需要控制成本。7一般概念

數(shù)據(jù)的互相依賴性;中間數(shù)據(jù)的保存;硬件的復(fù)制;用一個時鐘在幾個并行硬件中可同時完成多個操作;時鐘的頻率也可以提高。8一般概念步驟1步驟2步驟3寄存器寄存器寄存器圖流水線在復(fù)雜應(yīng)用中要復(fù)合應(yīng)用流水線和硬件復(fù)制方法9

加速算法核心(kernel)引起的性能改善的量化:設(shè)執(zhí)行算法核心所占的時間比例為f。則執(zhí)行非算法核心的時間為(1-f),因此有:t=ft+(1-f)t

如果加速器能把算法核心的處理速度提高到原來的s倍,則算法核心的處理時間就縮短到原來的1/s,非算法核心的處理時間不變。因此,這個算法總的運行時間為:

t’=ft/s+(1-f)t總體性能的提高比例是原來的處理時間除以加速后的處理時間:S’=(ft+(1-f)t)/(ft/s+(1-f)t)

=1/(f/s+(1-f))這個公式稱為Amdahl法則,是以GeneAmdahl的名字命名的,他是并行計算的先驅(qū)之一。這個公式表明加速處理核心(kernel)算法所帶來的整體性能的提高在很大程度上依賴于算法核心在整個算法執(zhí)行時間中所占的比例。

一般概念10

例1:假設(shè)在嵌入式處理器上運行的算法可以分成不同的部分,執(zhí)行每一部分所花費的時間可以估算出來,而該算法可分為兩個部分,即分成兩個核心(kernel)算法,一個占總時間的80%,而另一個只占總時間的20%。若用一個硬件加速器來加速算法核心,我們將第一個算法核心的運行速度提高到原來的10倍,或者將第二個算法核心提高到原來的100倍,試問對哪個算法核心使用硬件加速器能對總體性能的提高產(chǎn)生更好的效果?解:對第一個算法核心進行加速處理所帶來的總體性能提升為:1/((0.8/10)+(1-0.8))=1/(0.08+0.2)=3.57對第二個算法核心進行加速處理帶來的總體性能提升為:1/((0.2/10)+(1-0.2))=1/(0.02+0.8)=1.25一般概念11

從結(jié)果對比可以看到,雖然第二個算法核心提高的運算速度是第一個的10倍,但是由于它在原來總運行時間里所占的比例較低,對其進行加速處理也只能帶來較小的性能改善。而對第一個算法核心進行加速處理會對總體性能產(chǎn)生更顯著的效果。所以我們在開始正式設(shè)計硬件時必須找到主要矛盾,即占總運行時間比例較高的部分,針對這部分算法程序進行硬件加速器的設(shè)計,以期望取得顯著效果。一般概念12

在確定算法核心以后,我們需要確定執(zhí)行計算步驟的順序。我們要確保能得到數(shù)據(jù),以便按順序處理,并且確保中間結(jié)果能夠在后續(xù)步驟需要前計算出來。除了這些約束以外,有些運算步驟是可以潛在地并行執(zhí)行的。因此,我們要確定哪些步驟可以通過并行執(zhí)行來滿足性能要求。然后再確定加速器的結(jié)構(gòu),即確定各個處理模塊的功能以及它們之間的數(shù)據(jù)流動。一般概念13

從算法到加速器結(jié)構(gòu),是在系統(tǒng)設(shè)計流程的早期完成的。這通常是由有經(jīng)驗的系統(tǒng)設(shè)計師完成。讓綜合工具自動完成這一過程,面臨很大的技術(shù)挑戰(zhàn)。除了非常少的領(lǐng)域外,早期的高級綜合工具并不成功。近來,新一代工具開始浮現(xiàn),并且在很廣泛的領(lǐng)域內(nèi)表現(xiàn)出良好的前景,尤其在音頻,視頻,和其它的信號處理領(lǐng)域。隨著這種技術(shù)的成熟,我們可以期待高級綜合工具在設(shè)計方法學(xué)中將會有更廣泛的應(yīng)用。一般概念14

在許多嵌入式系統(tǒng)中,需要處理大量的輸入輸出數(shù)據(jù)。I/O控制器必須在外部設(shè)備和嵌入式系統(tǒng)之間高速傳輸數(shù)據(jù)。數(shù)據(jù)從外部設(shè)備讀入內(nèi)存,就可以被嵌入式軟件或加速器處理。處理后的數(shù)據(jù)被寫到內(nèi)存。如果讀寫內(nèi)存數(shù)據(jù)都在處理器的控制下進行,那么,數(shù)據(jù)傳輸速度會很慢,并且占用大量處理器時間,使處理器無法執(zhí)行其他任務(wù)。如果讓I/O控制器和加速器直接發(fā)起對內(nèi)存的訪問而不通過處理器,勢必可以大大加快訪問內(nèi)存的速度。這種內(nèi)存訪問方式稱為DMA(DirectMemoryAccess)方式。在這種方式下,I/O控制器和加速器作為主設(shè)備給出讀寫內(nèi)存的地址和控制信號,或者通過DMA控制器發(fā)起對內(nèi)存的訪問,由DMA控制器給出地址和控制信號。一般概念15

系統(tǒng)中有處理器和DMA設(shè)備,并且共用內(nèi)存訪問通路,必須避免由于多個主設(shè)備同時訪問內(nèi)存而引起的沖突。為此,我們可以在系統(tǒng)中引入仲裁器(Arbiter),如下圖所示。系統(tǒng)中的主設(shè)備(處理器,DMA方式的加速器、I/O控制器)在訪問內(nèi)存之前,必須給仲裁器發(fā)出請求信號,仲裁器根據(jù)預(yù)先確定的仲裁策略,在多個請求信號中決定誰將取得訪問內(nèi)存的總線控制權(quán),并給得到總線控制權(quán)的設(shè)備發(fā)出訪問內(nèi)存的準(zhǔn)許信號。當(dāng)該設(shè)備完成對內(nèi)存的訪問后,便撤消請求信號。然后,仲裁器進入新一輪的仲裁,仲裁勝出的設(shè)備進行內(nèi)存訪問。我們也可以讓處理器來執(zhí)行仲裁器的功能。當(dāng)其他主設(shè)備要訪問內(nèi)存時,必須先向處理器發(fā)出請求信號,由該處理器決定哪個設(shè)備可以訪問內(nèi)存。根據(jù)不同的應(yīng)用場合,選擇適合的仲裁策略,有優(yōu)先級模式(賦予某個或幾個設(shè)備更高的優(yōu)先權(quán)),輪詢模式(所有主設(shè)備嚴格按照一定的順序取得內(nèi)存訪問權(quán))。一般概念16

一般概念CPU加速器仲裁器存儲器圖2多主設(shè)備共享內(nèi)存系統(tǒng)I/O控制器requestgrantgrantrequestrequestgrant17

在許多應(yīng)用中,數(shù)據(jù)被有規(guī)律地放在內(nèi)存中如占用連續(xù)的內(nèi)存塊,加速器把數(shù)據(jù)從內(nèi)存中一塊一塊取出進行處理。例如處理靜態(tài)和視頻圖像的幾種算法把一幀圖像分割成8×8或者16×16的像素塊,然后獨立地處理每個塊。這種塊處理加速器的數(shù)據(jù)通路主要由兩部分組成。其中一個部分以DMA方式訪問內(nèi)存。這部分電路根據(jù)處理器寫入加速器內(nèi)部寄存器的基地址產(chǎn)生后續(xù)地址。這一功能通常由地址計數(shù)器來完成。數(shù)據(jù)通路的另一部分對數(shù)據(jù)進行處理??刂撇糠职匆欢ǖ臅r序控制數(shù)據(jù)通路的打開和關(guān)閉,使數(shù)據(jù)有序、正確地流動??刂乒δ芸梢杂靡粋€有限狀態(tài)機或多個狀態(tài)機實現(xiàn)。一般概念18

與塊處理加速器相對應(yīng)的是流處理加速器。流處理加速器處理的數(shù)據(jù)是按時間順序達到的數(shù)據(jù)流。數(shù)據(jù)流可以是來自于高速的輸入設(shè)備(如A/D、攝像機等),也可以是其他加速器的輸出。此外,內(nèi)存中的數(shù)據(jù)也能以流的方式讀出,供加速器處理。流處理加速器最常見的應(yīng)用領(lǐng)域之一是數(shù)字信號處理(DSP)。模擬信號經(jīng)A/D采樣后,得到采樣信號的數(shù)據(jù)流。對數(shù)據(jù)的處理包括濾波、混合、放大/衰減、以及時域和頻域間的轉(zhuǎn)換。一般概念19

雖然,加速器可以直接讀取內(nèi)存數(shù)據(jù),并且把數(shù)據(jù)處理完后寫回內(nèi)存,但是加速器必須知道什么時候開始工作,待處理數(shù)據(jù)的起始地址,數(shù)據(jù)的大小,處理后數(shù)據(jù)的存放地址以及完成處理后通知處理器。也就是說,處理器必須能夠控制加速器的工作、獲取加速器當(dāng)前的工作狀態(tài)。這些功能通常是由加速器內(nèi)部的輸入輸出寄存器來完成。

一般概念20

我們可以在加速器內(nèi)部設(shè)置地址寄存器和數(shù)據(jù)長度寄存器,處理器通過向這些寄存器寫入數(shù)據(jù)讓加速器知道從何處讀取數(shù)據(jù)、數(shù)據(jù)大小及處理完后數(shù)據(jù)寫到何處。還可以有狀態(tài)寄存器,處理器通過讀取狀態(tài)寄存器了解加速器當(dāng)前的狀態(tài)。也可以用狀態(tài)寄存器的值產(chǎn)生申請中斷信號,通知處理器。加速器可以看做是處理器的一個I/O設(shè)備,因此,處理器讀寫加速器的內(nèi)部寄存器與讀寫一般的I/O設(shè)備是一樣的。一般概念21

有的情況下,當(dāng)處理器給加速器發(fā)出一個處理任務(wù)時,并不要求加速器立即響應(yīng)。處理器把需要加速器處理的多項任務(wù)的描述信息寫到先入先出隊列(FIFO)中,加速器從FIFO中讀取每件任務(wù)的描述信息,等準(zhǔn)備好以后,就可以執(zhí)行一項任務(wù)。一般概念22視頻邊緣檢測下面我們將用視頻圖像邊緣檢測加速器的設(shè)計作為例子,來說明加速器設(shè)計中幾個方面的問題。真實的邊緣檢測加速器設(shè)計是非常復(fù)雜的,本書只是介紹加速器的設(shè)計原理,為了不被具體細節(jié)所累,我們在這兩者之間做了某種程度的折中。

23視頻邊緣檢測邊緣檢測是分析視頻圖像的重要手段之一,并且應(yīng)用領(lǐng)域廣泛,像安全監(jiān)控和計算機圖形學(xué)等。邊緣檢測是確定一幅圖像在哪些區(qū)域上亮度發(fā)生突變。這些亮度突變的區(qū)域通常就是物體的邊緣。24視頻邊緣檢測在這個例子中,我們假設(shè)有像素的圖像,每個像素用8比特表示,按行存儲在內(nèi)存中,并且每一行里從左到右連續(xù)的像素點占據(jù)著內(nèi)存中連續(xù)的存貯單元。像素值是無符號整數(shù),范圍從0(黑色)到255(白色)。這里,我們采用一種相對簡單的算法,叫做Sobel邊緣檢測法。它的機理是計算x和y方向亮度信號的導(dǎo)數(shù)值并且尋找導(dǎo)數(shù)中的最大值和最小值。這些區(qū)域就是亮度變化最劇烈的區(qū)域。25視頻邊緣檢測Sobel檢測法通過一個叫做卷積的過程來估計每個像素點每個方向上的導(dǎo)數(shù)值。把中心像素點和離它最近的八個像素點每個乘以一個系數(shù)后相加。該系數(shù)通常用一個的卷積表(convolutionmask)來表示。分別用于計算x和y方向?qū)?shù)值的Sobel卷積表Gx和Gy如下圖所示。26視頻邊緣檢測

-10+1-20+2-10+1+1+2+1000-1-2-1GxGy27視頻邊緣檢測我們把每個像素值分別乘以卷積表中對應(yīng)的系數(shù),再把相乘得到的九個數(shù)相加就得到了x方向和y方向的偏導(dǎo)數(shù)值Dx和Dy。然后,利用這兩個偏導(dǎo)數(shù)值計算中心像素點的導(dǎo)數(shù)。計算公式如下:28視頻邊緣檢測由于我們只想找到導(dǎo)數(shù)幅值的最大值和最小值,對上式作如下簡化:這樣近似能夠滿足計算要求,因為開平方和平方函數(shù)都是單調(diào)的,實際計算幅度的最大值、最小值與近似以后計算的最大值、最小值發(fā)生在圖像的同一個地方。并且,與計算平方和開平方相比,計算絕對值所用的硬件資源少得多。29視頻邊緣檢測我們需要重復(fù)地計算圖像中每個像素位置的導(dǎo)數(shù)幅值。但是,注意到環(huán)繞圖像邊緣的像素點并沒有一個完整的相鄰像素組來計算偏導(dǎo)數(shù)和導(dǎo)數(shù),所以我們需要對這些像素進行單獨處理。最簡單的方法就是把圖像中邊緣像素點的導(dǎo)數(shù)值值|D|設(shè)置為0。這可以通過軟件來完成。30視頻邊緣檢測例2:把Sobel邊緣檢測算法用偽代碼的形式表達出來,也就是,用一種與計算機編程語言類似的表示法。答:我們用類似于Verilog的偽代碼來表示該算法。令O[row][col]表示原始圖像的像素點,D[row][col]表示導(dǎo)數(shù)圖像的像素點,row的范圍從0到479,col的范圍從0到639。同時令Gx[i][j]和Gy[i][j]表示卷積表,其中i和j的范圍從-1到1.31視頻邊緣檢測該算法可以表達為如下形式:for(row=1;row<=478;row=row+1) beginfor(col=1;col<=638;col=col+1) begin sumx=0; sumy=0; for(i=-1;i<=+1;i=i+1)begin for(j=-1;j<=+1;j=j+1)begin sumx=sumx+O[row+i][col+j]*Gx[i][j]; sumy=sumy+O[row+i][col+j]*Gy[i][j]; end end D[row][col]=abs(sumx)+abs(sumy)endend32視頻邊緣檢測例3:求在計算Sobel卷積中表示每個像素點中間值和最終值所需要的比特數(shù)。答:每個像素用8比特?zé)o符號數(shù)表示。像素值與卷積表中的系數(shù)相乘得到的九個部分積的范圍從-510到+510。因此,部分積應(yīng)該用10比特有符號數(shù)表示。求出每個Dx和Dy的值需要把各自的九個部分積相加。33視頻邊緣檢測

結(jié)果值的范圍是從-1020到1020,可以用11比特有符號數(shù)表示。然后,再把這兩個絕對值相加,得到|D|的范圍從0到2040,也可以用11比特表示。因為后續(xù)的邊緣檢測操作只需要確定哪個導(dǎo)數(shù)圖像的像素值超過了特定閾值,我們并不需要11比特的精確度。相反,用8比特值來衡量結(jié)果更為方便,因為8比特的結(jié)果可以像原始圖像一樣以相同的格式回送到內(nèi)存中。在這兩者之間做了某種程度的折中。

34視頻邊緣檢測例4:假設(shè)視頻的幀速為每秒30幀,計算必須以多快的速度計算Sobel卷積。答:每幀圖象包括640×480=307,200個像素。因為每秒有30幀,必須以:307,200×30=9,216,000每秒的速度對像素點進行處理,換言之,大約每秒1000萬個像素。35視頻邊緣檢測例5: 確定能夠滿足所要求的計算性能的并行結(jié)構(gòu)方案。答: 既然計算只需要原始圖像的像素值,因此求解每個導(dǎo)數(shù)像素所必須的計算可以各自獨立地進行。因此,我們可以按照要求同時對盡可能多的像素進行計算。下圖給出了計算圖像的導(dǎo)數(shù)像素的全過程。

36視頻邊緣檢測

計算導(dǎo)數(shù)像素的數(shù)據(jù)關(guān)系圖37視頻邊緣檢測這張圖展示了每個操作步驟所需要的數(shù)據(jù),從原始圖像的頂部像素開始,通過獨立并行操作得到中間結(jié)果,最后求出底部的導(dǎo)數(shù)像素。我們已經(jīng)省略了系數(shù)值是0的部分積,因為它們對結(jié)果沒有任何影響。通過這幅圖,我們看到可以并行地計算所有的部分積,因為每個部分積只依賴于原始像素值和常量系數(shù)。然后我們可以并行地把兩組各六個部分積加起來,再并行地計算兩個絕對值,把它們加起來最后得到(原始圖像某個像素的)導(dǎo)數(shù)像素值。38視頻邊緣檢測包括邊緣檢測加速器在內(nèi)的視頻系統(tǒng)的頂層框圖如圖5所示。視頻輸入來自攝像機的I/O控制器,它把連續(xù)的視頻圖像保存在內(nèi)存中。在處理器上運行的軟件控制加速器,對給定的幀進行處理,得到相應(yīng)的導(dǎo)數(shù)圖像。圖5含有邊緣檢測加速器的視頻系統(tǒng)這

39視頻邊緣檢測例6:假設(shè)存儲原始圖像和導(dǎo)數(shù)圖像的內(nèi)存是32位寬,并且每個字節(jié)是單獨編址的。視頻圖像是按照每個像素一個字節(jié)存儲的。一幀里一行的像素從左到右依次存儲在連續(xù)的地址空間,并且所有行是從上到下,一行接一行地存儲。每次內(nèi)存讀寫需要花費20納秒,即需要100MHz系統(tǒng)時鐘的兩個周期。問內(nèi)存存取數(shù)據(jù)的速度是否足夠塊?解:前面的分析指出,攝像機以大約每秒1000萬個像素的速度到達,即每100納秒收到一個像素。如果視頻輸入控制器用一次單獨的寫操作把每個像素點存儲到內(nèi)存中,它就會消耗可用內(nèi)存帶寬的20%。更好的辦法是控制器把四個像素值合起來,用一次寫操作來存儲這些像素,這樣就可以把對內(nèi)存帶寬的占用減少到5%。40視頻邊緣檢測邊緣檢測加速器必須以輸入像素到達的同樣速度計算出導(dǎo)數(shù)像素值,換言之,每100納秒輸出一個導(dǎo)數(shù)像素值。因此,假定每四個導(dǎo)數(shù)像素合成一個32比特的值,則把計算出的導(dǎo)數(shù)像素值寫入內(nèi)存又消耗內(nèi)存帶寬的5%。計算每個像素需要從原始圖像中取出8個像素值。一個天真的想法是一次只讀取一個像素分多次讀取,并且計算后續(xù)像素的導(dǎo)數(shù)值時再次照此方法讀取。這個方案完成每個像素的計算需要進行8次(中心像素點周圍的8個像素)讀取,占用160%的內(nèi)存帶寬。顯然這是不可能實現(xiàn)的。

41視頻邊緣檢測

因為內(nèi)存中每個32位字包括了四個相鄰的行像素,每次讀取32位字,包含了盡可能多的像素,可減少所需要的帶寬。如果每一行里的三個像素點在同一個32位字中,讀取三行的像素只需要三次。如果每一行里的三個像素點在不同的字中,則讀取完整的三行像素需要6次。所以,計算每個像素的導(dǎo)數(shù)值平均需要4.5次讀操作,占用90%的內(nèi)存帶寬。這個方案還是不可行。42視頻邊緣檢測注意,原始圖像的像素,一旦被讀取,就可以用來計算該像素的后一列,本列和前一列中三個像素的導(dǎo)數(shù),這樣可以進一步減少所占的內(nèi)存帶寬。所以,我們可以把讀取的原始圖像的像素存儲在加速器中用于計算多個像素的導(dǎo)數(shù),而不是等到需要計算那些像素的導(dǎo)數(shù)值時再重新讀取一遍。這樣,每計算四個像素,只需要讀取三個字,即只需要15%的內(nèi)存帶寬。則讀取三行像素所需的15%內(nèi)存帶寬再加上把視頻圖像存入內(nèi)存所需的5%,以及把像素導(dǎo)數(shù)值寫入內(nèi)存所需的5%帶寬,共占用25%的內(nèi)存帶寬。我們假設(shè)剩下75%的內(nèi)存帶寬足以完成系統(tǒng)的其它操作,則這個方案是可行的。

43視頻邊緣檢測若需進一步減少加速器所消耗的帶寬,可以在加速器中加入小塊內(nèi)存來存儲從主存中讀取的一整行。這可以讓每個像素只被讀取一次,把讀取像素所要求的帶寬減少到只有5%。視頻輸入和邊緣檢測將總共只占用15%的可用帶寬。

44視頻邊緣檢測在設(shè)計邊緣檢測器加速器時,我們將采用以下方法:從原始圖像中讀取三行,每行4個相鄰的像素,把這些像素值存儲在加速器的寄存器中以待處理。我們把原始圖像的三整行作為一個數(shù)據(jù)塊,整塊的數(shù)據(jù)經(jīng)過加速器以后,形成導(dǎo)數(shù)圖像中的一整行。正如我們后面要介紹的,這樣的數(shù)據(jù)塊的處理過程包括三個階段:起始階段,重復(fù)計算階段,和完成階段。不斷地重復(fù)執(zhí)行這三個階段,就可以求出導(dǎo)數(shù)圖像中的每一行。

45視頻邊緣檢測

Sobel加速器的數(shù)據(jù)路徑結(jié)構(gòu)如圖6所示。它實質(zhì)上是一個這樣的流水線,先從原始圖像中依次讀取三行像素值存入圖右上角的寄存器,再讓這些像素按時鐘節(jié)拍流過左側(cè)的乘法器陣列,然后向下流過加法器到達Dx和Dy寄存器,再通過絕對值電路和加法器到達|D|寄存器,最終進入圖左下角的寄存器。然后把計算得到的像導(dǎo)數(shù)素值從寄存器寫到內(nèi)存中。(盡管一個從右到左的數(shù)據(jù)流和通常情況是相反的,但在本例中,這樣有助于保持像素的位置安排和原圖像一致)。我們將先假設(shè)流水線從一開始就充滿有效數(shù)據(jù)來描述流水線的操作過程。然后再討論在圖像行的起始處流水線是如何啟動的,和在圖像行的結(jié)尾處,流水線中的數(shù)據(jù)又是如何排出的。46視頻邊緣檢測圖6Sobel加速器數(shù)據(jù)通路結(jié)構(gòu)47視頻邊緣檢測計算流水線按照每四個像素值一組的形式產(chǎn)生給定行的導(dǎo)數(shù)像素值。加速器從內(nèi)存中的上一行,本行,下一行各讀取四個像素點到如圖6所示右上角的3個32位寄存器中。每個寄存器包括4個8比特像素值寄存器。在接下來的四個時鐘周期里,像素值依次左移,每次一個像素值,到乘法器陣列中。陣列中的每個單元包括一個像素值寄存器和一個或兩個乘法電路。乘法電路用于把像素值寄存器中存儲的像素值乘以一個常量系數(shù)。48視頻邊緣檢測

因為系數(shù)都是-1,+1,-2或者+2,這些電路并不是完全意義上的的乘法器。相反,乘以-1僅僅是一個取反電路,乘以+1是一個直通連接而沒有任何電路,乘以-2是把取反電路的結(jié)果左移,乘以+2僅僅是一個左移。在每個時鐘周期,硬件電路陣列提供了求一個導(dǎo)數(shù)像素值所需要的部分積,部分積加起來后存儲到Dx和Dy寄存器中。同樣,在每個時鐘周期,計算出前一個像素值的Dx和Dy的絕對值,加起來后存儲到|D|寄存器中。|D|寄存器中的導(dǎo)數(shù)像素值左移到結(jié)果行寄存器中。當(dāng)寄存器中四個結(jié)果像素值都準(zhǔn)備好后,隨即被寫入到內(nèi)存中去。

49視頻邊緣檢測進入穩(wěn)態(tài)后,在處理一行的過程中,加速器在移入新的像素值到乘法法器陣列,Dx,Dy和|D|寄存器之前,需要把導(dǎo)數(shù)像素值從結(jié)果寄存器寫到內(nèi)存中。否則,上一次計算結(jié)果就會被覆蓋掉。在把四個像素值寫到內(nèi)存后,讀寄存器中的像素值已經(jīng)全部移入流水線中,此時讀寄存器為空。我們再讀入三組各四個像素點,像素值按時鐘節(jié)拍移入計算流水線,當(dāng)結(jié)果寄存器填滿四個像素值后,再次寫到內(nèi)存然后不斷重復(fù)這個過程。時序如圖7所示。假設(shè)加速器有一個Wishbone總線接口,數(shù)據(jù)位寬32位,時鐘頻率為100MHz。加速器是內(nèi)存總線的主設(shè)備之一,它必須先給仲裁器發(fā)出訪問內(nèi)存的請求信號,等總線仲裁器批準(zhǔn)以后,才能讀寫內(nèi)存。我們假設(shè)仲裁器給加速器足夠高的優(yōu)先權(quán),這樣加速器可以占有需要的內(nèi)存帶寬。50視頻邊緣檢測圖7流水線中像素讀寫操作和計算的時序51視頻邊緣檢測我們已經(jīng)考慮了處理一行像素過程中的穩(wěn)定狀態(tài),下面我們將考慮在一行像素的開始處流水線是如何啟動的。在處理一行像素的開始處,流水線中的寄存器中沒有有效的數(shù)據(jù)。我們先讀入三行各四個像素值,經(jīng)過四個計算周期(4個時鐘周期)后,有效數(shù)據(jù)已經(jīng)進入到流水線中的Dx和Dy寄存器。此時,結(jié)果寄存器中沒有有效數(shù)據(jù)。因此,在經(jīng)過第一次四個計算周期后不進行寫操作。由于讀寄存器已空,再讀入三行像素值,經(jīng)過四個計算周期后,有效數(shù)據(jù)已經(jīng)進入到最右側(cè)的三個結(jié)果像素值寄存器中。最左側(cè)的結(jié)果像素值寄存器里仍然是無效數(shù)據(jù)。我們前面曾經(jīng)提過,最左邊的像素位置沒有一組完整的相鄰像素點來計算導(dǎo)數(shù)像素值,我們將用軟件把它設(shè)為0。所以,得到的第一組導(dǎo)數(shù)像素值(一個無效值和三個有效值)應(yīng)該寫入內(nèi)存中。此后,流水線進入了穩(wěn)態(tài),這種情況前面已經(jīng)討論過。52視頻邊緣檢測當(dāng)?shù)竭_一行的結(jié)尾,我們需要排出流水線中的數(shù)據(jù)。因為一行里像素點的個數(shù)是4的整數(shù)倍(640=160×4),我們每次都可以讀到包含四個像素值的完整組。當(dāng)我們把一行里最后四個像素讀入讀寄存器,經(jīng)過四個計算周期后,結(jié)果寄存器被移入四個新的結(jié)果值,同時讀寄存器中的像素值被全部移入流水線中。然后結(jié)果寄存器被寫入內(nèi)存。由于整行像素已經(jīng)被讀完,不執(zhí)行讀操作。此時,流水線中還有數(shù)據(jù),再執(zhí)行四個計算周期排出流水線中的數(shù)據(jù)。經(jīng)過這四個計算周期,結(jié)果寄存器被移入四個數(shù)據(jù),但是寄存器中最右邊的數(shù)據(jù)是無效數(shù)據(jù)。因為圖像最右邊的像素點沒有完整的相鄰像素組。我們還將用軟件把那個像素值清零。53視頻邊緣檢測例7:編寫Verilog寄存器傳輸級代碼來描述圖6的數(shù)據(jù)通路。答:定義Sobel加速器模塊的Verilog代碼如下://計算數(shù)據(jù)通路信號reg [31:0]prev_row,curr_row,next_row;reg [7:0] O[-1:1][-1:1];regsigned [10:0] Dx,Dy;wiresigned[10:0]D;reg [7:0] abs_D;reg [31:0] result_row;//可進行計算的數(shù)據(jù)通路always@(posedgeclk_i)//上一行寄存器

if(prev_row_load) prev_row <=dat_i; else if(shift_en) prev_row[31:8]<=prev_row[23:0];

54視頻邊緣檢測

always@(posedgeclk_i)//當(dāng)前行寄存器

if(curr_row_load) curr_row<=dat_i; else if(shift_en) curr_row[31:8]<=curr_row[23:0];always@(posedgeclk_i)//下一行寄存器

if(next_row_load) next_row<=dat_i; else if(shift_en) next_row[31:8]<=next_row[23:0];

55視頻邊緣檢測

//計算絕對值函數(shù)function[10:0] abs(inputsigned[10:0]x); abs=x>=0?x:-x;endfunction//計算流水線assignD=abs(Dx)+abs(Dy);always@(posedgeclk_i) if(shift_en) begin abs_D<=D[10:3]; Dx<=-$signed({3'b000,O[-1][-1]}) //-1*O[-1][-1] +$signed({3'b000,O[-1][+1]}) //+1*O[-1][+1] -($signed({3'b000,O[0][-1]})<<1)//-2*O[0][-1] +($signed({3'b000,O[0][+1]})<<1)//+2*O[0][+1]-$signed({3'b000,O[+1][-1]}) //-1*O[+1][-1] +$signed({3'b000,O[+1][+1]}); //+1*O[+1][+1] 56視頻邊緣檢測

Dy<=$signed({3'b000,O[-1][-1]}) //+1*O[-1][-1] +($signed({3'b000,O[-1][0]})<<1) //+2*O[-1][0] +$signed({3'b000,O[-1][+1]}) //+1*O[-1][+1]-$signed({3'b000,O[+1][-1]})//-1*O[+1][-1]-($signed({3'b000,O[+1][0]})<<1)//-2*O[+1][0] -$signed({3'b000,O[+1][+1]}); //-1*O[+1][+1] O[-1][-1]<=O[-1][0]; O[-1][0]<=O[-1][+1];O[-1][+1]<=prev_row[31:24]; O[0][-1]<=O[0][0]; O[0][0]<=O[0][+1]; O[0][+1]<=curr_row[31:24]; O[+1][-1]<=O[+1][0]; O[+1][0]<=O[+1][+1]; O[+1][+1]<=next_row[31:24];endalways @(posedgeclk_i) //結(jié)果行寄存器

if(shift_en) result_row <={result_row[23:0],abs_D};57視頻邊緣檢測模塊中前三個always塊表示三個寄存器組(每個寄存器組由四個8比特的寄存器組成),從內(nèi)存中讀取的每組四個像素值被加載到這三個寄存器組中。因為這些寄存器要通過依次讀取內(nèi)存來加載數(shù)據(jù),所以每個寄存器組有一個單獨的控制信號來控制數(shù)據(jù)的加載。同時,三組寄存器都并行地把一個像素值移出寄存器,進入流水線中,所以它們共用一個移位控制信號。58視頻邊緣檢測第四個always塊,描述加速器的計算流水線。所有的計算邏輯和寄存器移位操作都在控制信號shift_en控制下進行。信號O是一個的原始圖像像素陣列(類似于C語言中的二維數(shù)組),該陣列(數(shù)組)中的每個元素對應(yīng)一個寄存器。從圖6可以看到,下標(biāo)為[-1][+1]的元素,是寄存器陣列的前一行(prevrow),下一列(最右列)的像素值。陣列中的元素值都是由每個輸入寄存器最左邊8位向左移入陣列的。Dx和Dy值由陣列元素乘以對應(yīng)系數(shù)計算出來的。我們通過前面分析得出,Dx,Dy的范圍是從-1020到1020,用11比特有符號數(shù)來表示。因此,我們把每個原始像素擴展成11比特,并轉(zhuǎn)換成有符號數(shù)再進行計算。59視頻邊緣檢測最后一個always塊,在shift_en控制下8比特的計算結(jié)果被從右至左依次移入32比特結(jié)果寄存器。當(dāng)結(jié)果寄存器被移入32比特數(shù)據(jù)時,其值將被一次寫入內(nèi)存。60視頻邊緣檢測我們在前面曾提到塊處理加速器必須有地址產(chǎn)生和數(shù)據(jù)處理電路。加速器作為系統(tǒng)中的主設(shè)備,必須提供讀寫內(nèi)存的地址信號。我們設(shè)計的Sobel加速器也需要地址產(chǎn)生電路來給出讀取原始圖像像素所需的地址,以及寫入導(dǎo)數(shù)像素所需的地址。在加速器內(nèi)部,我們將會提供兩個寄存器,以便嵌入式軟件可以把原始圖像和導(dǎo)數(shù)圖像在內(nèi)存中的基地址寫入這兩個寄存器。地址產(chǎn)生電路可以用寄存器中的基地址自動地產(chǎn)生像素地址。我們要求所有的地址是按字排列的,也就是說,它們都是四的整數(shù)倍。這意味著地址的最低兩位總是00。61視頻邊緣檢測例8:假設(shè)一幅圖像在內(nèi)存中的基地址為B,請推導(dǎo)出計算圖像的第r行第c列的像素值地址的表達式。行列都從0開始編號。答:圖像尺寸是480行,每行640個像素。第r行的起始地址是:B+r×640那么,r行c列的像素點位于地址:B+r×640+c我們可以把表達式r×640+c

看作基地址的地址偏移量。62視頻邊緣檢測例9:假設(shè)內(nèi)存的大小是4M字節(jié),組織成1M×32比特。請你為Sobel加速器設(shè)計能自動選通存儲地址(數(shù)據(jù)通路)的電路。答:地址產(chǎn)生電路需要兩個基地址寄存器:原始圖像基地址寄存器O_base和導(dǎo)數(shù)圖像基地址寄存器D_base。因為像素值按四個一組存儲,地址的最低兩位總是0,所以不需要在地址寄存器中顯式地給出這兩位地址。有幾種方案可以得到讀/寫地址,包括采用計數(shù)器對圖像行和列進行計數(shù),利用行和列的計數(shù)值,根據(jù)例8推導(dǎo)的公式來計算像素地址。但是這種方法引入了乘法運算(r×640),實現(xiàn)起來會消耗較多的硬件資源。然而,我們可以僅僅對基地址的偏移值進行計數(shù),這樣就可以避免乘以640的操作,見圖8所示。63視頻邊緣檢測圖8地址產(chǎn)生電路64視頻邊緣檢測對于原始圖像,偏移值從0開始計數(shù)。從內(nèi)存中每讀取一組四個像素值,偏移值加1。把偏移值和基地址加起來形成前一行(prevrow)的像素組地址。前一行的像素組地址加上640/4形成當(dāng)前行(currrow)的讀地址。前一行的像素組地址加上1280/4形成下一行(nextrow)的讀地址(假設(shè)地址的最低兩位都是00)。圖象的像素點總共有480行640列,前一行(prevrow)像素的地址加上640/4后,與原地址正好差了一行的位置;加上1280/4后,正好相差兩行的位置。根據(jù)這兩個地址從內(nèi)存中讀取的像素值正好就是用Sobel卷積表計算當(dāng)前行像素導(dǎo)數(shù)值所需要的當(dāng)前行和下一行的像素值。對于導(dǎo)數(shù)圖像,我們從偏移值640/4開始計數(shù),依次加1形成每次的寫地址。圖中的多路器根據(jù)當(dāng)前操作要求選擇適當(dāng)?shù)挠嬎愕刂穪眚?qū)動內(nèi)存地址總線。65視頻邊緣檢測例10:編寫寄存器傳輸(RTL)級的Verilog代碼描述如圖8所示的地址產(chǎn)生電路。解決方案: Sobel加速器模塊定義中的地址生成電路的代碼如下:always @(posedgeclk_i) //原始圖像基地址寄存器

if(O_base_ce) O_base<=dat_i[21:2];always @(posedgeclk_i) //原始圖像地址偏移量計數(shù)器

if(offset_reset) O_offset <=0; else if(O_offset_cnt_en) O_offset <=O_offset+1;66視頻邊緣檢測assign O_prev_addr=O_base+O_offset;assign O_curr_addr=O_prev_addr+640/4;assign O_next_addr=O_prev_addr+1280/4;always @(posedgeclk_i) // 導(dǎo)數(shù)圖像基地址寄存器

if(D_base_ce) D_base<=dat_i[21:2];always @(posedgeclk_i) // 導(dǎo)數(shù)圖像地址偏移量計數(shù)器

if(offset_reset) D_offset<=0; else if(D_offset_cnt_en) D_offset<=D_offset+1;67視頻邊緣檢測assignD_addr=D_base+D_offset;assign adr_o[21:2]=prev_row_load?O_prev_addr:curr_row_load?O_curr_addr:next_row_load?O_next_addr:D_addr;assignadr_o[1:0]=2'b00;68視頻邊緣檢測第一、三個always塊把分別表示原始圖像基地址寄存器和導(dǎo)數(shù)圖像基地址寄存器。當(dāng)處理器要把原始圖像基地址或?qū)?shù)圖像基地址寫入其中一個寄存器時,O_base_ce或D_base_ce有效,數(shù)據(jù)總線上的數(shù)據(jù)就被加載到相應(yīng)的地址寄存器。第二、四個always塊描述原始圖像和導(dǎo)數(shù)圖像地址偏移量計數(shù)器。計數(shù)器的控制信號由控制電路部分提供。圖8中的四個加法器分別由四條assign賦值語句實現(xiàn)。分別產(chǎn)生O_prev_addr,O_curr_addr,O_next_addr和D_addr。最后,通過一個多路器在產(chǎn)生的四個地址中選擇一個作為輸出地址。69視頻邊緣檢測我們在前面曾經(jīng)提過,處理器需要提通過讀寫加速器內(nèi)部的寄存器來控制加速器的工作、了解它的狀態(tài)。這時處理器是主設(shè)備,加速器是從設(shè)備。處理器和加速器的這種交互功能是由加速器的從機接口部分完成的。70視頻邊緣檢測我們將設(shè)置如下幾個控制和狀態(tài)寄存器來實現(xiàn)處理器和加速器之間的交互:控制寄存器。當(dāng)寫入該控制寄存器時,加速器就開始處理一幅圖像。并不關(guān)心寫入該寄存器的是什么值,寫入任何數(shù)都開始處理圖像??刂萍拇嫫?。第0位是中斷使能位。狀態(tài)寄存器,其第0位是done標(biāo)志位(即完成標(biāo)志位),當(dāng)處理器處理完一幅圖像時,隨即將該位設(shè)置為1。其它位為0。當(dāng)done標(biāo)志位為1,且中斷使能位為1時,加速器便發(fā)出中斷請求。讀取該狀態(tài)寄存器done標(biāo)志位還有一個附帶作用是中斷應(yīng)答,并將done標(biāo)志位清零為了簡化總線接口,我們把所有的寄存器設(shè)為32位,占有連續(xù)的地址空間。完整的寄存器地址映射如表1所示。71視頻邊緣檢測表1Sobel加速器的寄存器寄存器偏移值讀/寫中斷控制0只寫開始4只寫原始圖像基地址8只寫導(dǎo)數(shù)圖像基地址12只寫狀態(tài)0只讀72視頻邊緣檢測例11:編寫加速器從機接口(slaveinterface)的Verilog模型代碼。答:總線從機操作的時序如下圖所示??偩€的讀/寫操作都是在cyc_i和stb_i為1的一個周期內(nèi)發(fā)起的。73視頻邊緣檢測處理器發(fā)起一次讀/寫操作,加速器通過在下一個周期把ack_o信號置1,并在隨后一個周期把ack_o置0來響應(yīng)。我們需要對地址總線進行譯碼,得到加速器的選通信號。利用地址的低位確定哪個寄存器被讀寫。對起始寄存器(start)地址進行寫操作,并沒有設(shè)置真實的寄存器來保存寫入的數(shù)據(jù),而是利用對該地址的寫操作來產(chǎn)生一個控制信號start,啟動加速器的計算時序。讀取狀態(tài)寄存器,done標(biāo)志位(第0位)連同其他位(第1-31位)將被放到數(shù)據(jù)總線上。讀取其他寄存器將返回全0。對于加速器,要輸出到總線上的數(shù)據(jù)包括兩個部分:從機接口中的狀態(tài)寄存器和主機部分的結(jié)果寄存器,為此我們使用一個多路器來選擇數(shù)據(jù)總線的驅(qū)動源。描述從機接口部分的型代碼如下:74視頻邊緣檢測//Wishbone從機接口assign start=cyc_i&&stb_i&&we_i&&adr_i[3:2]==2'b01;//adr_i[1:0]=00assignO_base_ce=cyc_i&&stb_i&&we_i&&adr_i[3:2]==2'b10;assignD_base_ce=cyc_i&&stb_i&&we_i&&adr_i[3:2]==2'b11;always@(posedgeclk_i) //中斷使能寄存器

if(rst_i) int_en<=1'b0; elseif(cyc_i&&stb_i&&we_i&&adr_i[3:2]==2'b00) int_en<=dat_i[0];always@(posedgeclk_i) //狀態(tài)寄存器

if(rst_i) done<=1'b0; else if(done_set)//當(dāng)一幅圖像處理完時,done_set被置1 done<=1'b1; //formasterwrite75視頻邊緣檢測

elseif(cyc_i&&stb_i&&!we_i&&adr_i[3:2]==2'b00&&ack_o) done<=1'b0;//讀狀態(tài)寄存器操作將清除標(biāo)志位//中斷申請assignint_req=int_en&&done;always@(posedgeclk_i) //生成應(yīng)答ack輸出

ack_o<=cyc_i&&stb_i&&!ack_o;//總線數(shù)據(jù)輸出多路選擇器always@* if(cyc_i&&stb_i&&!we_i) if(adr_i[3:2]==2'b00) dat_o={31'b0,done}; //statusregisterread else dat_o=32'b0;//otherregistersreadas0 else dat_o=result_row; //formasterwrite76視頻邊緣檢測例12:導(dǎo)數(shù)圖像的計算必須按照確定的步驟進行,請設(shè)計能操縱計算步驟的控制器。解決方案:我們可以用一個有限狀態(tài)機來安排計算的操作步驟。因為大部分的計算步驟是重復(fù)執(zhí)行的,所以可以用計數(shù)器來跟蹤計算的過程。我們用一個行計數(shù)器來確定已經(jīng)完成了多少行的計算,從第0行起一直增加到第477行;再用另一個計數(shù)器來確定已經(jīng)完成了多少列的計算,從第0列起一直增加到第159列((159+1)×4=640)。控制計算步驟的有限狀態(tài)機的狀態(tài)轉(zhuǎn)移圖如圖10所示。為避免狀態(tài)轉(zhuǎn)移圖顯得過于混亂,其中只顯示了狀態(tài)和轉(zhuǎn)移條件,也沒有顯示某一個狀態(tài)回到自己狀態(tài)的轉(zhuǎn)移。我們在這里假設(shè):若一個給定的狀態(tài)轉(zhuǎn)移條件為假(即不成立),則該有限狀態(tài)機就呆在原狀態(tài),直到下一個時鐘周期。77視頻邊緣檢測該FSM(有限狀態(tài)機)的初始狀態(tài)為idle(空閑)狀態(tài)。當(dāng)處理器對start寄存器寫入數(shù)據(jù)時,start信號變?yōu)?(有效),F(xiàn)SM(有限狀態(tài)機)啟動讀操作和第一行計算的初始時序。這個過程包括讀取最初三組原始圖像的像素值,然后執(zhí)行四個計算周期。完成后,該有限狀態(tài)機進入了一個循環(huán),在這個循環(huán)里,它再次讀取三組原始圖像的像素值,執(zhí)行四個計算周期,然后寫一組由計算得到的像素值。正像我們在觀察該有限狀態(tài)機輸出函數(shù)時所看到的那樣,列計數(shù)器在每次寫操作后加一。在最后一次計算周期結(jié)束的時候,若此時列計數(shù)器不是158,則該有限狀態(tài)機繼續(xù)循環(huán),若此時列計數(shù)器是158,則進入一個狀態(tài),在該狀態(tài)中開始排出流水線中的數(shù)據(jù)。排出流水線中的數(shù)據(jù)包括一個把倒數(shù)第二組結(jié)果寫入的狀態(tài),四個計算周期,和一個把最后一組計算結(jié)果寫入的狀態(tài)。行計數(shù)在這最后一次寫操作后器加一。然后若此時行計數(shù)器的計數(shù)值不是477,則該有限狀態(tài)機回到下一行的初始時序,若此時行計數(shù)器的計數(shù)值是最終的計數(shù)值477,則回到空閑狀態(tài)。

78視頻邊緣檢測圖10狀態(tài)轉(zhuǎn)移圖79視頻邊緣檢測該有限狀態(tài)機的輸出函數(shù)如表2和3所示。為讓圖表讀起來簡單一些,我們把控制信號輸出為0的表格項留做空白,只列出表格項為1的情況。有些控制信號是摩爾型輸出,只取決于當(dāng)前狀態(tài),見表2所示。其它控制信號為米利型輸出,見表3所示。這些信號由輸入條件和當(dāng)前的狀態(tài)共同決定其值。80視頻邊緣檢測表2:摩爾狀態(tài)機的輸出81視頻邊緣檢測表3:米利狀態(tài)機的輸出82視頻邊緣檢測例13為Sobel加速器的控制部分編寫一個Verilog模型。解決方案:控制部分的代碼包括該控制有限狀態(tài)機(FSM)的內(nèi)部信號、行列計數(shù)器和控制信號的聲明:parameter[4:0] idle =5'b00000, read_prev_0=5'b00001,read_curr_0=5'b00010,read_next_0=5'b00011,comp1_0=5'b00100,comp2_0=5'b00101, comp3_0=5'b00110, comp4_0=5'b00111, read_prev=5'b01000, read_curr=5'b01001, read_next=5'b01010,83視頻邊緣檢測

comp1=5'b01011, comp2=5'b01100, comp3=5'b01101, comp4=5'b01110, write_result=5'b01111, write_158=5'b10000, comp1_159=5'b10001,comp2_159=5'b10010, comp3_159=5'b10011, comp4_159=5'b10100, write_159=5'b10101;

84視頻邊緣檢測reg[4:0]current_state,next_state;reg[8:0]row;//范圍從0到477;reg[7:0]col;//范圍從0到159;wirestart;wirestb_o;regoffset_reset,row_reset,col_reset;regprev_row_load,curr_row_load,next_row_load;regshift_en;regcyc_o,we_o;regrow_cnt_en,col_cnt_en;regO_offset_cnt_en,D_offset_cnt_en;regint_en,done_set,done;85視頻邊緣檢測用行、列兩個計數(shù)器來控制計算過程,分別用下面兩個always塊表示:always@(posedgeclk_i) //Rowcounter if(row_reset) row<=0; else if(row_cnt_en) row<=row+1;always@(posedgeclk_i) //Columncounter if(col_reset) col <=0; else if(col_cnt_en) col<=col+1;86視頻邊緣檢測always@*begin //FSM的組合邏輯部分

offset_reset =1’b0;row_reset =1’b0; col_reset =1’b0; row_cnt_en =1’b0;col_cnt_en =1’b0; O_offset_cnt_en =1’b0;D_offset_cnt_en =1’b0; prev_row_load =1’b0;curr_row_load =1’b0; next_row_load =1’b0; shift_en =1’b0;cyc_0 =1’b0; we_o =1’b0;done_set =1’b0; case(current_state)idle:begin offset_reset=1’b1;row_reset=1’b1; col_reset=1’b1; if(start)next_state=read_prev_0; else next_state=idle;end87視頻邊緣檢測read_prev_0:begin col_reset=1’b1;pre_row_load=1’b1; cyc_o =1’b1; if(ack_i)next_state=read_curr_0; elsenext_state=read_prev_0; end read_curr_0:begin curr_row_load=1’b1;cyc_o=1’b1; if(ack_i)next_state=read_next_0; elsenext_state=read_curr_0; end read_next_0:begin next_row_load=1’b1;cyc_o=1’b1; if(ack_i) begin O_offset_cnt_en=1’b1; next_state=comp1_0; end elsenext_state=read_next_0; end

88視頻邊緣檢測

comp1_0:begin shift_en=1’b1; next_state=comp2_0; end ... comp4:begin shift_en=1’b1; if(col==158)next_state=write_158; elsenext_state=write_result; end write_result:begin cyc_o=1’b1;we_o=1’b1; if(ack_i) begin col_cnt_en=1’b1;D_offset_cnt_en=1’b1; next_state=read_prev; end elsenext_state=write_result; end

89視頻邊緣檢測

write_result:begin cyc_o=1’b1;we_o=1’b1; if(ack_i) begin col_cnt_en=1’b1;D_offset_cnt_en=1’b1; next_state=read_prev; end elsenext_state=write_result; end write_158:begin cyc_o=1’b1;we_o=1’b1; if(ack_i) begin col_cnt_en=1’b1;D_offset_cnt_en=1’b1; next_state=comp1_159; end elsenext_state=write_158; end ...

90視頻邊緣檢測

write_159:begin cyc_o=1’b1;we_0=1’b1; if(ack_i) begin D_offset_cnt_en=1’b1; if(row==477)begin done_set=1b1; next_state=idle; end elsebegin row_cnt_en=1’b1; next_state=read_prev_0; end end elsenext_state=write_159; end endcaseendassignstb_o=cyc_o;91視頻邊緣檢測到目前為止,我們已經(jīng)開發(fā)了構(gòu)建Sobel加速器需要的全部硬件,剩下的部分是用來控制加速器工作的嵌入式軟件。正如我們在介紹這個例子時提到的那樣,視頻邊緣檢測有著廣泛的應(yīng)用領(lǐng)域。所以與其為每個具體的應(yīng)用重新設(shè)計一個新的控制軟件,還不如開發(fā)一個能適用于多種類似應(yīng)用的可重用的軟件組件。開發(fā)一個能提供一系列操作的驅(qū)動程序,使得應(yīng)用程序能夠從抽象的視角來理解加速器,就可以圓滿地完成以上任務(wù)。每個應(yīng)用程序都可以把這個驅(qū)動程序當(dāng)作完成其所需功能的軟件元件集合的一部分。例如,識別視頻圖像中物體的應(yīng)用程序可以把邊緣檢測應(yīng)用于視頻流的每一幅圖像,接著把邊緣分組,再和邊緣圖片庫進行對比。在一個完整的應(yīng)用程序中,這些軟件的開發(fā)和硬件的開發(fā)一樣重要。更完整的策略可以在關(guān)于嵌入式系統(tǒng)軟件開發(fā)的書中找到。92加速器的驗證因為加速器是比較復(fù)雜的,在設(shè)計過程中,驗證特別重要。我們必須確保已完成的加速器設(shè)計將會正確地對所有合法的輸入數(shù)據(jù)進行操作,并且會與嵌入式處理器準(zhǔn)確地配合和互動。因為所有可能的數(shù)據(jù)值和操作順序組合的空間是如同天文數(shù)字般的巨大,對設(shè)計進行無遺漏的驗證是不現(xiàn)實的??尚械霓k法是,我們必須先制訂可以覆蓋多種操作條件的驗證方案。

93加速器的驗證驗證復(fù)雜加速器的方法之一是獨立地驗證它操作的不同方面。比如,我們可以采用一種“分而治之”的策略,逐個地驗證Sobel加速器下述幾個方面的問題:從機總線的操作計算時序主機總線操作地址的產(chǎn)生像素的計算94加速器的驗證顯然,加速器的每個方面都必須正確地工作,因為加速器是作為一個整體在工作。然而,每次只驗證一個方面比試圖一次驗證所有的方面要簡單的多。在驗證了從機總線的各種操作都能正常運行后,我們可以用這些總線操作來發(fā)起計算過程。然后,檢查計算是否能根據(jù)設(shè)計好的步驟進行,與主機總線操作的配合是否正確無誤,暫時先不考慮實際的地址和像素值。然后確保能生成正確的地址,最后檢查像素值的計算是否正確。驗證流處理加速器與上述過程是類似的,但我們還要驗證這個加速器和待處理的數(shù)據(jù)源是否能正確地配合。95加速器的驗證為了完成這個驗證過程,必須構(gòu)建一個測試平臺,該平臺可以模擬帶有加速器的嵌入式系統(tǒng)的行為。若我們有一個已驗證的嵌入式處理器模型,則可以把它加到測試平臺中,編寫小的測試程序在它上面運行。測試程序把參數(shù)寫入加速器中的寄存器,對其進行設(shè)置并啟動操作。另一方面,若不能獲得處理器模型,則必須編寫處理器總線的功能模型,即能執(zhí)行預(yù)先確定的總線操作時序,但不實際執(zhí)行任何處理器指令的模型。我們的測試平臺也需要有存儲器和總線仲裁器的模型。這個存儲器模型,像處理器模型一樣,沒有必要具有全部的功能,而只要具有總線的讀寫操作功能即可,只要能按照預(yù)先確定的規(guī)則產(chǎn)生讀取的數(shù)據(jù),可以不考慮數(shù)據(jù)的寫入。這些簡化使得我們可以把精力集中在加速器的驗證上,以可控的方式建立測試案例。96加速器的驗證例14:開發(fā)一個可對Sobel加速器進行驗證的測試平臺,該平臺包含一個具有總線功能的處理器模型。該處理器模型能通過程序命令加速器對一幅存儲在地址為00800016

的原始圖像進行計算,并把計算生成的圖像像素的導(dǎo)數(shù)值存入地址為05300016

的內(nèi)存中。該處理器模型必須每10μs讀一次狀態(tài)寄存器,直到done標(biāo)志位(完成標(biāo)志位)被設(shè)置為止。該測試平臺還必須包括能賦予加速器優(yōu)先權(quán)的總線仲裁器,以及具有總線功能的存儲器,該存儲器對讀操作返回0,并拋棄寫入的數(shù)據(jù)。97加速器的驗證解決方案:該測試平臺的構(gòu)建可參照如圖2所示的系統(tǒng)模型。加速器是待驗證的設(shè)計,仲裁器和具有總線功能的處理器還有存儲器組成了測試平臺的剩余部分。我們還加入了時鐘和復(fù)位信號發(fā)生器。測試平臺模塊定義的要點如下:98加速器的驗證

`timescale1ns/1ns

moduletestbench;

parametert_c=10; parameter[22:0]mem_base=23’h000000; parameter[22:0]sobel_reg_base=23’h400000; parametersobel_int_reg_offset=0; parametersobel_start_reg_offset =4;parametersobel_O_base_reg_offsetp=8;parametersobel_D_base_reg_offsetp=12;parametersobel_status_reg_offsetp=0;

99加速器的驗證

reg clk,rst;wire bus_cyc,bus_stb,bus_we;wire[3:0] bus_sel; wire[22:0] bus_adr; wire bus_ack; wire[31:0] bus_dat; wire int_req; wire sobel_cyc_o,sobel_stb_o,sobel_we_o; wire[21:0] sobel_adr_o; wire sobel_ack_i; wire sobel_stb_i; wire sobel_ack_o; wire[31:0] sobel_dat_o;…….100加速器的驗證

alwaysbegin //時鐘發(fā)生器

clk=1’b1;#(t_c/2); clk=1’b0;#(t_c/2); end initialbegin //復(fù)位發(fā)生器

rst=1’b1; #(2.5*t_c) rst=1’b0; endsobelduv(.clk_i(clk),.rst_i(rst), .cyc_o(sobel_cyc_o), .stb_o(sobel_stb_o), .we_o(sobel_we_o), .adr_o(sobel_adr_o), .ack_i(sobel_ack_i), .cyc_i(bus_cyc),.stb_i(sobel_stb_i), .we_i(bus_we),.adr_i(bus_adr[3:2]), .ack_o(sobel_ack_o), .dat_o(sobel_dat_o), .dat_i(bus_dat), .int_req(int_req));…endmodule101加速器的驗證時鐘發(fā)生器always塊用參數(shù)t_c確定了時鐘周期時間,產(chǎn)生頻率為100MHz的時鐘信號。參數(shù)mem_base和sobel_base定義了存儲器的基地址(00000016

)和Sobel加速器寄存器的基地址(40000016)。其他參數(shù)定義了控制寄存器和狀態(tài)寄存器相對基地址的偏移值。接下去,測試平臺列出了表示總線地址,數(shù)據(jù)和控制信號的wire類型的線網(wǎng)。正如我們馬上將要看到的那樣,這些wire類型的線網(wǎng)信號是從系統(tǒng)中不同的源設(shè)備經(jīng)由多路器選擇出來的。該測試平臺還聲明了專用于連接Sobel加速器的線網(wǎng)。在模塊中,加速器被實例引用為待驗證的設(shè)計(duv)并與該線網(wǎng)連接。102加速器的驗證為處理器總線功能模型編寫的測試平臺代碼如下:regcpu_cyc_o,cpu_stb_o,cpu_we_o;reg[3:0] cpu_sel_o;reg[22:0] cpu_adr_o;wire cpu_ack_i;reg[31:0] cpu_dat_o;wire[31:0] cpu_dat_i;…

103加速器的驗證

…taskbus_write(input[22:0]adr,input[31:0]dat); begin cpu_adr_o=adr; cpu_sel_o=4’b1111; cpu_dat_o=dat; cpu_cyc_o=1’b1;cpu_stb_o=1’b1;cpu_we_o=1’b1; @(posedgeclk);while(!cpu_ack_i)@(posedgeclk); endendtaskinitialbeg

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論