1个不稳定版本

0.1.0 2024年7月5日

#34 in 模拟器

Download history 99/week @ 2024-07-01 589/week @ 2024-07-08 568/week @ 2024-07-15 722/week @ 2024-07-22 1339/week @ 2024-07-29 2595/week @ 2024-08-05 2174/week @ 2024-08-12

6,837 每月下载量
用于 11 个包(通过 sp1-core

Apache-2.0

100KB
2.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());
}

依赖项

~1.5MB
~36K SLoC