---
# System prepended metadata

title: SOCStudy

---

<!-- 112.9.16 -->
# **<font color="purple">"SoC Design" Course Study Journel</font>**
This study journal is created by Yeh Cheng-Hong, 112501538, CoSR department, NTHU.

Course: NTHU 11210EE525100 系統晶片設計(SOC Design)
<br/><br/>
## Lab 0: Collaborative Learning Checklist
- [x] Join in SoC lab Slack channel.
- [x] Create README in [my personal Github](https://github.com/whywhytellmewhy).
- [x] Subscribe [bol-edu/HLS-SOC-Discussions](https://github.com/bol-edu/HLS-SOC-Discussions)/Discussions on Github.
- [x] Create a study journel on Hackmd.io. (This one!)
<br/><br/>

<!-- 112.9.28 -->
## Lab 1: From Vitis HLS to onlineFPGA
==環境安裝步驟==：
* **安裝 VirtualBox:** 虛擬機器，用來跑VM，好處是可以有「擷取/恢復快照」的功能，可以記錄下不同版本，方便開發與管理
* **安裝Ubuntu VM以及Xilinx相關軟體（Vitis、Vitis HLS、Vivado）:** 在[雲端硬碟](https://drive.google.com/drive/folders/1aVujPu872Siyw-uODWrvf4p0axVsdPsw)中已pack在一起成為映像檔。也可以按照[此處](https://github.com/bol-edu/course-lab_1/blob/2022.1/HLS%20Tools%20Installation%20Guide%202022.1.pdf)說明下載Windows版，或是按照[此處](https://github.com/bol-edu/course-lab_1/blob/2022.1/HLS%20Tools%20Installation%20Guide%202022.1_ubuntu.md)說明下載Ubuntu VM版。

==安裝好上述環境後，就可以正式開始做這次的lab了！==

The implementation flow to verify/validate an IP design is summarized as follows: (以**VM**為主要開發平臺)
1. **Vitis HLS:** 
    1. Type in `vitis_hls` in terminal
    2. GUI介面上按下「Create Project」，輸入Project name:「hls_ip」以及Location:「/home/ubuntu/course-lab_1」
    3. 跳過Add/Remove Design Files設定介面
    4. 跳過Add/Remove Testbench Files設定介面
    5. 來到Solution Configuration設定介面：Period:「10」(單位: ns) [註1]；Part:「按下『...』-->Select:『Parts』、Search中輸入並點選『xc7z020clg400-1』」[註2]
    > [註1] 若PYNQ-Z2的FPGA可運行於時脈200MHz以上，可以選擇週期為10ns [(資料來源)](https://github.com/bol-edu/course-lab_1/blob/2022.1/2022.1-Workbook-Lab1.pdf)

    > [註2] 因vitis 2021.2版本讀不到PYNQ-Z2的board file，所以選用與PYNQ-Z2相同part [(資料來源)](https://github.com/bol-edu/course-lab_1/blob/2022.1/2022.1-Workbook-Lab1.pdf)
    6. 匯入design檔案：hls_ip/Source按右鍵-->「New Source File...」-->選擇「Multiplication.cpp」及「Multiplication.h」
    7. 匯入testbench檔案：hls_ip/Test Bench按右鍵-->「New Test Bench File...」-->選擇「MultipTester.cpp」
    8. 指名IP匯出的top function：上方工具欄「Project-->Project Settings-->Synthesis-->Top function: 輸入『Multiplication.cpp的function名稱，即multip_2num』」
    9. Directives Control：在Synthesis前必須先加入directive描述
        * 方法1: inline方式加入`#pragma`，例如
        ```csharp
        #pragma HLS INTERFACE s_axilite port=pn32ResOut
        #pragma HLS INTERFACE s_axilite port=n32In2
        #pragma HLS INTERFACE s_axilite port=n32In1
        #pragma HLS INTERFACE ap_ctrl_none port=return
        ```
        * 方法2: 用directives.tcl  
            [Lab2 Workbook](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)中有介紹，步驟如下：
            1. 中上方的視窗選擇「MultipTester.cpp」的tab
            2. 右上方的視窗選擇「Directive」的tab
            3. 編輯directives：  
                * 在此以「插入**interface**的directive組態」為例：
                    1. 在top function上按滑鼠右鍵-->選擇「Insert Directive...」
                    2. Directive：「INTERFACE」-->Options：「(填入要的值)」
                    3. 重複上述動作，將top function引入的引數（即top function下方的那些綠色點點）也插入interface的directive組態
                        :::warning
                        :warning: 有些設置需要先把視窗拉大才看得到 [(資料來源)](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)
                        :::
                        :::danger
                        :warning: 若有需要設定depth，記得要設成跟test data筆數**相等** [(資料來源)](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)
                        :::
                    4. 最終結果會長得類似下圖：  
                        ![](https://hackmd.io/_uploads/BJZsW4YeT.png)
                        </br></br>
                        :::info
                        💡 最後可在左上方視窗中的「hls_ip/solution1/constraints/directives.tcl」看到Directives的設定結果  
                        💡 在檔案總管的檔案「hls_ip/solution1/directives.tcl」中也可看到Directives的設定結果
                        :::
    10. C simulation：按工具列的綠色箭頭-->「C Simulation」。結果將顯示在下方console欄。
    11. C Synthesis：按工具列的綠色箭頭-->「C Synthesis」-->設定Period。report出現後，檢查是否有slack/time violation。
    12. Co-simulation：**<font color="red">必須先將</font>**
        ```csharp
        #pragma HLS INTERFACE ap_ctrl_none port=return
        ```
        **<font color="red">這行註解掉，並且重跑一次C Synthesis！</font>** 接著按工具列的綠色箭頭-->「Cosimulation」-->第一個下拉式選單選擇「Vivado XSIM」，右側點選「Verilog」；第二個下拉式選單Dump Trace選擇「all」。完成後可按下工具列的![](https://hackmd.io/_uploads/H1jnL0Mxp.png)圖示檢視波形。
    13. Export IP：**要先將**
        ```csharp
        //#pragma HLS INTERFACE ap_ctrl_none port=return
        ```
        **這行還原，並且重跑一次C Synthesis！</font>** 接著按工具列的綠色箭頭-->「Export RTL」-->Export Format下拉式選單選擇「Vivado IP (.zip)」。
        > 由[Lab2 Workbook](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)，此步驟亦可稱為「**Export RTL**」


2. **Vivado:**
    1. Type in `vivado` in terminal
    2. GUI介面上按下「Create Project」
    3. 按Next
    4. 輸入Project name:「vivado」以及Location:「/home/ubuntu/course-lab_1」
    5. 勾選「Do not specify sources at this time」
    6. Parts輸入並選擇「xc7z020clg400-1」
    7. 按Finish
    8. Import IP（from Vitis HLS）：點擊左側欄的「Settings-->IP展開-->Repository-->+ --> 點選/home/ubuntu/course-lab_1/hls_ip -->select-->展開IPs-->點選Multip_2num [註3]-->OK-->OK」
    > [註3] 將IP repositories指定到前面的Vitis HLS專案目錄，接著匯入由Vitis HLS專案開發的IP [(資料來源)](https://github.com/bol-edu/course-lab_1/blob/2022.1/2022.1-Workbook-Lab1.pdf)
    9. Block Design：
        1. 點擊左側欄的IP INTEGRATOR下的「Create Block Design」-->OK-->在右上方Diagram視窗中按+ -->加入『ZYNQ7 Processing System』及『Multip_2num』這兩個components-->按下![](https://hackmd.io/_uploads/HysE2MXxa.png)重新整理-->按下上方綠色條中的<font style="background-color: Lime; color: blue">Run Block Automation</font>-->OK
        :::warning
        :warning: Run Block Automation會將ZYNQ的configuration重置，所以一定要**先「Run Block Automation」再完成底下的「ZYNQ的configure (例如PL Fabric clocks設定、PS-PL configuration設定)」** [(資料來源)](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)
        :::
        2. 設定ZYNQ的configuration：滑鼠左鍵雙擊ZYNQ7 Processing System的方塊圖-->點選Clock Configuration-->展開PL Fabric clocks-->FCLK_CLK0:『100』(單位: MHz) **<font color="red">[:warning:在按下OK前先注意下方說明]</font>** -->OK-->按下上方綠色條中的<font style="background-color: Lime; color: blue">Run Connection Automation</font> [註4]-->OK（若不能直接按OK則先勾選「All Automation」再按OK）-->若使用**AXI-Stream**的interface，則可能還會再出現<font color="blue">Run Connection Automation</font>的按鈕，一直按到沒有出現為止-->按下![](https://hackmd.io/_uploads/HysE2MXxa.png)重新整理-->檢查接線是否有誤-->手動接線(若需要的話)-->再點選Address Editor的tab檢視memory map
    > [註4] (For lab1) 因為此block design只有1個IP設計，故連線可由系統自動完成，直接執行Run Connection Automation即可 [(資料來源)](https://github.com/bol-edu/course-lab_1/blob/2022.1/2022.1-Workbook-Lab1.pdf)
    :::danger
    :warning: **特別注意**：若使用**AXI-Master / AXI-Stream**的interface，要特別設定下列configuration（這是因為AXI-Lite與AXI-Master / AXI-Stream在ZYNQ7 Processing System所使用的port不相同，所以必須開啟HP port設定 [(資料來源)](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)）：
    1. 滑鼠左鍵雙擊ZYNQ7 Processing System的方塊圖（前面的步驟已有做過）
    2. 開啟HP port設定：點選PS-PL Configuration-->展開HP Slave AXI Interface-->將SAXI HP0 interface右方的方框打勾☑️</br></br>
    
    :warning: **特別注意**：若使用**AXI-Stream**的interface，除了上述2點外，還要特別做下列AXI-Master to stream的步驟（這是因為AXI-Master to stream是利用Xilinx的DMA IP來實現的，故需設定此DMA IP）：
    
    3. 在右上方Diagram視窗中按+ -->加入「AXI Direct Memory Access」這個component
    4. 滑鼠左鍵雙擊AXI Direct Memory Access的方塊圖
    5. 將「Enable Scatter Gather Engine」取消勾選-->Width of Buffer Length Register (8-26)：「25」bits-->「『Enable Read Channel』及『Enable Write Channel』是否勾選：依照設計需求決定，可為『單一Read Channel』 or 『單一Write Channel』 or 『兩者』」-->OK
    6. 更改DMA blocks的名稱：在中上方視窗中的Design tag中-->對要改名的block按滑鼠右鍵-->「Block Properties...」-->更改Name欄位-->按鍵盤Enter。記得要改成跟python code中相同的DMA in/DMA out名稱，例如：axi_dma_in_0、axi_dma_out_0
    :::
    10. HDL Wrapper：在中上的視窗中點選Sources的tab-->展開Design Sources-->對design_1 (design_1.bd)按滑鼠右鍵-->Create HDL Wrapper...-->OK-->確認Tcl console（位於底下視窗）中有<br/><font color=blue>"add_files -norecurse /home/ubuntu/course-lab_1/vivado/vivado.gen/sources_1/bd/design_1/hdl/design_1_wrapper.v"</font><br/>這行產生
    11. Synthesis + Placement + Routing + Generate Bit-stream：要先經過Synthesis + Placement + Routing的步驟，最後才能產生bit-stream file給FPGA用。Vivado IDE提供一鍵自動執行這些步驟：在工具列按下![](https://hackmd.io/_uploads/HkIRh7Qxa.png)即可-->按下Yes-->調整Number of jobs的數目 [註5]-->OK-->等到＂Bitstream Generation Completed＂的視窗出現，即可直接關閉此視窗並完成bitstream的產生
    > [註5] Number of jobs越多則跑得越快 [(資料來源)](https://github.com/bol-edu/course-lab_1/blob/2022.1/2022.1-Workbook-Lab1.pdf)
    12. 可在底下的路徑中找到.bit及.hwh的檔案：
        ```console
        cd ~/course-lab_1
        cp ./vivado/vivado.runs/impl_1/design_1_wrapper.bit ./Multip2Num.bit
        cp ./vivado/vivado.gen/sources_1/bd/design_1/hw_handoff/design_1.hwh ./Multip2Num.hwh
        ``` 
        In general, 可寫成下列pseudo command：
        ```console
        cd ~/course-lab_???
        cp ./vivado_???/vivado_???.runs/impl_1/design_1_wrapper.bit ./?????.bit
        cp ./vivado_???/vivado_???.gen/sources_1/bd/design_1/hw_handoff/design_1.hwh ./?????.hwh
        ```



3. **onlineFPGA:**
    <!-- 112.10.3補上 -->
    > Reference: [OnlineFPGA 系統使用者手冊](https://drive.google.com/file/d/1Vx0e3m9EviOuqPVhowYVbgVunZxD828i/view)
    1. 使用MobaXterm將`Multip2Num.bit`以及`Multip2Num.hwh`下載到本機端
    2. 租借onlineFPGA board
    3. 複製租借到的板子的IP+port (`140.XXX.XXX.XXX:XXXX`)，在瀏覽器上輸入網址＂`http://140.XXX.XXX.XXX:XXXX`＂
    4. 輸入租借到的密碼
    5. 上傳 `Multip2Num.bit`、`Multip2Num.hwh` 以及 `Multip2Num.ipynb`
    6. 若有其他需要上傳的檔案（例如data）也上傳
    7. 滑鼠左鍵點擊`Multip2Num.ipynb`進入
    8. 執行程式碼並確認remote FPGA的執行結果正確
    9. 歸還onlineFPGA board
    

<br/>


<!-- 112.10.1開始 -->
## Lab 2: FIR design using HLS
此lab分為4個模式：
| board | interface |
|:---------:|:----------:|
| ZYNQ | AXI-Master |
| ZYNQ | AXI-Stream (或僅稱"Stream") |
| KV260 | AXI-Master |
| KV260 | AXI-Stream (或僅稱"Stream") |

1. ZYNQ+AXI-Master：  
    * 在Vitis HLS中要注意底下事項：
        :::danger
        :warning: 由[這個討論串](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/77)及[詳細資訊](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/42)得知：若使用Ubuntu VM，**FIRTester.cpp**中
        ```csharp
        // For Windows:
        if (system("fc .\\out.dat ..\\..\\..\\out_gold.dat")) {
            cout << ">> Test failed!" << endl;
            return 1;
        }
        ```
        要改成
        ```csharp
        // For Linux:
        if (system("diff ./out.dat ../../../out_gold_unix.dat")) {
            cout << ">> Test failed!" << endl;
            return 1;
        }
        ```
        :::
    
        <!-- :::danger
        :warning: 由[這個討論串](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/69)得知：**FIR.h**中要加入
        ```csharp
        #include <gmp.h>
        #define __gmp_const const
        ```
        to avoid `error: 'mpfr_srcptr' has not been declared.`
        ::: -->

        :::danger
        :warning: 由[這個討論串](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/69)得知：若在co-simulation時遇到`error: 'mpfr_srcptr' has not been declared.`，則在**FIR.h**中要加入
        ```csharp
        #include <gmp.h>
        #define __gmp_const const
        ```
        :::

        :::danger
        :warning: 由[lab2 Workbook](https://github.com/bol-edu/course-lab_2/blob/2022.1/2022.1-Workbook-Lab2.pdf)以及[這個討論串](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/42)的說明：由於out_golden.dat檔案來自Windows系統，所採用的換行符號(`\r\n`)和Linux系統所採用的(`\n`)不一樣，因此需先用
        ```console
        dos2unix -n out_gold.dat out_gold_unix.dat
        ```
        指令做轉換，其中語法為`dos2unix -n old_filename new_filename`，其中`-n`表示不要覆蓋掉原檔案。 [(參考資料)](https://stackdiary.com/linux-docs/dos2unix/)
        :::
    * 在Vivado以及onlineFPGA中要注意的事項已融合在[Lab 1](#Lab-1-From-Vitis-HLS-to-onlineFPGA)的說明中
2. ZYNQ+Stream：  
    * Vitis HLS中要注意的事項：  
        在此處的Directives Control是使用[Lab 1](#Lab-1-From-Vitis-HLS-to-onlineFPGA)中的「方法1（`#pragma`的方式）」，若直接使用上方ZYNQ+AXI-Master所Export的IP檔案，會在之後手動接線時發現此FIR的IP少了兩個port
    
    * Vivado中要注意的事項：
        1. 此lab中使用兩個DMA：其中一個設定為「單一Read Channel」作為DMA_in；另一個設定為「單一Write Channel」作為DMA_out
        2. 由[這個討論串](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/66)得知，DMA_out的block應命名為axi_dma_out_1（為了與python code中的名稱相同）
        3. 在此要手動接2條線：
            * fir_n11_strm的「pstrminput」 port要接到axi_dma_in_0的「M_AXIS_MM2S」 port
            * fir_n11_strm的「pstrmoutput」 port要接到axi_dma_out_1的「S_AXIS_S2MM」 port

<br/>

<!-- 112.10.7開始 -->
## Lab 3: FIR design using Verilog
==✏ **Prerequisite**: Introduction to AXI interface==
1. AXI4-Lite
    - [x] [Introduction to AXI4-Lite interface](https://www.realdigital.org/doc/a9fee931f7a172423e1ba73f66ca4081)
    - [x] [AXI4-Lite user guide](https://docs.xilinx.com/r/en-US/pg202-mipi-dphy/AXI4-Lite-Interface)
2. AXI-Stream
    - [x] [AXI-Stream Protocol Specification Documentation](https://developer.arm.com/documentation/ihi0051/latest/)
    - [x] [AXI-Stream user guide](https://docs.xilinx.com/r/en-US/pg256-sdfec-integrated-block/AXI4-Stream-Interface)

<br/>

<!-- 112.12.9~112.12.10開始 -->
## Lab 6: UART + Matrix_multiplication/Q_sort/FIR integration
1. 合成`vivado_only_UART`時有hold time violation --> 透過[這個討論區](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/158)的方法得以解決


<br/>


<!-- 113.1.11~開始 -->
## Lab D: SDRAM
- 觀察**sdram_controller.v**的發現：
    1. 「a_d」在INIT state會傳workbook中所謂的「Mode Register」(第196行)，在其他時候則是傳address
    2. 「refresh_ctr」是指refresh counter；「delay_ctr」是指delay counter
    3. 「dq」是指output給SDRAM的data
    4. 其中有一些「9:8」的記得要改成「BA」(bank address)；還有其他像是「22:10」之類的也要記得改
- 記錄一下有改到的部分：
    1. sdr.v第552行
        ```v
        /////Mode_reg <= 13'b000_1_00_011_0_000;//Addr;
        ⬇️⬇️⬇️
        Mode_reg <= Addr; // Modified
        ```
    2. sdram_controller.v中有註記「Modified」或「Added by us」的部分


<br/>

<!-- 112.9.30 -->
## 附註：使用Ubuntu VM上傳資料夾至Github的流程
==📌 事先準備（只需做一次）：==
1. 使用瀏覽器在Github上創建一個repository，在此我把它叫作SOC-design
2. 在Ubuntu的terminal上輸入
    ```console
    git clone https://github.com/whywhytellmewhy/SOC-design.git
    ```
3. 即可在Ubuntu上產生名為SOC-design的資料夾

<br/>

==📌 每當想要上傳資料夾至Github時：==
1. 在Ubuntu上SOC-design資料夾裡面創建名為「labXX」的資料夾
2. 將檔案丟進來「labXX」資料夾中

:::info
:warning: 注意：若原檔案所在之資料夾已有連結到其他人的Github，則需將資料夾「裡面」的東西複製出來到labXX才可
:::

3. 先將terminal到SOC-design所在的資料夾：
    ```console
    cd /SOC-design
    ```
    1. **(建議)** 先使用git pull確保local repository與remote repository兩者同步（會merge不同之處）：
        ```console
        git pull
        ```
        若本來就已同步則會回傳`Already up to date.`
    
    2. 將超過100MB的.vcd檔刪除：執行
        ```console
        source run_delete_big_files
        ```
        :::warning
        💡 此時可使用`source run_list_big_files`指令，會回傳剩下哪些超過100MB的檔案，若有出現路徑中有.git的檔案可以不用理它。
        :::
        
    3. 使用git add：
        ```console
        git add labXX
        ```
        :::warning
        💡 此時可使用`git status`指令，會回傳有哪些檔案/資料夾被增加/刪除/修改。
        :::
        :::warning
        💡 git add的相反指令為「git rm」
        :::

    4. 接著用git commit：
        ```console
        git commit -m "一些註記(雙引號要留著)"
        ```
        將這些更新上傳到local repository
        
    5. 最後用git push：
        ```console
        git push
        ```
        將這些更新上傳到remote repository（也就是Github的repository中）。
        
        :::danger
        :warning: **在git push後若有發生error而導致沒有成功上傳到remote repository時**：即使local端刪除掉導致error的檔案並再commit，仍會將這些檔案嘗試上傳而再度error。此時可透過
        1. **先備份檔案再說！！！**
        2. 使用`git status`得到有多少commit沒有成功上傳，例如下圖為「**6**個」
            ![](https://hackmd.io/_uploads/ryh0BtCGp.png)
        3. 使用`git reset --hard HEAD~「數目」`，例如上例中為`git reset --hard HEAD~6`
        4. 使用`git status`確認目前狀態為behind remote端
            ![](https://hackmd.io/_uploads/H1X1tFCz6.png)
        5. 使用`git pull`將remote端檔案pull到local端
        6. 確認要加入的資料夾有在本地端，若無則從備份複製過來
        7. 回到上方git add，重新執行上述步驟即可
        
        ([參考資料](https://gist.github.com/cutiko/0b1615c63504a940877541362cc51211))

        :::
        
:::success
✨:star:  <font color="blue">**整理如下**</font> :star:✨
```console
cd /SOC-design
git pull
git add labXX
git commit -m "一些註記(雙引號要留著)，例如「add labXX」"
git push
```
:::


<!-- 113.1.11 -->
## 附註(二)：多人協作Github的流程
參考資料：https://myapollo.com.tw/blog/git-tutorial-collaboration/

==📌 事先準備（只需做一次）：==
1. 使用瀏覽器在Github上的repository新增協作者，如下圖的位置
    ![image](https://hackmd.io/_uploads/BJWlCfaOp.png)
    
2. 協作者在Ubuntu的terminal上輸入
    ```console
    git clone https://github.com/whywhytellmewhy/SOC-design.git
    ```
    產生名為SOC-design的資料夾
    
3. 將terminal移到SOC-design所在的資料夾：
    ```console
    cd /SOC-design
    ```
    
4. (建議) 新增分支以避免與main分支衝突：
    ```console
    git checkout -b "???"
    ```
    其中`???`填入新分支的名稱，例如`final_project/myname`
    
    :::warning
    💡 此時可使用`git branch`指令，會回傳所有分支，**其中開頭有`*`的為目前所在分支**。
    :::
    
<br/>

==📌 每當**協作者**想要上傳資料夾至Github時：==
1. 先將terminal移到SOC-design所在的資料夾
    ```console
    cd /SOC-design
    ```

2. 使用`git branch`指令，會在螢幕上回傳所有分支，其中開頭有`*`的為目前所在分支。**確認所在的分支是否正確，若不正確，則使用 `git checkout ???`（???填入分支的名稱）轉換過去**

3. **<font color="red">刪除超過100MB的波形檔(.vcd)：</font>** 執行底下的指令即可
    ```console
    source run_delete_big_files
    ```
    :::warning
    💡 此時可使用`source run_list_big_files`指令，會回傳剩下哪些超過100MB的檔案，若有出現路徑中有.git的檔案可以不用理它。
    :::
4. 依序執行
    ```console
    git pull origin ???(分支名稱)
    git add .
    git commit -m "一些註記(雙引號要留著)，例如「add labXX」"
    ```
    
5. 最後執行
    ```
    git push origin ???
    ```
    其中`???`填入新分支的名稱，不需要加雙引號
    :::danger
    :warning: **在git push後若有發生error而導致沒有成功上傳到remote repository時**：
    1. **先備份檔案再說！！！**
    2. 使用`git reset --hard HEAD`
    3. 使用`git pull`將remote端檔案pull到local端
    4. 確認要加入的資料夾有在本地端，若無則從備份複製過來
    5. 回到上方git add，重新執行上述步驟即可
        
    ([參考資料](https://gist.github.com/cutiko/0b1615c63504a940877541362cc51211))

    :::
    
6. 協作者使用瀏覽器登入Github，會看到類似底下提示
    ![messageImage_1704977468011](https://hackmd.io/_uploads/BkPuNvT_p.jpg)
    點進去後可以在右側欄位選擇Reviewer，接著點選綠色底的<font style="background-color: green; color: white"> Create pull request </font>，再點選<font style="background-color: green; color: white"> Merge pull request </font>。

<br/>


## Reference
1. [Hackmd.io支援的特殊格式](https://hackmd.io/s/features-tw#%E6%AA%A2%E8%A6%96)
2. [How to Commit and Push Changes from Ubuntu 18.04 to GitHub](https://www.liquidweb.com/kb/committing-pushing-github-ubuntu-18-04/)
3. [支援的程式碼種類](https://support.codebasehq.com/articles/tips-tricks/syntax-highlighting-in-markdown)
4. 