iT邦幫忙

1

RISC-V on Rust 從零開始(3) - RISC-V 核心基本資料結構

這次要實作的是 RISC-V 的核心基本架構。RISC-V提供了32個integer register用作基本的算術邏輯運算,如下圖:
https://ithelp.ithome.com.tw/upload/images/20210703/20122004bYQEIjHnrH.png

以 Rust 的struct實作如下,目前先支援32位元的架構:

#[derive(Default)]
struct RVCore {
    pc: u32,
    regs: [u32; 32],
}

與C++最大的不同在於陣列的宣告,regs: [u32; 32] 代表這邊宣告regs是一個長度為32的陣列,且每個元素為usigned 32-bit integer。繼承Default class目的是為了讓RVCore能夠自動初始化,往後使用RVCore就不用手動初始化每一個欄位。

光有data沒有太大用處,還必須有用來操作的method:

impl RVCore {
    fn step(&mut self, inst: u32) {
        println!("PC = {}, inst = {}", self.pc, inst);
        self.pc += 4;
    }
    
    fn run(&mut self, num_steps: i32) {
        let mut step_count = 0;
        while step_count < num_steps {
            self.step(0);
            step_count += 1;
        }
    }
}

Rust的語法相當有趣,data與method必須分成不同的block定義,好處是不會像C++那樣,data與method混在一起,提升了可讀性。這裡定義了step(),每次會傳入一條指令,執行並印出目前的PC,並且把PC加4。run() 則是可以指定要跑幾個step,目前每次都是傳0給step(),先看看能不能正常運作。

接下來在main裡面測試RVCore是否能正常運作:

fn main() {
    let mut core: RVCore = Default::default();
    core.run(5);
}

在命令列輸入cargo run可以看到以下輸出:

PC = 0, inst = 0
PC = 4, inst = 0
PC = 8, inst = 0
PC = 12, inst = 0
PC = 16, inst = 0

沒錯,這就是我們所預期的,可以想像這是一個最基本的RISC-V核心,可以讓他跑任意條指令,每條指令都只會把PC加4,這樣一個最基本的核心架構就完成了。完整的程式碼如下:

#[derive(Default)]
struct RVCore {
    pc: u32,
    regs: [u32; 32],
}

impl RVCore {
    fn step(&mut self, inst: u32) {
        println!("PC = {}, inst = {}", self.pc, inst);
        self.pc += 4;
    }
    
    fn run(&mut self, num_steps: i32) {
        let mut step_count = 0;
        while step_count < num_steps {
            self.step(0);
            step_count += 1;
        }
    }
}

fn main() {
    let mut core: RVCore = Default::default();
    core.run(5);
}

1 則留言

0
EN
iT邦研究生 3 級 ‧ 2021-07-08 12:17:34

要開發 RISC-V Emulator 嗎!!期待!/images/emoticon/emoticon37.gif

還在摸索Rust的語法QQ 且戰且走囉

我要留言

立即登入留言