iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Software Development

從零開始的RISC-V ISA Simulator (Another Little RISC-V ISA Simulator)系列 第 28

Day 28 - 真正執行risc-v test、跑過第一支elf、及regression環境

  • 分享至 

  • xImage
  •  

今天的任務就是要把RISC-V Test跑起來,然後看有哪些錯誤。

RISC-V TEST Pass/Fail判斷

首先我們觀察RISC-V Test發現他最後會走到fail或pass,兩個function的最後一道指令都是ecall。

https://ithelp.ithome.com.tw/upload/images/20231013/20162436hJlHd1lIm8.png

並且在ecall前,a7會被放93,而如果是success a0會填0,如果是failed a0會被放gp,而gp對應的是執行到幾個測試。

首先這邊93的意思是用來跟system溝通,在有OS的環境a7內的值不同代表想要執行的ecall不一樣,而93參考這裡,代表的是EXIT。
https://ithelp.ithome.com.tw/upload/images/20231013/20162436GkbVXVPkpu.png
因此我們可以這麼做,當ecall發生且a7是93時結束模擬,並回傳a0內的值。

https://ithelp.ithome.com.tw/upload/images/20231013/20162436HTg1f3iEz2.png

要注意的是這是在baremetal下才要這樣做,如果是在有OS的環境OS會自己幫你把application關掉,不要多此一舉。

1'st Run, linker script issue

第一支程式我們選擇rv64ui-p-add,執行下去發現還在Load code的時候就segFault了Q Q。

確認後發現,RISC-V Test的code都放在0x80000000開始的位置,為了方便我們修改為0x00000000開始。

  • env/pt/link.ld
    https://ithelp.ithome.com.tw/upload/images/20231013/20162436U3xpYX0Nm4.png

2'nd run, ZERO reg issue
重新執行,發現會hang住,而為了方便debug我們設計一個簡易的log系統,其中底下印的insnType及倒的reg都是針對這次的debug去改,實際上只要先印出PC和insn本身即可。

https://ithelp.ithome.com.tw/upload/images/20231013/20162436elUDNLgE75.png

追查後發現我們的reg[0]被改過之後導致bnez指令錯誤,但reg[0]在RISC-V spec內無論怎麼讀都應該是0,因此我們修改在每一次的step前把reg[0]設回0。

3'rd run, pass...?

https://ithelp.ithome.com.tw/upload/images/20231013/20162436FDMoBYJ61m.png

執行到Ecall,simulator結束,並且觀察到輸出結果是0,為了保險起見同時檢查objdump。

https://ithelp.ithome.com.tw/upload/images/20231013/20162436XyYeWrgEy8.png

6a0是pass段的ecall,看起來是順利完成,比我想像中的還順利。

Regression環境
測試完ADD之後我們可以來建立環境大量進行測試,否則一支一支這樣測試會有點慢,我們這邊簡單寫一個python script去幫助我們。

import os
import sys

def run_aliss(folder_name, pattern_list_file):
    with open(pattern_list_file, 'r') as file:
        patterns = [line.strip() for line in file.readlines()]

    if not os.path.exists(folder_name):
        print("No file" + folder_name + "found")
        return

    for pattern in patterns:
        aliss_command = f"./ALISS -e {folder_name}/{pattern}"
        os.system(aliss_command)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("python3 run_aliss.py folder_name pattern_list")
        sys.exit(1)

    folder_name = sys.argv[1]
    pattern_list_file = sys.argv[2]

    run_aliss(folder_name, pattern_list_file)

這個script會根據pattern_list裡面的值,到folder裡面去依序執行,同時在ecall exit時把a0的值印出來,這樣就可以一次判斷跑的結果。

執行結果如下,

rv64i/rv64ui-p-add
return value = 0
rv64i/rv64ui-p-addi
return value = 0
rv64i/rv64ui-p-addiw
return value = 0
rv64i/rv64ui-p-addw
return value = 0
rv64i/rv64ui-p-and
return value = 0
rv64i/rv64ui-p-andi
return value = 0
rv64i/rv64ui-p-auipc
return value = 0
rv64i/rv64ui-p-beq
return value = 0
rv64i/rv64ui-p-bge
return value = 0
rv64i/rv64ui-p-bgeu
return value = 13
rv64i/rv64ui-p-blt
return value = 0
rv64i/rv64ui-p-bltu
return value = 7
rv64i/rv64ui-p-bne
return value = 0
rv64i/rv64ui-p-fence_i
return value = 0
rv64i/rv64ui-p-jal
return value = 0
rv64i/rv64ui-p-jalr
return value = 7
rv64i/rv64ui-p-lb
return value = 0
rv64i/rv64ui-p-lbu
return value = 0
rv64i/rv64ui-p-ld
return value = 0
rv64i/rv64ui-p-lh
return value = 0
rv64i/rv64ui-p-lhu
return value = 0
rv64i/rv64ui-p-lui
return value = 0
rv64i/rv64ui-p-lw
return value = 0
rv64i/rv64ui-p-lwu
return value = 0
rv64i/rv64ui-p-ma_data
return value = 93
rv64i/rv64ui-p-or
return value = 0
rv64i/rv64ui-p-ori
return value = 0
rv64i/rv64ui-p-sb
return value = 0
rv64i/rv64ui-p-sd
return value = 0
rv64i/rv64ui-p-sh
return value = 0
rv64i/rv64ui-p-simple
return value = 0
rv64i/rv64ui-p-sll
return value = 43
rv64i/rv64ui-p-slli
return value = 101
rv64i/rv64ui-p-slliw
return value = 0
rv64i/rv64ui-p-sllw
return value = 35
rv64i/rv64ui-p-slt
return value = 0
rv64i/rv64ui-p-slti
return value = 0
rv64i/rv64ui-p-sltiu
return value = 17
rv64i/rv64ui-p-sltu
return value = 29
rv64i/rv64ui-p-sra
return value = 0
rv64i/rv64ui-p-srai
return value = 0
rv64i/rv64ui-p-sraiw
return value = 91
rv64i/rv64ui-p-sraw
return value = 35
rv64i/rv64ui-p-srl
return value = 7
rv64i/rv64ui-p-srli
return value = 7
rv64i/rv64ui-p-srliw
return value = 7
rv64i/rv64ui-p-srlw
return value = 7
rv64i/rv64ui-p-sub
return value = 0
rv64i/rv64ui-p-subw
return value = 0
rv64i/rv64ui-p-sw
return value = 0
rv64i/rv64ui-p-xor
return value = 0
rv64i/rv64ui-p-xori
return value = 0

其中0的代表pass,而有值的代表錯在哪一次測試,可以看到有些指令還是有一些問題,我會趁明天假日修一點,並蒐集比較常見的錯誤分享給大家,而今天主要是完成該環境,透過以上環境我們可以大量跑riscv-test並找到錯誤的位置,待全部修好之後就可以跑Linux啦。


碎碎念 : 終於執行完一支elf啦,雖然後面看到還有許多錯誤,但至少我們踏出成功的第一步了...


上一篇
Day 27 - RISC-V M Extension , 簡單來說...就是乘除
下一篇
Day 29 - Debug, RV64I Test Pass
系列文
從零開始的RISC-V ISA Simulator (Another Little RISC-V ISA Simulator)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言