1 个不稳定版本

0.1.0 2021 年 8 月 9 日

#95模拟器

Download history 1993/week @ 2024-03-14 2085/week @ 2024-03-21 2251/week @ 2024-03-28 1730/week @ 2024-04-04 2110/week @ 2024-04-11 2522/week @ 2024-04-18 3145/week @ 2024-04-25 2666/week @ 2024-05-02 2940/week @ 2024-05-09 3528/week @ 2024-05-16 2349/week @ 2024-05-23 2758/week @ 2024-05-30 2917/week @ 2024-06-06 2735/week @ 2024-06-13 3456/week @ 2024-06-20 2516/week @ 2024-06-27

12,208 每月下载量
12 个软件包中(通过 risc0-zkvm)使用

Apache-2.0

74KB
1.5K SLoC

Rust RISC-V 模拟器库 (rrs-lib)

此软件包包含实现 RISC-V 指令集模拟器的组件。它设计为模块化,因此对于任何需要解码或以其他方式处理 RISC-V 指令的应用程序都应非常有用。

rrs-lib 支持 RV32IM,没有特权支持、CSR 指令或异常/中断(尽管这些是计划中的功能)。

用法

[dependencies]
rrs-lib = "0.1"

rrs-lib 的一个关键特性是 InstructionProcessor 特性。它包含每个 RISC-V 指令的一个函数。process_instruction 函数解码指令并调用 InstructionProcessor 中适当的函数。InstructionProcessor 可以执行指令、反汇编指令或执行其他操作(例如,计算执行指令的统计信息)。rrs-lib 提供了执行 RISC-V 代码并在字符串中生成指令反汇编的 InstructionProcessor 实现。此示例演示了这两种用法

use rrs_lib::{HartState, MemAccessSize, Memory};
use rrs_lib::memories::VecMemory;
use rrs_lib::instruction_executor::{InstructionExecutor, InstructionException};
use rrs_lib::instruction_string_outputter::InstructionStringOutputter;

fn simulate_riscv() {
  let mut hart = HartState::new();
  // Memory contains these instructions:
  // lui x2, 0x1234b
  // lui x3, 0xf387e
  // add x1, x2, x3
  let mut mem = VecMemory::new(vec![0x1234b137, 0xf387e1b7, 0x003100b3]);

  hart.pc = 0;

  // InstructionExecutor implements IntructionProcessor. The step function calls
  // process_instruction internally and handles things like updating the PC.
  let mut executor = InstructionExecutor {
      hart_state: &mut hart,
      mem: &mut mem,
  };

  // Execute first instruction
  output_disass(&mut executor);
  assert_eq!(executor.step(), Ok(()));
  assert_eq!(executor.hart_state.registers[2], 0x1234b000);

  // Execute second instruction
  output_disass(&mut executor);
  assert_eq!(executor.step(), Ok(()));
  assert_eq!(executor.hart_state.registers[3], 0xf387e000);

  // Execute third instruction
  output_disass(&mut executor);
  assert_eq!(executor.step(), Ok(()));
  assert_eq!(executor.hart_state.registers[1], 0x05bc9000);

  // Memory only contains three instructions so next step will produce a fetch error
  assert_eq!(executor.step(), Err(InstructionException::FetchError(0xc)));
}

fn output_disass<M: Memory>(executor: &mut InstructionExecutor<M>) {
  let mut outputter = InstructionStringOutputter { insn_pc: executor.hart_state.pc };
  let insn_bits = executor.mem.read_mem(executor.hart_state.pc, MemAccessSize::Word).unwrap();
  println!("{}", rrs_lib::process_instruction(&mut outputter, insn_bits).unwrap());
}

依赖关系

~37KB