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 仿真器

MIT license

305KB
5K SLoC

C 3K SLoC // 0.4% comments Rust 2K SLoC // 0.1% comments

rvsim

Docs Crate

一个使用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。它接受一个CpuStateMemoryClock,然后使用这些资源模拟一个虚拟CPU。 CpuState是一个结构体,而MemoryClock是特质,允许完全控制虚拟机的其余结构。

当使用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