組別:2 組員: 劉祐瑋、陳昇達、劉佩雯 Lab: 2_2 HackMD link: https://hackmd.io/6kZrHyqzTtKPoeHpqlZlZw?view (歡迎利用此閱讀) Github link: https://github.com/nthuyouwei/asoclab/tree/main/lab02 # lab2_01_edgedetect 略(如workbook 介紹) # lab2_02_edgedetect_fsic ## how we design our work 這部分說明建立在了解lab2_01_edgedetect下做說明 根據新的Spec我們可以畫出新的架構圖如下: 所以我們可以改原本的EdgeDetech.h 如下: ![image](https://hackmd.io/_uploads/rJ7tKwqyA.png =60%x) 首先,我們需要把data width變寬4倍來達到4 pixels per cycle ,由 gradType 和 pixelType 更改為 gradType4x 和 pixelType4x。除此之外,interface 還引入了額外的控制參數sw_in(這是為了讓我們可以選取模式:select the output source from input image or the calculated magnitude),以及兩個用於CRC校驗的輸出(crc32_hw_pix_in 和 crc32_hw_pix_out)。而在interconnect的部分,為了做crc以及決定是否直接輸出input image,我們需要加dat_in_mag這條通道來傳遞pixel至Mag(原先只要傳遞dx)。 故我們在EdgeDetect_defs.h中定義了新的typedf ![image](https://hackmd.io/_uploads/SygkvT5kC.png) 注意數據結構Stream_t,我是根據testbench來定義,其中sof代表起始幀標誌、eol代表行結束標誌: ![image](https://hackmd.io/_uploads/Skd_5o9yR.png) ![image](https://hackmd.io/_uploads/BkbKjs51A.png) 接者我們進到 module Ver 來討論,02中的EdgeDetect_Verder.h跟01中EdgeDetect_Verder.h雷同,我們只需注意這時候一個for loop裡面是計算四筆pixel,並且一次傳出四筆的data和dy。改動內容如下: - Buffer tmp 大小都變4倍: ![image](https://hackmd.io/_uploads/r19fapqyR.png) - index x ,做完一次其實做了4筆所以要改成 x+=4,且break 的部分也要改成widthIn-4: ![image](https://hackmd.io/_uploads/S1KXRp9kC.png) ![image](https://hackmd.io/_uploads/H1Y-JCqyA.png) - add index x4 = x/4 ,我們一樣要利用奇偶數來判斷要從哪裡放的位置,但因為每次x會+4無法使用他來判斷,故我們利用x4=x/4,來取代原本x在for迴圈中的進行演算法的位置。 ![image](https://hackmd.io/_uploads/rkKu-09yA.png =60%x) - 計算部分,一次計算四筆,並且利用set_slc來存進去對應的位置: ![image](https://hackmd.io/_uploads/BkgOaT9yR.png) - 輸出部分:跟01一樣 ![image](https://hackmd.io/_uploads/rkjVmgs1A.png) 再接者我們進到 module Hor 來討論,02中的EdgeDetect_Horder.h跟01中EdgeDetect_Horder.h雷同,我們只需注意這時候一個for loop裡面是計算四筆pixel,並且一次傳出四筆的data(原本在01中不須要傳)和dx。改動內容如下: - Buffer tmp 大小都變4倍,除此之外原先01中是利用pix0、pix1 、pix2來暫存做運算,但因為我們有4筆資料需要運算, 故4(舊)+4(新)+1(保留一個tmp給舊的,新的要用到)總共要9個來運算,所以我們改成p$[9]$(注意這裡只要用一個pixel的大小就好了),以及增加一個pixel 的暫存 pix: ![image](https://hackmd.io/_uploads/S11OA0qJA.png) - index x ,做完一次其實做了4筆所以要改成 x+=4,且再判斷read data、left and right boundary 和break時也要適當的更改: ![image](https://hackmd.io/_uploads/BJ0D-JiyR.png) ![image](https://hackmd.io/_uploads/rylKW1j1R.png) ![image](https://hackmd.io/_uploads/Bksq-ysyR.png) ![image](https://hackmd.io/_uploads/BkA2Zyj1R.png) ![image](https://hackmd.io/_uploads/rkNWzki1A.png) - 計算部分,一次計算四筆,並且利用set_slc來存進去對應的位置: ![image](https://hackmd.io/_uploads/BJzGN1oyR.png =60%x) - 如何利用p[9]來計算,跟01一樣我們要分為三種狀況right boundary case和left boundary case 還有中間的case,因為要等兩筆資料寫進去我們才會算第一筆的資料(因為算四筆需要4+2(前後)筆)。其中p[0]到p[8]是由舊到新,所以在中間case,我們需要先做shift再寫入新的pixel至p[5]~p[8]。除此之外我們要把p[4]也shift至p$[0]$(因為四筆data需要前後兩筆共六筆來計算,故我們要保留p[4])。然後會有right boundary case 和left boundary case (就是在算第一筆還有最後一筆時會用到)只是把p[0]和p[5]利用鏡像填充p[2]跟p[3](紅色框框與藍色框框)。 ![image](https://hackmd.io/_uploads/ryq1zgikR.png =45%x) - 輸出部分:我們每次計算完的p[1]至p[4]我們要再次把他輸出傳進Mag(在01中並不需要)以及我們所算的dx ![image](https://hackmd.io/_uploads/S11o7xs1R.png) 緊接者我們進到 module Mag 來討論,這裡跟01有很大的不同,首先我們刪掉了angle的計算,並且加入了crc32計算,除此之外我們還加入sw_in來選擇輸出(the output source from input image or the calculated magnitude),以及不同01利用square root 來計算mag,在02中我們將會利用sum of absolute difference 來計算。改動內容如下: - Buffer tmp 大小都變4倍,且增加crc32的tmp。除此之外因為輸出要Stream_t架構,所以我們到時也需要轉換。 ![image](https://hackmd.io/_uploads/rko4hej10.png) - index x ,做完一次其實做了4筆所以要改成 x+=4,且再判斷dat.eol和break也要適當的更改: ![image](https://hackmd.io/_uploads/Hk3qhes1C.png) ![image](https://hackmd.io/_uploads/HJnypei1C.png) ![image](https://hackmd.io/_uploads/BJjl6gskR.png =80%x) - 計算magn,使用 ac_abs 函數計算 dx 和 dy 中每個像素梯度值的絕對值,然後利用 ac_fixed來處理數值溢出,最後利用.to_uint()來轉換type。 ![image](https://hackmd.io/_uploads/S1CFCxokC.png =60%x) - sw_in 決定輸出: ![image](https://hackmd.io/_uploads/Hy-hCgsy0.png) - 加入 crc32 (crc32 github 有提供) ![image](https://hackmd.io/_uploads/ByM-J-syC.png) - 符合最一開始講到的Stream_t架構,並輸出: ![image](https://hackmd.io/_uploads/HycBybiyA.png) ## What's the test result of catapult design ### Run design 首先我們可以利用我放在github中的directive.tcl 來run 整體design 包括設計FIFO 深度、pipeline等等,這部分如同01中的說明。 ``` sh catapult -f directive.tcl ``` ### Result #### C simlation (log file in github) ![image](https://hackmd.io/_uploads/SJJTGZj1R.png) #### C design checker ![image](https://hackmd.io/_uploads/ry6bHZiJC.png =60%x) #### Questasim result report_txt: ![image](https://hackmd.io/_uploads/B1dFSWo1C.png =50%x) waveform(紅框為error=0): ![image](https://hackmd.io/_uploads/HJoELWj1A.png ) #### 其他rtl.rpt resource usage 都放在github了 # lab2_03_fsic_prj ## how we integrate our design in FSIC 在完成 lab2_02_edgedetect_fsic 生成 RTL code 之後,我們會得到一個 concat_EdgeDetect_Top.v 的檔案,我們要將它放到 fsic 的環境去跑simulation,而 fsic 的環境所需要的檔案可以從 filelist 中得知 ![image](https://hackmd.io/_uploads/Hy0UJI310.png =40%x) 而這些檔案可以從 Lab1 fsic-sim 的 資料夾中找到,並上傳到 rtl 的資料夾下。 同時我們要將 concat_EdgeDetect_Top.v 改名為 concat_EdgeDetect_Top_fsic.v 也複製到 rtl 的資料夾下。 緊接著我們要把EdgeDetect top module 放入user_prj0(這部分design是從github clone下來的,大致一致,接下來我主要會說明設計)。 ![image](https://hackmd.io/_uploads/SkpDjS3yR.png =60%x) 在接線上時,因為在Verder中有兩個line buffer所以我們需要接上兩個 SRAM (spram.v) ![image](https://hackmd.io/_uploads/ry0SxL31A.png =50%x) 接者我們要連接我們的axi-stream的接口: ![image](https://hackmd.io/_uploads/HJ7Wb52JR.png =60%x) ![image](https://hackmd.io/_uploads/Hy6bWch10.png =60%x) 除了 axi-stream的interface外,我們還需要利用設定register來輸出或輸入其他data像是widthin、hightin、sw_in ...等,我們到時會利用axi-lite來讀取或寫入(可以從soc端也可以從fpga端)。 - Control Write Register ![image](https://hackmd.io/_uploads/BJUWoUn1A.png =80%x) - Control Read Register ![image](https://hackmd.io/_uploads/S1FXsUnJR.png =80%x) ## how we test our design in FSIC ### testbench design 這部分design是從github clone下來的,大致一致,接下來我主要會說明他的設計。 首先如同lab1_sim所提到我們需要初始化,然而因為user project selction control defalut 就是user_prj0,所以這部分不用特別設定。(如果不在user_prj0,就需要設定,如同lab1) 再者,上述有提到我們需要利用 axi-lite寫入data,如下: ![image](https://hackmd.io/_uploads/B1zd8q31R.png =80%x) 最後我們利用axi-stream傳data,並且也可以讀出data驗證。(這部分design方法如同lab1做fir一樣的方式,可以參考此詳細說明: https://github.com/nthuyouwei/asoclab/blob/main/lab01/fsic-sim/asoclab01_fsic-sim_report.pdf) ![image](https://hackmd.io/_uploads/BJeq95hkA.png =80%x) ![image](https://hackmd.io/_uploads/SJRn55h1C.png =80%x) ![image](https://hackmd.io/_uploads/BkxMsqnkC.png =80%x) ### Use questasim simulation -vsim the result: ![image](https://hackmd.io/_uploads/SyW0cBhy0.png =80%x) ### Use vivado simulation - xsim 我們可以跟lab1一樣利用vivado xsim來跑模擬,會得到一樣的結果。 ![image](https://hackmd.io/_uploads/H1LVoUhkR.png) 我們還可以利用gtkwave來分析waveform: 首先最重要的throughput: ![image](https://hackmd.io/_uploads/BJCAo8nyA.png) 可以知道這邊thoughput 為4 ,這我們可以跟catapult report上的report來比對,我一開始以為應該是一樣的但我猜想這裡應該是跟Mag比對因為Mag是最後一層輸出。且後面也去看了cosim的waveform throughput也是4。 - catapult report: ![image](https://hackmd.io/_uploads/SJTD3Lnk0.png) - cosim waveform: ![image](https://hackmd.io/_uploads/SkT8CRp10.png) 最後,我們當然也可以把各其他module的waveform拿出來觀察研究: ![image](https://hackmd.io/_uploads/Hk36RU31C.png) 例如我們可以確定在ver module中的line buffer data有寫入SPRAM: ![image](https://hackmd.io/_uploads/r1vqAK2JA.png) ## futher optimization 我們可以更改architecture讓每個main function都設定成II=1 ![image](https://hackmd.io/_uploads/rkpO-Ipk0.png) 最後可以發現throughput=1: ![image](https://hackmd.io/_uploads/SycPJ1RyC.png) 不過在驗證上,不論是cosim或者fsic可能需要重新設計tb,因為以目前cosim 結果可以發現throughput還是等於4且block Mag and Ver有idle的狀態,除此之外,目前fsic 中的tb會卡住,未來如果時間允許的話也可以再去修改。 - waveform of questasim ![image](https://hackmd.io/_uploads/HJ9Vx1AyR.png) ![image](https://hackmd.io/_uploads/By4HHyR10.png)