4个版本
使用旧的Rust 2015
0.2.2 | 2021年3月21日 |
---|---|
0.2.1 | 2018年11月14日 |
0.2.0 | 2018年11月11日 |
0.1.0 | 2018年3月18日 |
#101 in 仿真器
305KB
5K SLoC
rvsim
一个使用Rust编写的实现RV32G[C]的RISC-V仿真器。
请参阅文档了解用法。
当前限制
- 仅支持小端主机。
- Windows支持需要工作。
功能
serialize
启用序列化支持rv32c
启用RV32C压缩指令集支持rv32fd
启用RV32F(单精度浮点)和RV32F(双精度浮点)指令集支持(默认值)
许可证
Rvsim使用MIT许可证,但包括Berkely SoftFloat的部分,当启用'rv32fd'功能时使用(默认)。Berkely SoftFloat使用BSD 3-clause许可证。有关详细信息,请参阅COPYING.md文件。
lib.rs
:
A RISC-V simulator implementing RV32G[C].
用法
此crate中的主要工作马是Interp
。它接受一个CpuState
、Memory
和Clock
,然后使用这些资源模拟一个虚拟CPU。 CpuState
是一个结构体,而Memory
和Clock
是特质,允许完全控制虚拟机的其余结构。
当使用crate功能serialize
时,可以将CpuState
序列化(和反序列化),以便将虚拟机挂起到持久存储。
在elf
模块中也提供了一个非常基本的ELF解析器。Rvsim本身使用此解析器运行官方的RISC-V测试套件。
示例
extern crate rvsim;
use std::io::Write;
/// A simple `Memory` implementation, that creates an address space with just some DRAM.
struct SimpleMemory {
dram: Vec<u8>,
}
impl SimpleMemory {
const DRAM_BASE: u32 = 0x1000_0000;
const DRAM_SIZE: usize = 0x10_0000;
fn new() -> Self {
Self { dram: vec![0; Self::DRAM_SIZE] }
}
}
/// Our implementation of `Memory` builds a simple memory map.
///
/// The `Memory` trait is also implemented for `[u8]`, so we can simply delegate to it, after
/// translating the address.
///
/// The condition here only checks the start address of DRAM, because the upper bound is
/// already checked by the `[u8]` implementation. This type of memory map can be easily
/// extended by adding more `else if` clauses, working through blocks of memory from highest
/// base address to lowest.
impl rvsim::Memory for SimpleMemory {
fn access<T: Copy>(&mut self, addr: u32, access: rvsim::MemoryAccess<T>) -> bool {
if addr >= Self::DRAM_BASE {
rvsim::Memory::access(&mut self.dram[..], addr - Self::DRAM_BASE, access)
} else {
false
}
}
}
fn main() {
// Create the `SimpleMemory` and load some code into it.
// Writing to the start of DRAM will put the code at `DRAM_BASE` in the address space.
let mut mem = SimpleMemory::new();
(&mut mem.dram[..]).write_all(&[
0x73, 0x00, 0x10, 0x00 // `EBREAK`
]).unwrap();
// We can use the very basic `Clock` implementation that is provided.
let mut clock = rvsim::SimpleClock::new();
// Create the virtual CPU state, setting the PC to the start of our program.
let mut state = rvsim::CpuState::new(SimpleMemory::DRAM_BASE);
// Run until the program stops.
let mut interp = rvsim::Interp::new(&mut state, &mut mem, &mut clock);
let (err, op) = interp.run();
// The program should've stopped at the `EBREAK` instruction.
assert_eq!(err, rvsim::CpuError::Ebreak);
assert_eq!(op, Some(rvsim::Op::Ebreak));
}
当前限制
- 仅支持小端主机。
- Windows支持需要工作。
许可证
Rvsim使用MIT许可证,但包含Berkely SoftFloat的部分,它使用BSD 3-clause许可证。有关详细信息,请参阅COPYING.md文件。
依赖关系
~0–660KB
~13K SLoC