---
# System prepended metadata

title: asoc lab2_2

---


組別: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)




