使用Python實現RISCV模擬器(一)
不用花幾百塊錢買開發板,也不需要折騰複雜的官方模擬器,只需要有Python就可以進行RISCV的開發了
=====================================================================================================================================================================
1. 簡介
pyriscv 是筆者開發的一套RISCV資料精確的模擬器。由於Python對運算子過載、函式指標等高階程式設計方法有非常方便的支援,因此程式碼量非常的小,也便於閱讀和理解。
目前pyriscv還在持續開發中。當前github上的版本只支援RV32I這個指令集,且沒有實現Load/Store、MEMORY、SYSTEM和CSR。因此目前只能夠做簡單的暫存器級運算和控制。
目前的程式碼量近300行,核心部分僅僅60多行。在開發過程中沒有用到任何第三方庫,僅僅使用Python自帶的功能。
2. 快速執行
github地址: ofollow,noindex"> https:// github.com/jerry-jho/py riscv
clone下來之後,src/pyriscv.py即為模擬器入口。交叉編譯器產生elf後,需要使用交叉編譯器提供的objcopy工具將elf轉換為verilog memory格式,便於模擬器讀取。模擬器的命令列引數即為
python3 pyriscv.py <mem convert from elf>
在程式碼庫裡提供了一個示例app.S和連結指令碼link.ld,沒有安裝riscv編譯器的同學可以從這裡下載到預先編譯好的編譯器。注意不要把這個編譯器安裝到帶空格的目錄裡,在安裝過程中要仔細觀看它的預設安裝路徑
https:// github.com/gnu-mcu-ecli pse/riscv-none-gcc/releases gnu-mcu-eclipse/riscv-none-gcc gnu-mcu-eclipse/riscv-none-gcc全套命令為:
cd app $riscv-gcc -g -march=rv32i -mabi=ilp32app.S -nostdlib -Tlink.ld -o app.elf $riscv-objdump -S -d app.elf > app.lst $riscv-objcopy -F verilog app.elf app.mem python3 ../src/pyriscv.py app.mem
3. 平臺約定
- 復位向量位於0x00000000,如果需要修改它,需要在link.ld中指定或者在程式碼裡分配,同時,在例化PyRiscv時指定reset_vec這個引數。
- 任何對x0的寫入均會列印到控制檯上。因此,如果想使用printf,只需要在putc裡將傳入的字元扔給x0就可以了。當然,這樣的設計不太理想,因為很多命令都會寫入x0(例如跳轉)
- 執行slt x0,x0,x0這條指令會退出模擬器
接下來的幾個章節會對這個模擬器的設計進行分析,也歡迎大家評論、fork、star,我會盡可能在接下來的講述中優先考慮回答讀者的問題。