2. 設計模擬器架構

1 運行 FreeRTOS 的最低硬件要求

一個 RISC-V core 加片上存儲器,以及片上外設 uart,已經具備了計算機的5大組成部分——運算器、控制器、存儲器、輸入設備、輸出設備,可以構成一個最簡單的單片機。

給上面這個單片機再添加片上 timer 就具備了運行 FreeRTOS 的最低硬件條件。也就是說,有了下面的硬件,就具備了運行 FreeRTOS 的硬件條件:

  1. RISC-V core (要能夠處理 timer 中斷)
  2. 存儲器
  3. uart
  4. timer

RISC-V core 至少要包含下面的模塊:

  1. 控制單元(Control Unit, CU)
  2. 算術邏輯單元(Arithmetic Logic Unit, ALU)
  3. 寄存器(Registers): pc, gpr, csr
  4. CLINT (Core-Local Interruptor): 參考 SiFive FE310-G002 芯片。
  5. 總線接口單元(Bus Interface Unit, BIU)

2 至少應該實現(xiàn)的 RISC-V 指令集

  • 要運行 FreeRTOS 至少要支持 RV32I 和 Zicsr 指令集
    • RV32I was designed to be sufficient to form a compiler target and to support modern operating system environments.
    • 中斷需要 CSR ,所以,需要支持 Zicsr 指令集

3 模擬器中的模塊

3.1 執(zhí)行一條指令的步驟

這里是開發(fā)功能精確 ISS,參照早期 ARM CPU 的三級流水——取指、譯碼、執(zhí)行,就夠用了。

RRV-ISS 中執(zhí)行一條指令,可以分為三步:取指、譯碼、執(zhí)行。

3.2 RRV-ISS 中大的功能模塊

  1. core
    1. 寄存器:pc,gpr,csr
    2. 取指:去 pc 指定的地址取指令,并把 pc 更新到下一條指令的起始地址
    3. 譯碼:解析指令,根據(jù)指令獲取操作數(shù)以及運算的函數(shù);執(zhí)行階段就是一行調用運算函數(shù)的代碼
  2. 外設
    1. 存儲器
    2. CLINT:其中包含了 timer
    3. uart
  3. bus:所有外設(片上外設、片外外設)都通過 bus 模塊的接口進行訪問
  4. loader:將程序加載到 memory

3.3 rust 工程的 crate & mod 結構

  1. 該工程使用 workspace 進行組織
  2. 將通過執(zhí)行一條 add 指令來打通各個 mod 之間的接口
  3. 隨著項目的深入,模塊/接口可能會變化
├── Cargo.toml
├── cpu_peripherals
│   ├── Cargo.toml
│   └── src
│       ├── clint.rs
│       ├── lib.rs
│       ├── mem.rs
│       └── uart.rs
├── iss   # 指令集模擬器的 binary crate
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── rv_core
│   ├── Cargo.toml
│   └── src
│       ├── core.rs
│       ├── csr.rs
│       ├── decoder.rs
│       ├── fetch.rs
│       └── lib.rs
├── sim_lib  # 模擬器的 mod 庫
│   ├── Cargo.toml
│   └── src
│       ├── bus.rs
│       ├── lib.rs
│       ├── loader.rs
│       └── simulator.rs
└── tests   # 整個工程的集成測試
    ├── Cargo.toml
    ├── src
    │   └── lib.rs
    └── tests
        └── exec_add_instr.rs # 執(zhí)行一條 add 指令

4 讓大模型生成工程的打樁代碼

4.1 生成打樁代碼提示詞

任務:請根據(jù)“cargo workspace 目錄結構”給工程打樁
角色:資深的指令集模擬器開發(fā)者,你同時具有豐富的軟件架構設計經驗、rust程序開發(fā)經驗以及RISC-V ISA設計經驗
背景:正在使用rust編寫RISC-V的ISS

要求
==============
1. 一步一步思考,給出完整代碼
2. 在 cpu_peripherals/src/lib.rs 中定義一個Device trait,Device提供按字節(jié)、半字、字、任意長度進行讀寫的接口,所有的讀寫都有可能失敗
3. 所有peripherals都需要實現(xiàn)Device trait
4. 在 cpu_peripherals/src/lib.rs 中定義Device type的enum,每個peripheral有對應的type,Device trait有獲取type的接口
5. bus 要管理各種實現(xiàn)了 Device 接口的設備,每個設備有對應的地址范圍,需要提供根據(jù)地址查找對應設備的接口,要盡可能提高查找設備的速度
6. 代碼中要有必要的錯誤處理
7. 添加單元測試
8. 添加集成測試,集成測試放在tests/tests/exec_add_instr.rs
9.  注釋使用英文
10. 實現(xiàn)所有的rs文件

cargo workspace 目錄結構:
    ```bash
    ├── Cargo.toml
    ├── cpu_peripherals
    │   ├── Cargo.toml
    │   └── src
    │       ├── clint.rs
    │       ├── lib.rs
    │       ├── mem.rs
    │       └── uart.rs
    ├── iss   # 指令集模擬器的 binary crate
    │   ├── Cargo.toml
    │   └── src
    │       └── main.rs # 作為入口文件,調用各個module的接口
    ├── rv_core
    │   ├── Cargo.toml
    │   └── src
    │       ├── core.rs # core 的主體
    │       ├── csr.rs # 模擬csr
    │       ├── decoder.rs
    │       ├── fetch.rs
    │       └── lib.rs
    ├── sim_lib  # 模擬器的 mod 庫
    │   ├── Cargo.toml
    │   └── src
    │       ├── bus.rs # 模擬總線,管理各種設備
    │       ├── lib.rs
    │       ├── loader.rs  # 加載 ELF 文件到模擬器內存
    │       └── simulator.rs # 模擬器的主體
    └── tests   # 整個工程的集成測試
        ├── Cargo.toml
        ├── src
        │   └── lib.rs
        └── tests
            └── exec_add_instr.rs # 執(zhí)行一條 add 指令的集成測試
    ```

4.2 調整生成的代碼

4.2.1 修改代碼,保證下面的命令結果都正常

cargo check
cargo test
cargo run

4.2.2 增加 log 機制

使用 tracing 庫,來做 ISS 的 log。
tracing 庫的介紹詳見:Rust 語言的全鏈路追蹤庫 tracing

4.2.3 統(tǒng)一的錯誤處理

4.3 解碼

4.4 測試

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容