这次要实作的是 RISC-V 的核心基本架构。RISC-V提供了32个integer register用作基本的算术逻辑运算,如下图:
以 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);
}
<<: RISC-V on Rust 从零开始(2) - 建立档案架构
>>: 资料结构与演算法[3] - List和SortedList与BinarySearch
教材网址 https://coding104.blogspot.com/2021/06/java-m...
【前言】 除了从 web3.js 来取得 ERC-721 的 Token's Ownership,...
grep 是查找档案中内容的指令,在一般的作业情境下, grep 的功能是十分足够了,但是在开发作业...
NSubstitute 基本语法前言-2 今天会是基本介绍 NSubstitute 的最後一个篇章 ...
-流行的 F/LOSS 许可证之间的兼容性关系(来源:Carlo Daffara) 在评估开源组件...