---
# System prepended metadata

title: '[SoC_Study] Sheng08’s SOCStudy'
tags: [SOC Design, SoC Lab, SoCStydy]

---

# [SoC_Study] Sheng08's SOCStudy
###### tags: `SoCStudy`, `SoC Lab`, `SOC Design`

[ToC]

# My Github and Team Github
大家好，我是 Sheng08。此 Hackmd Page 紀錄本學期 **系統晶片設計 SOC Design** 課程相關學習內容與筆記!

- 📂 **GitHub Profile**: [https://github.com/Sheng08](https://github.com/Sheng08)
    - **My GitHub for SoC Repo**: [https://github.com/Sheng08?tab=repositories&q=SoC-Lab](https://github.com/Sheng08?tab=repositories&q=SoC-Lab)
- 💻 **GitHub Organizations**: [https://github.com/NYCU-SOC-Design-Team13](https://github.com/NYCU-SOC-Design-Team13)
    - 課程團隊的Repositories於此GitHub組織統整

---
# StudyJournal

## SoC Design overall system flow

![](https://i.imgur.com/6Irn9eG.png)

- Step
    1. C Simulation:
        * 利用 C/C++ 撰寫欲達成目標邏輯算法 → 運行C Simulation工具 → 驗證程式碼正確性
    2. C Synthesis:
        * 選擇合成設置 → 運行合成(Synthesis)工具 → 產生合成後的 report
    3. Co-Simulation:
        * 使用C模擬的輸入/輸出 → 運行合成的HDL模擬 → 比較結果
    4. Export RTL:
        * 從HLS工具中選擇輸出或導出RTL → 獲得HDL文件
    5. Implementation:
        > 在這個階段，HDL 被轉換成 FPGA 或 ASIC 的實際物理結構。
        > 選擇特定的 FPGA/ASIC → 運行 Implementation
        1. Synthesis (within Implementation):
            * 將HDL 轉換為一個 Netlist，這個 Netlist 包含邏輯閘、Flip-flop等之間的連接
        2. Placement:
            * 決定 Netlist 中，每個元件在 FPGA 或 ASIC 物理布局上的位置
        3. Routing:
            * 確定如何在 FPGA 或 ASIC 中連接這些元件，以形成完整的設計
        4. Generate Bit-stream:
            * 創建一個代表整個 FPGA 配置的文件，可被下載到 FPGA 上執行

而 "Export RTL" 後，可進行 Block Design (系統集成)，使用圖形化介面連接不同的 IP 模組，也可以包含從 HLS 或其他來源導入的自定義 IP (Intellectual Property)。

## What is Vitis-HLS

Vitis-HLS (Vitis High-Level Synthesis)，為基於 C++ 的開發工具，可以高階語言轉換為RTL語言。

使用此設計流程，開發者可直接利用 C/C++ 來描述演算法及Test Bench，執行 C Simulation 驗證設計的正確性。接著，透過高階合成工具，完成 C/C++ 轉換到 RTL。同時也需要考慮延時、時序以及資源的問題。然後，依照 RTL 設計流程，使用軟體工具進行 RTL 電路的合成、佈局以及佈線。最終，在系統層面上對整體設計進行驗證和修正。

![](https://i.imgur.com/6voejSt.png)
> Ref: https://xilinx.eetrend.com/blog/2022/100560242.html


## What is TestBench
- 使用同一 TestBench 進行 C/RTL Co-simulation
- 將用於合成的**Top Function**（核心功能）與 Test Bench 及 header file 分開
    - Testbench 模擬的是對Top Function的整體測試，確保整個系統在集成後能正常工作
![image](https://hackmd.io/_uploads/ryqDqjAua.png)
> Ref: 
> Testbench Hierarchy: https://blog.csdn.net/bleauchat/article/details/90634328
> IThome [Day8]testbench 1/3: https://ithelp.ithome.com.tw/articles/10192221

## C-simulation v.s. Co-simulation
![image](https://hackmd.io/_uploads/H1LOioAuT.png)
- C-simulation：
    - TestBench 和 Top Function 編譯成單一執行檔進行模擬
- Co-simulation：
    - Top Function 在模擬器中運行，而資料則透過 TestBench 和模擬器啟動的行程(Proccess)進行傳輸
> Ref:
> What is the difference between "C Simulation" and "C test bench in Cosimulation"? https://support.xilinx.com/s/question/0D52E000073ylp9SAA/what-is-the-difference-between-c-simulation-and-c-test-bench-in-cosimulation?language=en_US
> 

## Top Funciton 與 Host 溝通方式

![image](https://hackmd.io/_uploads/r11A2iRd6.png)

### **Block Protocol (Block-Level Interface Protocol)**
- 在Block Protocol中，資料以 "Block" 的形式進行傳輸。這意味著資料被分成大的 Block，然後一次性傳輸
- 通常用於大資料量的傳輸，如：在記憶體和存儲設備之間
- 在`s_axilite`上指定（如：ap_ctrl_hs、ap_ctrl_chain、ap_ctrl_none）
- **控制訊號**：
    ```
    0x00: control signals
      bit 0 - ap_start (R/W/COH)
      bit 1 - ap_done (R/COR)
      bit 2 - ap_idle (R)
      bit 3 - ap_ready (R)
      bit 7 - auto_restart (R/W)
    ```
   - **ap_start (R/W/COH)**： Start kernel。可讀寫，COH（Clear on Handshake）表示當 handshake 完成後會自動清零
   - **ap_done (R/COR)**：表示核心操作已完成。唯讀，COR（Clear on Read）表示讀取後自動清零
   - **ap_idle (R)**：當核心處於空閒(idel)狀態並準備接受新輸入時，為高
   - **ap_ready (R)**：當核心準備好開始新的操作時，為高
   - **auto_restart (R/W)**：設定核心在完成操作後是否自動重新啟動
2. **流程**：
   - 當 Block-Level Protocol 開始操作後，將使用 Port-Level I/O 協定來順序地將資料輸入和輸出核心。
3. **控制**：
   - 使用 `AP_CTRL_HS`（Handshake Control）協定來控制核心
   - 透過 `#pragma HLS INTERFACE ap_ctrl_hs port=return` 來設定介面
   - 只能在當前執行完成（即 `ap_done` 為 high）後被重新啟動（設置 `ap_start` 為 1）。
4. **與 Host 互動**：
   - 使用 `s_axilite` 協定來控制 HLS 核心
   - 可以將多個 Port 組合到 axilite 中
   - 為了開始操作，將 `ap_start` 設置為 1
   - **開始讀取輸入之前，資料必須準備好**
   - Host 可以透過讀取記憶體 Mapping 的 register 來確認核心的狀態

### **Port Protocol (Port-level Interface Protocol)**
   - Port Protocol 通過特定 Port 進行資料交換。這些 Port 可以是物理的（如I/O）或虛擬的（如軟software interface）。
   - 資料通常以較小的單元（如 bit, bytes）進行傳輸
   - 適用於需要頻繁且低延遲交換少量資料情況，如: 感測器資料讀取或**控制訊號**傳輸
   - GPIO（General Purpose Input/Output） Port，
       - 用於讀寫個別的 bit 或 小資料 block。
- **AXI Protocol**
    > * interconnect-bus-opt.pdf (主要)
    > https://www.youtube.com/watch?v=bNZPzd0WjVM&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=18
    > * interconnect-axi.pdf
    > https://www.youtube.com/watch?v=GfXhuWJN930&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=16
    > <br>
    > ![image](https://hackmd.io/_uploads/B1i8U3A_T.png =500x)
   - `AXI4-Lite`（`s_axilite`）：
       - scalar inputs (e.g. int)
       - 用於將多個參數組合到同一個 AXI4-Lite
       - 通常用於傳送控制訊號、配置參數或小資料量的傳輸
       - AXI4-Lite 不支援突發傳輸(Burst Transfers)
           - 只有32bit sigle cycle
           - ARM CPU promgramg hw 的 GP port 用 axi-lite
       - ![image](https://hackmd.io/_uploads/r1c-O3Rdp.png)
   - `AXI4-Master`（`m_axi`）：
       -  適用於需要大量資料處理和高速資料傳輸的應用，如: 存取外部記憶體
       -  用於處理**陣列或指標**，可以將多個 Port 組合起來
       -  支援突發傳輸(burst length 越大，需要越多buffer，連續儲存可以 burst)
       -  Pipeline Request
       -  Host 創建 buffer 儲資料，並透過 `s_axilite` 介面指定記憶體位址空間的基底位址(base address)
       -  ![image](https://hackmd.io/_uploads/rJ7_P3COp.png)
   - `AXI4-Stream`（`axis`）：當C函數的參數指定為hls::stream時使用
       - 專門用於**連續**資料流的傳輸
       - 特點是不包括 address channel，可以進行**高速且連續**的資料流傳輸，無需每次傳輸都進行位址定位
       - ![image](https://hackmd.io/_uploads/B1Urd2AuT.png)
       - 沒有位址概念，需要 DMA（Direct Memory Access）傳輸
           - 直接在 Host 和外部設備之間傳輸，無需CPU介入
- Address interleave memory stripping:
    - 不同addr在不同range
- Set number of outstanding request – to hide memory latency
    - 減少latency

## Concept about interrupt
- 中斷允許外部設備或其他硬體事件能夠取的處理器的控制，從而使處理器能回應較緊急操作或重要任務
- 當中斷發生時，當前正在執行的**程序或操作**會被**暫停**，處理器轉而處理中斷請求
1. **中斷處理流程：**
   - 雖然中斷可能在處理器的任何 Pipeline Stage發生，但通常在寫回階段（Write-Back, WB Stage）進行檢查和處理
       - 即便中斷信號在早期階段被觸發，**處理器會在目前指令執行完成後才處理中斷**
   - ![](https://hackmd.io/_uploads/rkOrk7bNT.png =400x)
2. **中斷類型：**
   - **軟體中斷（Exception）：** 這類中斷是由程序中的異常情況引起的，如：除以零錯誤、頁面錯誤(Page fault)等
   - **硬體中斷：** 硬體中斷通常由外部事件觸發，如：外部設備的訊號或其他硬體訊號(e.g. 鍵盤)
   - 軟體和硬體中斷都需要處理器暫停當前任務，並跳轉到對應的中斷處理程序
       > ![中斷類型示意圖](https://hackmd.io/_uploads/HkBsu4-E6.png =500x)
       > 
       > ![硬體中斷示意圖](https://hackmd.io/_uploads/HJX2dNbVa.png =500x)

## Cache organization
* Video ref:
    - https://www.youtube.com/watch?v=kqp8G-hwjSo&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=19

![image](https://hackmd.io/_uploads/HJu-000_a.png =300x)

1. **Tag：**
   - Tag 是用來唯一識別存儲在 cache 中的資料。存儲與該資料相關的Linear Address
   - 當處理器查找 cache 時，會將記憶體請求的 Tag 與 cache 中存儲的 Tag 進行比較，以確定所需資料是否已經在 cache 中 
2. **Index：**
   - Index 用於選擇 cache 中的特定 Block 或行（Slot/Entry）
   - 決定處理器應該在哪個 cache line 進行 Tag 比較
   - Index 基本上是將大量的快取內容分割成可管理的小塊，使得資料查找更加快速有效
3. **Offset：**
   - Offset 在一個 cache block 中資料的具體位置。確定了資料在 cache block 內的確切起始點
   - 一個 Cache block 可能包含多個位址的資料

## Average memory access time
* Video ref:
    -  https://www.youtube.com/watch?v=kqp8G-hwjSo&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=19

![](https://hackmd.io/_uploads/BJe8pygE6.png =500x)

## Address decoding

* ![截圖 2023-11-15 上午9.31.32](https://hackmd.io/_uploads/BJstkj-46.png =500x)

* ![截圖 2023-11-15 上午9.31.55](https://hackmd.io/_uploads/HkYcJoZEp.png =500x)

## Amdahl’s law
* 參考資料:
    1. https://hackmd.io/@kwei/HJXtaPoI9
    2. https://www.inlighting.org/archives/amdahls-law-and-its-proof

![image](https://hackmd.io/_uploads/rkotiC0_6.png)

![image](https://hackmd.io/_uploads/BJcLjR0Oa.png =300x)

## Data hazard – identify data hazard, and its solution
* Video ref:
    -  Hazard and Forwarding: https://youtu.be/OkC9qy1L31I?si=4rt5g38up-90uKQi
    -  Hazard and Stall: https://youtu.be/E2PeWi24GYQ?si=gmQVYDDoavwCiOC6
    -  Load Use Hazard – Conditions and Stalls: https://youtu.be/SbK6cGoC0sY?si=xuvWRBlq8SgIk4Vh
    -  Branch Hazard: https://youtu.be/DjmIjF1YWeY?si=EyreBGSet51IAAkI

* 每個指令的執行錯開一個cycle，避免不同指令在相同時間使用同一元件
![截圖 2023-11-14 上午12.40.29](https://hackmd.io/_uploads/rkhKZRyVp.png =500x)

![截圖 2023-11-14 上午12.12.49](https://hackmd.io/_uploads/Sya-ipJN6.png =500x)

![截圖 2023-11-14 上午12.14.24](https://hackmd.io/_uploads/HJAvs61Vp.png =500x)

![截圖 2023-11-14 上午12.17.23](https://hackmd.io/_uploads/H1eQ2pJNa.png =500x)

![截圖 2023-11-14 上午12.24.37](https://hackmd.io/_uploads/BJf0paJE6.png =500x)

![截圖 2023-11-14 上午12.28.03](https://hackmd.io/_uploads/Hkbo0TJEa.png =500x)

## Load-to-Use hazard elimination
* stall => pipeline 暫停
![截圖 2023-11-14 上午2.20.18](https://hackmd.io/_uploads/HJ61KkeVT.png =500x)

![截圖 2023-11-14 上午2.19.56](https://hackmd.io/_uploads/ryYRuJlNp.png =300x)

## HLS loop unroll
* Video ref:
    - https://youtu.be/R4KWfKh-uLE?list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&t=4962

* ==Unroll = Data Parallelism==

![截圖 2023-11-14 上午4.04.08](https://hackmd.io/_uploads/BJGIZWeEa.png =500x)

![截圖 2023-11-15 上午9.38.12](https://hackmd.io/_uploads/HyiMZibNa.png =500x)

## Accelerator execution model and Programming sequence
![截圖 2023-11-15 上午9.46.45](https://hackmd.io/_uploads/HJzzXj-NT.png)

## Dataflow v.s. Pipeline

1. **定義**：
   - **Pipeline**：指的是將一個大的任務分解成多個小步驟，這些步驟依序執行，每個步驟處理的資料可以流向下一個步驟。在SoC設計中，pipeline通常用於提高處理器的效率，如：在CPU的指令執行中。
   - **Dataflow**：指的是資料在系統中的流動方式。在SoC設計中，dataflow關注的是如何在不同的處理單元間高效地移動資料，以及資料的存儲和訪問模式。
2. **應用範圍**：
   - **Pipeline**：通常用於處理器設計中，例如在指令集架構（ISA）和微架構設計中實現。
   - **Dataflow**：廣泛應用於SoC的整體設計，包括記憶體架構、I/O系統和網路介面等。
3. **性能優化**：
   - **Pipeline**：透過減少處理器閒置時間和提高指令處理速度來優化性能。
   - **Dataflow**：透過優化資料路徑和存取模式來降低延遲和提升數據處理速度。

## What is Dataflow 

1. **計算觸發方式**:
   - **Dataflow**：在這種設計中，計算的執行是由資料的到達觸發的。只有在所有必要的輸入資料都準備好時，相關的計算或處理步驟才會啟動。
   - **傳統設計**：計算的進行通常遵循預先定義的、按順序執行的指令流程，這些指令流程不直接依賴於資料的到達。
2. **資料流動與控制流**:
   - **Dataflow**：這種設計的重點在於==資料的流動方式==。程序的結構和行為主要取決於資料如何在系統中移動。
   - **傳統設計**：更加==關注控制流==，即程序的執行順序和條件分支。
3. **並行性和平行處理**:
   - **Dataflow**：支持並行和平行處理，因為不同的計算單元可以同時處理各自的資料流。
   - **傳統設計**：並行性和平行處理通常需要額外的設計和考慮，如使用執行緒、進程。
4. **可擴展性和靈活性**:
   - **Dataflow**：由於其模組化和decoupling(解耦)的特性，易於擴展和重組，可以靈活地添加新的處理元件或修改現有流程。
   - **傳統設計**：擴展和修改可能相對困難，尤其在緊密coupling(耦合)的系統中，改變一部分可能需要對其他部分進行廣泛調整。
5. **對錯誤和異常的處理**:
   - **Dataflow**：錯誤和異常可以在資料流中被局部化處理，不必影響整個系統。
   - **傳統設計**：錯誤處理通常需要通過控制流來管理，並可能涉及程序的多個部分。
6. **實現和維護**:
   - **Dataflow**：可能需要特定的工具和框架來實現和維護。
   - **傳統設計**：可以利用更廣泛的開發工具和技術。

* Dataflow
    - How to schedule data and computation in hardware resources over space and time
        > ![image](https://hackmd.io/_uploads/SkxZzoR_a.png)
        > Ref: https://inst.eecs.berkeley.edu/~ee290-2/sp20/assets/labs/lab2.pdf
* Mapping
    - A dataflow for a specific input shape with concrete tiling sizes 
    - Spatial: 同一時間點不同運算資源 => 跨**空間**
        - Spatial Reuse: 同一時間點將同相同資料分配給不同運算單元(PE)
    - Temporal: 不同時間點資料使用狀況 => 跨**時間**
        - Temporal Reuse: 概念有overlap時，下一時間點使用到上次的部分資料
    > ![image](https://hackmd.io/_uploads/H1W8GiCda.png)
    > Ref: 
    > Understanding Reuse, Performance, and Hardware Cost of DNN Dataflows: A Data-Centric Approach Using MAESTRO
    > https://arxiv.org/abs/1805.02566

## Caravel SOC
* Caravel SOC Brief: https://youtu.be/MBXKNe3kahw?si=1Hd6u3Fp5u1lTilz
    >  ![image](https://hackmd.io/_uploads/BJQAKn0up.png)
* Reference
    - https://github.com/efabless/caravel/
    >  ![image](https://hackmd.io/_uploads/H1bT3hC_6.png)
* HouseKeeping SPI register Access
    1. **Front Door (SPI):**
       - The front door access is achieved through the SPI interface. 
       - SPI, or Serial Peripheral Interface, is a common communication protocol used in microcontrollers for connecting with peripherals.
       - In the context of the Caravel SoC, the SPI interface is connected to the padframe. A padframe is a layout structure in a chip that allows for connection points for external signals.
       - This connection is made through GPIO (General-Purpose Input/Output) pins, which are versatile pins that can be programmed to perform either input or output functions.
    2. **Back Door (MMIO):**
       - The back door access is done through the MMIO (Memory-Mapped I/O) method using the Wishbone interface.
       - Wishbone is a standard bus (a communication system that transfers data between components inside a computer) architecture used in microcontrollers and SoCs for connecting different components.
       - MMIO allows the device to access the memory locations in the same way it accesses regular RAM. This means that the registers of the device are mapped to certain memory addresses.
       - In the Caravel SoC, this interface is connected to the management SoC, facilitating a method for memory-mapped control and status registers.
    > ![image](https://hackmd.io/_uploads/Hy8gpnRdT.png)

## Memory
* Video ref:
    1. https://www.youtube.com/watch?v=Ha0SZcsjotQ&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=20
    2. https://www.youtube.com/watch?v=whPr5KNTOhI&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=21

![image](https://hackmd.io/_uploads/BkWBkTRuT.png)
### DRAM statements
* Channel: 獨立的 Address Line 和 Data Line
* DIMM: 一個記憶體; 一個面叫做Rank

> ![截圖 2023-11-15 下午1.49.07](https://hackmd.io/_uploads/Syzk2CbVa.png =400x)
> 
> ![截圖 2023-11-15 下午1.50.27](https://hackmd.io/_uploads/BJ-VnA-N6.png =400x)
### DRAM
* 結構
    - Flash memory cells on the same wordline are belonging to a flash page
    - Channel -> Chip -> Die (32 Gb) -> Plane -> Block -> Pages -> Cell
        - 1 Die = 2 * 1024 * 512 * 4KB = 4GB = 32Gb
        - 1 Die = 2 plane
    - ![image](https://hackmd.io/_uploads/SJSe-TRd6.png)
    > Ref: https://www.gamersnexus.net/guides/1497-ssd-architecture-1-what-is-tlc-nand-mlc-anatomy/Page-2
* Access Granularity
    * Read/Write Granularity: Flash page (4KB ~ 16KB)
    * Erase Granularity: A block comprises a lot of Flash Pages (e.g., 512)
    * Cannot erase and write only a page
        * Challenges: Erase unit > Write unit, shall follow the sequential write constraint
    > ![image](https://hackmd.io/_uploads/SJ6ib60ua.png)
    > ![image](https://hackmd.io/_uploads/HJPpZTA_6.png)
* **Erase-before-Write** property inside each block

#### DRAM Access Sequence
![image](https://hackmd.io/_uploads/S1RdK6COT.png)

關於DRAM（動態隨機存取記憶體）的操作命令，我們可以用以下的方式來解釋：

1. **Row Access Command（Activate(激活）)：**
   - 將資料從DRAM陣列中的單元移至 sense amplifiers
   - 資料會被 restore 並存回DRAM陣列中的單元
   - Access Command 操作本身會破壞存儲的資料
   - ![image](https://hackmd.io/_uploads/S1rz3TCuT.png)
2. **Column Read Command (Read)：**
   - 將資料從某一 DRAM bank 的 sense amplifiers 陣列通過 data back 移動到 controller
   - 從DRAM讀取資料到處理器或其他元件的過程
   - ![image](https://hackmd.io/_uploads/r1Cf2a0Op.png)
3. **Column Write Command (Write)：**
   - 從 controller 將資料移至目標 bank 的 sense amps
   - 將資料寫入DRAM的步驟
   - ![image](https://hackmd.io/_uploads/ByPXnp0up.png)
4. **Precharge：**
   - Precharge 完成 row access sequences，重置 sense amps 和 Bitlines，並為對同一DRAM單元陣列的另一個 row access command 做準備
   - 此步驟確保DRAM可以迅速地對新的存取command作出回應
   - ![image](https://hackmd.io/_uploads/HkzEnpR_T.png)
5. **Refresh：**
   - Refresh 確保將完整的值存儲到DRAM單元中
   - 由於DRAM的特性，資料會隨著時間逐漸流失，因此需要定期 Refresh 以保持資料的完整性
   - ![image](https://hackmd.io/_uploads/S16E3TAdT.png)

### SDRAM 

### SRAM model
* Video ref:
    * https://youtu.be/SiIH3PBk3Ak?list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&t=4535
* LUT RAM (Distributed RAM)
    * Synchronous write / Asynchronous read
* Block RAM - FIFO
    * Synchronous w/r

![截圖 2023-11-14 下午8.29.02](https://hackmd.io/_uploads/SkifO1WEp.png =500x)

![截圖 2023-11-14 下午9.18.55](https://hackmd.io/_uploads/rku1VeZEp.png =500x)

#### SDRAM controller design
![image](https://hackmd.io/_uploads/rJ6CF98_T.png)
> Ref: https://github.com/bol-edu/caravel-soc_fpga-lab/blob/main/lab-sdram/LabD-sdram_workbook.pdf

* 各狀態說明：

| 狀態                   | 說明                                        |
| --------------------- | ------------------------------------------- |
| INIT (初始化)          | 初始化記憶體參數和設定。包括設定時序參數、模式註冊等 |
| IDLE (閒置)            | 等待接收記憶體操作命令                         |
| ACTIVATE (激活)        | 激活特定記憶體 Row 以進行存取(Read 或 Write)    |
| WRITE (寫入)           | 向已激活 Row 指定的 Col 寫入資料               |
| READ (讀取)            | 從已激活 Row 指定的 Col 讀取資料               |
| READ_RES (讀取回應)     | 處理從記憶體**讀取**的資料回應                 |
| PRECHARGE (緩啟動/預充電)| 關閉記憶體 Row 以準備下一操作命令              |
| REFRESH (刷新)         |  刷新記憶體以維持記憶體中存儲的資料穩定           |

> 上述皆由 controller 進行記憶體的管理與各項操作。
> 
>:rocket: 補充：
> * REFRESH 為了維持記憶體中存儲資料的穩定，需不斷刷新，也分成兩種模式：
> 1. **Auto Refresh (自動刷新):** 在這種模式下，controller 負責定期發送刷新命令，以確保所有記憶體單元都獲得刷新。在執行自動刷新前，必須先將所有處於激活狀態的 bank 進行 PRECHARGE，以確保記憶體行對刷新命令做出正確反應。
> 2. **Self Refresh (自我刷新):** 此模式允許 SDRAM 獨立於外部 controller 進行刷新操作，通常在系統進入低功耗狀態時使用。自我刷新模式下，SDRAM 內部邏輯會自動進行刷新週期，不需外部 controller 介入。


* FSM 說明：

| 狀態轉換序列 | 說明 |
|---------------|----------------------|
| INIT → IDLE | 初始化所有 bank（設定時序、模式等），並進入閒置狀態，準備接收指令 |
| IDLE → ACTIVATE → WRITE → IDLE | 在特定 bank 的閒置狀態下，激活記憶體 Row，執行**寫入**操作，然後該 bank 回到閒置狀態 |
| IDLE → ACTIVATE → READ → READ_RES → IDLE | 在特定 bank 的閒置狀態下，激活記憶體 Row，執行**讀取**操作，處理讀取回應，然後該 bank 回到閒置狀態 |
| IDLE → WRITE → IDLE | 在特定 bank 的閒置狀態下，直接執行**寫入**操作（假設該 Row 已激活），然後該 bank 回到閒置狀態 |
| IDLE → READ → READ_RES → IDLE | 在特定 bank 的閒置狀態下，直接執行**讀取**操作，處理讀取回應，然後該 bank 回到閒置狀態 |
| IDLE → PRECHARGE → ACTIVATE → WRITE → IDLE | 在特定 bank 的閒置狀態下，進行 `PRECHARGE`，激活記憶體 Row，執行**寫入**操作，然後該 bank 回到閒置狀態 |
| IDLE → PRECHARGE → ACTIVATE → READ → READ_RES → IDLE | 在特定 bank 的閒置狀態下，進行 `PRECHARGE`，激活記憶體 Row，執行**讀取**操作，處理讀取回應，然後該 bank 回到閒置狀態 |
| IDLE → PRECHARGE → REFRESH → IDLE | 在特定 bank 的閒置狀態下，進行 `PRECHARGE` 和 `REFRESH` 以維持數據穩定，然後該 bank 回到閒置狀態 |

> SDRAM 通常被分割成多個 bank，每個 bank 可以獨立操作(允許 controller 同時在不同的 bank 上執行不同的操作)，從而提高整體存取效率和總體性能。

### SDRAM bus protocol
![image](https://hackmd.io/_uploads/rkMiZ2IO6.png)

* 外部訊號：
    > 這些訊號用於控制 SDRAM 的操作和資料傳輸
    > 
    > <img src="https://hackmd.io/_uploads/ryyKR2IOa.png" width="500">

    | 訊號類型  | 訊號名稱   | 說明 |
    |----------|----------|------|
    | 時脈相關 | `clk` | 同步時脈訊號 |
    |         | `Cke` (Clock Enable, `sdram_sle`) | 為 clk 訊號的 enable |
    | 基本控制 | `Cs_n` (Chip Select, `sdram_cs`) | Chip 選擇，控制裝置回應 |
    |         | `Cas_n` (Column Address Strobe, `sdram_cas`) | 控制 Column Address 的讀取 |
    |         | `Ras_n` (Row Address Strobe, `sdram_ras`) | 控制 Row Address 的讀取 |
    |         | `We_n` (Write Enable, `sdram_we`) | write 的 enable 的訊號 |
    | 資料控制 | `Dqm` (Data I/O Mask, `sdram_dqm`) | 資料位的讀寫控制，可控制 I/O port 取消那些輸入或輸出的資料 |
    |         | `Ba` (Bank Address, `sdram_ba`) | Bank 的位址。用於選擇哪一個 Bank |
    |         | `Addr` (Address, `sdram_a`) | 指定 Column 或 Row Address |
    | 資料傳輸 | `Dqi` (Data Input, `sdram_dqi`) | 資料輸入訊號 |
    |         | `Dqo` (Data Output, `sdram_dqo`) | 資料輸出訊號 |

* 內部訊號：
    > 這些訊號為 SDRAM Controller 內部用來管理記憶體操作
    > 
    > ![image](https://hackmd.io/_uploads/BywCR3Uua.png)

    | 訊號名稱 | 說明 |
    |----------|------|
    | `Activate_enable` | 啟用(激活)特定 Row 的操作。並等待 `Read_enbale` 或 `Write_enable` |
    | `Aref_enable`     | 自動刷新(auto refresh)操作的 enable 訊號                   |
    | `Burst_term`      | 截斷 Read / Write 操作中的 Burst 傳輸                      |
    | `Mode_reg_enable` | 模式註冊的 enable 訊號                                    |
    | `Prech_enable`    | PRECHARGE 操作的 enable 訊號                             |
    | `Read_enable`     | 啟用(激活) Column Address 以進行**讀取**操作                    |
    | `Write_enable`    | 啟用(激活) Column Address 以進行**寫入**操作                     |

:rocket: 補充：
* 「Strobe」：
    通常指的是一種用來同步或指示特定事件或操作的訊號。這種訊號通常用於控制數據的讀取或寫入時機，確保資料在正確的時刻被送入或從某個設備中讀出。例如：
    * **RAS (Row Address Strobe):** 用於控制行地址的讀取時機。
    * **CAS (Column Address Strobe):** 用於控制列地址的讀取時機。
* Burst Termination(`Burst_term`):
    - **終止當前突發傳輸：** 當執行突發終止命令時，正在進行的連續讀寫操作會被立即中斷
    - **適用於各類突發長度：** 無論是固定長度或整頁長度的突發傳輸，都可被此命令終止
    - **不涉及記憶體 Row 的關閉：** 執行突發終止命令不會 PRECHARGE 或關閉當前激活的記憶體 Row
    - **需單獨 PRECHARGE 以關閉 Row：** 若需關閉被激活的記憶體 Row，必須執行額外的 PRECHARGE 操作
* 突發傳輸（Burst Transfer）:
    - 是一種記憶體或資料傳輸的模式，其中資料以**連續的快速序列傳輸**，而不是單個 Byte 逐一傳輸。這種傳輸模式通常用於提高資料傳輸的效率，尤其是在大量資料需要被快速讀取或寫入記憶體時。
    - 在突發傳輸模式中，一旦開始傳輸，資料將連續不斷地流動，直到達到預設的傳輸數量（例如: 一定數量的 Byte 或 Word ）。這種方式減少了每次資料傳輸前後所需的設定時間，從而提高整體傳輸速率。
    - 在許多高速記憶體和儲存設備中，如: SDRAM(同步動態隨機存取記憶體)等，用於最大化資料處理效率和Bandwidth利用率。


## :memo: Terminology

* **C Simulation:**
    - 目的: 驗證C/C++的算法邏輯正確性
    - 說明: 為初步的模擬階段，只涉及C/C\++程式，**不涉及任何硬體描述語言**。基本上，這階段確保C/C\++程式在未進行任何合成或硬體轉換的情況下運行正確性
    - 結果: 若發現錯誤，需要於這階段修改C/C++程式
* **C Synthesis:**
    - 目的: 將轉換C/C++到硬體描述語言 (HDL)，如 VHDL 或 Verilog。
    - 說明: 高階合成 (HLS) 工具會嘗試**將C/C\++程式碼轉化成硬體結構**。在這階段，可能需要進行優化或改善，以達到所需的**clock速度、資源使用或功耗**
    - 結果: 得到合成後的報告(`csynth.rpt`)，包括估計的資源使用、性能(Performance)等
* **Co-Simulation:**
    - 目的: 驗證合成後的HDL程式碼與C/C++原始碼的**行為**是否一致。
    - 說明: 在這階段，原始C/C++程式碼和其合成的HDL程式碼將**同時模擬**。這是確保合成後的HDL實現與原始演算邏輯在功能上保持一致
    - 結果: 若發現差異或問題，需回到C Synthesis階段，調整優化指令或更改C/C++程式，然後重新合成和模擬
* **Export RTL:**
    - 目的: 生成代表特定設計的硬體描述語言 (HDL)，如 VHDL 或 Verilog。
    - 說明: 在完成高階合成 (HLS) 後，已從其C/C++ 轉換為硬體結構。而 "Export RTL" 將硬體結構生成為可用於標準 FPGA 或 ASIC toolchain 的 HDL 程式碼的過程
    - 結果: 生成的 HDL 可以被整合到更大的系統中，或者直接使用在 FPGA 或 ASIC 設計中
* **IP (Intellectual Property):**
    - 目的: 封裝特定的設計或功能以便**重複使用**
    - 說明: IP 是指一個已經設計好的、可以重複使用的功能或子系統。IP 可為自己設計，亦可為第三方供應商提供。當設計被合成並驗證無誤後，可被封裝成一個 IP，以便在其他設計中重複使用或共享
    - 結果: 生成的 IP 模組通常以標準格式提供，如：Xilinx 的 AXI4 接口，允許被整合到更大的系統中

## 📌觀念補充
-  在 HLS 中，"pragmas" 和 "directives" 通常指同樣的東西，都是用於指導合成過程的指令。允許優化和指導合成過程，而不必大量修改 C/C++ 的原始碼。
-  reg (register) 為存儲單元。在 FPGA 設計中，register 是用來保存狀態或資料的基本元件，由`flip-flops`構成。
    * `regIP = ol.multip_2num_0`，代表 IP 核心的物件，可通過 Python 存取的 register
        * 每個在 FPGA overlay 中的 IP 都可利用其名稱於 Python 存取和控制
- `Overlay`: 將 bitstream 載入到 FPGA，並將相應的硬體設計在 FPGA 上執行
    * MMIO (Memory-Mapped I/O): 允許 CPU 使用常規的記憶體存取指令，如：load 和 store
        * 特定 I/O 裝置的 register 或控制位會**映射(mapping)到系統的主記憶體地址空間中的某些位置**
    * 在 PYNQ 環境中，利用 MMIO 直接訪問 FPGA 上的 MMIO 地址空間，能夠讀取與寫入 FPGA 中的硬體 register
    * 使用 Overlay 載入 FPGA 設計時，各個 IP 核心可能有屬於自己的 MMIO 地址範圍，允許從 Python 存取和控制這些核心
- ALU(算術邏輯單元)
    * https://zh.wikipedia.org/zh-tw/%E7%AE%97%E8%A1%93%E9%82%8F%E8%BC%AF%E5%96%AE%E5%85%83
    * MUX
        * 優：1. Area 小 2. timing fast
        * 缺：output loading 影響input ; timing chat off ; routing congection
    * latch:
        * 優點：area 小 ; timging fast
        * level-trigger
    * DFF
        * 優點：
        * edge trigger
    * DUT v.s LUT v.s. BRAM?
- DUT - Device Under Test：
    * DUT 是指在硬體設計和驗證過程中，正處於測試階段的裝置。這可能是任何電子元件或系統，像是晶片、電路板或整體電子裝置
    * 在晶片設計方面，DUT 通常指新開發的半導體晶片。這些晶片在量產前，需要經過一系列的功能性測試和性能評估，以確保它們達到所有功能和性能的標準
    * 測試可能包括了功能性驗證（確保裝置能如預期般運作）、性能評估（測量裝置的速度、耗電等）及耐久性測試（確保裝置在長期使用下仍能維持性能）
- LUT - Look-Up Table）：
    * LUT 是一種用來儲存預先計算結果的資料結構，其目的在於加快計算速度。透過查詢表格中的值，可以避免進行複雜或耗時的計算
    * FPGA 中的 LUT 可以被設定來實現特定的邏輯操作，如基本邏輯閘或更複雜的功能
- CPU 暫存器功能
    > ![image](https://hackmd.io/_uploads/HyWzgAJV6.png =300x)
---

# Verilog study
以下連結為 Verilog 學習筆記(之後更新...)
* https://hackmd.io/@Sheng08/H14FahROT

## 學習網站 (HDLBits)
- https://hdlbits.01xz.net/wiki/Main_Page

## Logic Gate Function
* Video ref: https://www.youtube.com/watch?v=SiIH3PBk3Ak&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=3
> 組合邏輯（combinational logic）與 順序邏輯（sequential logic）

1. **LHS（Left Hand Side）的`reg`與`wire`的選用：**
   - 在 Procedure block內部，當需要實現組合邏輯時，LHS的變數應該使用`reg`，而不是`wire`
       - 因為在 Procedure block 內，`wire`類型的變數不能被賦值（即不能位於賦值的左邊）
   - ![示例圖片](https://hackmd.io/_uploads/S1jSJ9xN6.png =400x)
2. **組合邏輯在 Procedure block 中的使用：**
   - Verilog 最初是作為一種 simulation 語言開發，後來才支援 synthesize 所以可以將 combinational 放在 Procedure block 不用 assign 語句
   - 組合邏輯通常包括`if`和`case`語句。
   - **在組合邏輯中應使用阻塞賦值（blocking statement），而在順序邏輯中則應使用非阻塞賦值（nonblocking statement）**
        * ![截圖 2023-11-14 下午2.16.17](https://hackmd.io/_uploads/BJT3xqgEa.png =300x)
        
        * ![截圖 2023-11-14 下午2.19.05](https://hackmd.io/_uploads/BkDDZclNp.png =300x)
3. **Loop 和初始化在硬體合成中的限制：**
   - `while`循環一般不能用於硬體合成，但`for` loop 可以
   - `for` loop 也有其限制。例如: 不能依賴於動態資料或資料依賴性高的狀況
   - 在邏輯設計中，不建議使用`initial` block，因為不適合硬體合成

## Blocking/NonBblack

1. **阻塞賦值（Blocking Assignments）：**
   - ==blocking = Asynchronous = Combinational==
   - **使用情境：** Blocking 主要用於**組合邏輯（Combinational Logic）**
   - **特點：** 組合邏輯的輸出僅依賴於當前的輸入值，而不依賴於之前的狀態或時間序列
   - **即時反應：** 使用`= `符號的 Blocking Assignments，可以確保輸入一旦變化，輸出立即更新，這符合組合邏輯的即時反應特性
   - **順序執行：** 在`always`塊中使用阻塞賦值，將按照程式碼中的順序執行賦值操作，有利於根據邏輯需求順序安排程式碼
2. **非阻塞賦值（Non-Blocking Assignments）：**
   - ==non-blocking = Synchronous = Sequential==
   - **使用情境：** Non-Blocking 主要用於**順序邏輯（Sequential Logic）**，尤其是涉及 register 操作的狀況
   - **特點：** 順序邏輯通常涉及 clock-driven 的行為，如: Flip-flop(觸發器)的操作
   - **同時更新：** 使用`<=`符號的 Non-Blocking Assignments 確保所有相關狀態在每個 clock 周期的 edge（如上沿或下沿）同時更新
   - **避免競態條件(race condition)：** 在複雜的順序電路中，非阻塞賦值通過允許所有變化在 clock 周期結束時同時發生，有助於避免因程式碼順序執行導致的race condition
   - **時序準確性：** 非阻塞賦值有助於更準確地模擬硬體中的時 clock-driven 行為，提高設計的可靠性和準確性

---

# Labs
以下連結為本次課程所有 Lab 整理包含筆記與報告。
- Lab 1
    - [Github](https://github.com/Sheng08/SoC-Lab-lab1)
    - [Note](https://hackmd.io/@Sheng08/H1hkiwMl6)
- Lab 2
    - [Github](https://github.com/Sheng08/SoC-Lab-lab2)
    - [Note](https://hackmd.io/@Sheng08/Hy8gkU2ep)
- Lab 3
    - [Github](https://github.com/Sheng08/SoC-Lab-FIR)
    - [Report](https://hackmd.io/@Sheng08/BkA-NLfzT)
- Lab 4
    - [Github](https://github.com/Sheng08/SoC-Lab-FIR_Lab4)
    - [Lab4-1 Report](https://hackmd.io/@Sheng08/rJCgSEmET)
    - [Lab4-2 Report](https://hackmd.io/@Sheng08/ByxwnUm4T)
- Lab 5
    - [Github](https://github.com/Sheng08/SoC-Lab-lab5)
    - [Report](https://hackmd.io/Ae-A2Z_hTxirA8ZjlSL8mQ)
- Lab 6
    - [Github](https://github.com/Sheng08/SoC-Lab-lab6)
    - [Report](https://hackmd.io/UXvy0bm5Qp2mG7kHX_wzlQ)
- Lab D (Extra lab)
    - [Github](https://github.com/Sheng08/SoC-LabD)
    - [Report](https://hackmd.io/8bcLtNcRQomzpaY_YCkX8g)
- Final-project
    - [Github](https://github.com/Sheng08/SoC-Lab-Final)
    - [Report](https://hackmd.io/@Sheng08/rypJ-_a_p)

# Evidence of soft skill activities

- [Problem #200](https://github.com/bol-edu/HLS-SOC-Discussions/discussions/200)
    > https://github.com/bol-edu/HLS-SOC-Discussions/discussions/200
    > ![image](https://hackmd.io/_uploads/H1E8yY0_a.png)
- 回覆 Problem #195
    > 分享想法
    > https://github.com/bol-edu/HLS-SOC-Discussions/discussions/195#discussioncomment-8079168
    > ![image](https://hackmd.io/_uploads/Sy6ikFRdT.png)

