?(本系列只需要modelsim即可完成數字圖像的處理,每個工程都搭建了全自動化的仿真環境,只需要雙擊top_tb.bat文件就可以完成整個的仿真,大大降低了初學者的門檻!!!!如需要該系列的工程文件請關注知識星球:成工fpga,https://t.zsxq.com/DMeqH,關注即送200GB學習資料,鏈接已置頂!)
前面我們實現了圖像三行數據的緩存,文件是data_cache.sv,有了這個文件,處理起來3x3的各種算子都不在話下。那現在問題來了,對于5x5的算子,使用data_cache.sv就不可以了。其實這都不是事,既然有了開發data_cache.sv的經驗,那就稍微修改一下,新建一個data_cache5.sv的文件,能支持5x5即可。
下面詳細說明一下數據緩存的方法,由于要緩存5行圖像的數據,那就要有5個ram,分別是ram0-ram4。行計數器從0-4反復的計數,方便數據的存取;需要的5x5的區域像素存在chnl0-chnl4中,chnl0-chn4都是5字節長度的,chnl0存放第0行的5個像素數據,chnl1存放第1行的5個像素數據,chnl2存放第2行的5個像素數據,chnl3存放第3行的5個像素數據,chnl4存放第4行的5個像素數據。
設計要點就是當前行的數據一定是5x5的最后一行,所以直接給到chnl4即可。每一行都是1個ram在寫,4個ram在讀,由于5個ram是循環讀寫的,可以根據行計數器確定這5個ram中數據的排列順序,比如行計數為0時,ram1存放的是第0行數據,ram2存放的是第1行數據,ram3存放的是第2行數據,ram4存放的是第3行數據,ram0存放的是第4行數據。
還有一個問題就是5x5的行緩存,圖像外圍要補兩圈的0才能讓所有5x5因子的計算一致。前兩行補零是通過先緩2行圖像數據再讀數來實現的,這時候還有兩個ram沒有寫進數據,就可以讀出來兩行的0;最后兩行的補零是通過增加兩行的數據有效信號來實現的,新增加的兩行寫0,就可以實現最后兩行都是0。而前兩列和后兩列的補零是通過將數據讀有效信號打兩拍作為輸出有效信號來實現的,每行的像素數據是通過左移位進入chnl0-chnl4的,由于行信號延時了兩拍,輸出信號有效時,已經有3個數據緩存到chnl0-chnl4,chnl0-chnl4的高16位還是0,這樣就可以實現前兩列的0,而后兩列直接通過延時的兩拍有效信號來實現。
解釋起來可能不太清晰,我們直接在代碼中講解。在\src\cache文件夾下新建data_cache5.sv文件,考慮到通用,文件采用參數化設計的思路。而且5x5因子輸出25個圖像數據變量有些多,直接使用數組輸出。
相關的變量的位寬也使用參數來定義。
通過組合邏輯實現ram讀寫相關信號和輸出信號,場同步和行同步信號不僅延時四個時鐘周期,還要多延時兩行。
實現列數和行數的計數,其中156-166行主要實現增加兩個數據行有效active信號。
數據行有效信號的延時打拍,用于數據的讀取和列補零;新增加的兩行數據直接給0,實現新增的最后兩行數據是0。
如下實現了行計數從0-4的功能,start信號用來控制先緩存兩行數據在讀數據,主要用來實現前兩行的補零。
以第一行數據的緩存為例,根據行號sel_cnt來確定需要讀取哪個ram的數據,最后260行的active_d0=0,而 active_d1和active_d2還拉高時補最后兩列的0。
最后一行數據的讀寫和前四行不太一樣,直接讀當前的圖像數據即可。
最后例化五個ram即可。
同樣,成工也把三行緩存的data_cache.sv模塊修改成了data_cache3.sv,也是加入了對于的參數。
在top文件中,例化了rgb2ycbcr模塊和data_cache5模塊。
在tb_image_sim文件中的第二個initial塊中,進行相關的圖像讀取和存儲的操作。
雙擊sim文件夾下的top_tb.bat文件,完成系統的自動化仿真。
可以加入相關的波形查看。如下是先緩存兩行數據再開始讀數操作。
我們看一下讀取的第一個數組數據,前兩行和前兩列都加上了0。
再看看最后的增加了兩個active信號,此時數據是0。
而輸出的最后一個數組數據,最后兩行和兩列都是0。