# Microblaze Helloworld tutorial on ZCU102
## 作者
| author | email |修改日期|
| -------- | -------- | -------- |
| 賴昱憲 | larrylaiforwork@gmail.com|2022/07/06|
## 工具版本
vivado ver : 2019.2
vitis ver : 2022.1 (使用比2022.1舊的版本可能會出錯)
## 前言
- 基本上這個教學是完完全全 step by step 全部都截圖給你看了,所以應該不會有步驟不清楚的部分,不像是官方給回覆,完全就是不清不楚 OWO
- 圖如果太小請右鍵->在新分頁中開啟
- 還有假如今天某一步驟錯了,undo 後再繼續做,結果到後面最終結果錯誤,那麼建議全部重來,因為基本上 tool 都蠻多 bug 的,尤其是有 GUI 的 tool,很多時候它的 undo 不是真的 undo
- 用 tool 真的很累,一堆問題 QAQ
- 假如我紅字的部分有人能解答出來,請幫我補充在裡面
## 目錄
- [Fetching Microblaze Hello world instructions from DDR](#Fetching-Microblaze-Hello-world-instructions-from-DDR)
- [Fetching Microblaze Hello world instructions from Local Memory (BRAM)](#Fetching-Microblaze-Hello-world-instructions-from-Local-Memory-(BRAM))
- [References](#References)
## Fetching Microblaze Hello world instructions from DDR
這份教學中會將 fsbl (first boot loader)、pmu (platform manage unit) elf、bitstream 與 hello world elf 這四個 partition 合成 boot image,之後再將 boot image 燒錄至 qspi flash 中,之後開機 microblaze 便會透過 AXI 去 PS side ddr 取得 hello world instruction 並執行
由於 microblaze 在 fsbl 配置好 bitstream 時便會開始運行,但是此時 hello world elf (instructions) 此 partition 還未配置(尚未 load 到 PS ddr 上),為了避免 microblaze 取到錯誤的 instruction,因此我們需要設置 microblaze 到 sleep mode

在 fsbl 配置完所有 partition 後再透過 gpio 去 wake up microblaze
### **vivado part**
開啟一個新的專案

選擇專案名稱以及路徑


選擇板子型號






因為是 execute code from ddr, 所以不需要local memory, 將 microblaze 配置如下圖

接著為了設定 microblaze 的 reset mode,以及讓 zynq 透過 gpio wake up microblaze,需要再做下面的操作




連線過來


連線過來

由於zynq預設有很多 peripherals io 是我們不需要的,而有些我們需要的功能他也沒有開啟,所以需要重新設定

可以看到下圖是它預設開啟的設定,其中我們只需要qspi, i2c0, i2c1, uart0以及部分的gpio,所以要把其他東西關掉

關閉PCIe, Display Port, SATA, USB0

關閉GEM3

關閉PMU, CAN1

關閉SD

關閉UART1

開啟GPIO EMIO寬度調為2 (GPIO EMIO 是PS與PL之間的IO)
關閉GPIO0 MIO, GPIO1 MIO (GPIO MIO 是PS與PS之間的IO)

接著依照下圖設置 PS-PL
其中 slave AXI LPD 是給 microblaze 與 PS uart0 的 io interface
slave AXI HP0 FPD 是給 microblaze 與 PS ddr 的 io interface

接著讓vivado幫你自動接線,
要注意的是 S_AXI_HPD_FPD 的預設設置是錯的,記得將 Master interface 改成 Cached

接下來你應該會收到一堆 warning, 這是因為 address editor 那邊還沒設置好,所以如下圖點選 address editor 後,在 Data Part 只留下 HP0_DDR_LOW 以及 LPD_UART0,在 Instruction Part 只留下 HP0_DDR_LOW,其餘的點右鍵,再點 Unmap segment

最後會變成這樣

之後再產生完 HDL Wrapper 後就點選Generate Bitstream
(假如沒有 run synthesis 過,那麼點選 Generate Bitstream 它會先幫你
run synthesis->run implementation->generate bitstream)


跑完後export hardware



### **vitis part**

用剛剛產生出來的XSA檔(硬體描述檔)建立 platform

取消 generate boot components

建立 domain for fsbl

建立 domain for pmu

設置 board support package settings

將 zynqmp_fsbl_bsp 設置為 true
<font color="#f00">不這樣設置的話會 compile 不過,不要問我為什麼要這樣設置,我也不知道為什麼,解決問題的人也不知道為什麼,請參考 https://support.xilinx.com/s/question/0D52E00006hpMsXSAU/vitis-20201-xfsbl-file-generation-failed?language=en_US </font>

之後 build platform

之後建立 application project



先建立 microblaze 的hello word application


接著建立 fsbl



接著建立 pmu



之後修改 fsbl->src->xfsbl_handoff.c 中的 function XFsbl_HandoffExit 並儲存
在其中加入下列 code 去對 gpio 送出訊號以達到喚醒 microblaze 的作用
詳情請參考
https://www.xilinx.com/htmldocs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
```
Xil_Out32(0xff0a0018, 0x1);
Xil_Out32(0xff0a02c4, 0x1);
Xil_Out32(0xff0a02c8, 0x1);
Xil_Out32(0xff0a004c, 0x1);
```

之後 build application

編譯完後應該只會有一個 error,這是 vitis 內部的路徑 bug,不用理它

之後準備生成 boot image

先把他預設的都刪掉(由於前面提到的路徑 bug,所以要自己手動加)

之後再一個一個手動加回去,要注意加回去的順序
一定要是 fsbl->pmu->bitstream->helloworld








<font color="#f00">不設置成a53_1的話會沒辦法跑,不要問我為什麼要這樣設置,我也不知道為什麼,解決問題的人也不知道為什麼,請參考 https://support.xilinx.com/s/question/0D52E00006hpPxrSAE/xfsblerrorunsupportedhandoff?language=en_US </font>


建好 image 後就準備將它燒錄到板子上的 qspi flash上了
在燒錄前先確定板子上uart, jtag, 電源線有接好
之後在確認boot mode是否為 jtag
如何設定boot mode請參考
https://www.centennialsoftwaresolutions.com/post/pictures-of-sw6-for-every-zcu102-zynq-ultrascale-mpsoc-boot-mode
都設好後就上電並開始燒錄


燒好之後將板子電源關閉,將 boot mode 調為 qspi 32bit
同時電腦先開啟可以觀測 uart 的工具(例如tera term 或者是vitis也有內建)
將包率調為115200(ps uart 的包率預設為115200)
之後上電


## Fetching Microblaze Hello world instructions from Local Memory (BRAM)
這份教學與 [Fetching Microblaze Hello world instructions from DDR](#Fetching-Microblaze-Hello-world-instructions-from-DDR) 不同的是,我們是直接將 bitstream 與 hello world elf 整合在一起,產生一個新的 bitstream,所以 instructions 一開始就寫入在 microblaze 的 local memory 中,無須再透過 AXI 去 PS side ddr 取得 instruction,也不必考慮 microblaze 運行時 hello world elf 尚未配置的問題,所以也不需要去 sleep & wake up microblaze
由於許多與 [Fetching Microblaze Hello world instructions from DDR](#Fetching-Microblaze-Hello-world-instructions-from-DDR) 步驟類似,因此不會像前面一樣 step by step,不然這樣做文件太累了 OVO
整體步驟大概是
1. 使用 vivado 生成 bitstream
2. 使用 vitis 生成 helloword elf
3. 回到 vivado 將步驟2的 elf 檔與 bitstream 融合產生新的 bitstream
4. 利用新的 bitstream 來完成最後的 microblaze application
### **vivado 生成 bitstream**
因為是 execute code from local memory, 將 microblaze 配置如下圖

接著設置 zynq,與前面的工作不同,我們也不需要 gpio 去 wake up microblaze,也不需要 slave AXI_HP0_FPD 去連接 PS side ddr


接著讓他自動接線

然後去設定 Address Editor,將其設定成下圖

之後一樣產生完 HDL Wrapper 後就點選 Generate Bitstream
之後 export hardware (記得勾選 include bitstream)
完成後先不要關閉vivado
### **vitis 生成 helloword elf**


記得取消generate boot components







build完後在 helloworld_elf/Debug/ 底下會產生 後面的步驟會用到的helloworld_elf.elf

### **vivado 將 elf 檔與 bitstream 融合產生新的 bitstream**
回到剛剛的 vivado



這裡要依序去做 run synthesis->run implementation->generate bitstream
(不能只點選 generate bitstream,因為先前步驟都跑過synthesis與implementation了,所以假如只點選 generate bitstream,那麼就只會執行generate bitstream,run synthesis 與 run implementation 不會被重新執行)

接著一樣 export hardware(include bitstream)
### **使用 vitis 利用新的 bitstream 來完成 microblaze application**
為了避免搞混,創立一個新的空白資料夾當作工作資料夾


利用前面生成的新的 bitstream 來建立 platform

記得取消 generate boot components















先把他預設的都刪掉(由於前面提到的路徑 bug,所以要自己手動加)

之後再一個一個手動加回去,要注意加回去的順序
一定要是 fsbl->pmu->bitstream

之後的燒錄步驟與前面一模一樣
之後結果

## References
https://support.xilinx.com/s/article/1175350?language=en_US
https://www.xilinx.com/htmldocs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
https://support.xilinx.com/s/question/0D52E00007CiCiYSAV/how-to-boot-the-microblaze-processor-from-flash-on-zcu102?language=en_US
https://support.xilinx.com/s/question/0D52E00006hpMsXSAU/vitis-20201-xfsbl-file-generation-failed?language=en_US
https://support.xilinx.com/s/question/0D52E00006hpPxrSAE/xfsblerrorunsupportedhandoff?language=en_US
https://www.centennialsoftwaresolutions.com/post/pictures-of-sw6-for-every-zcu102-zynq-ultrascale-mpsoc-boot-mode
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842019/Zynq+UltraScale+FSBL
https://www.youtube.com/watch?v=RmLG-TMVUgo&t=618s