rtl
和模拟框架之间的dpi
接口不易维护spike
的C++
代码不易维护和扩展online difftest
不是必要的offline diffetst
的验证框架可以带来很多其它的好处online difftest
相比更加灵活spike
的C API
C
通过C API
与spike
交互的example
Rust
通过FFI
绑定到spike
的C API
上的example
Rust
的FFI
支持很好Rust
的代码更易于维护和扩展t1
提交了我在Github
上的第一个PR
t1
的README.md
中nix
的build
问题t1
基于nix
的项目管理Rust
的FFI
接口unsafe
.
├── examples
│ ├── elfloader // C API example
│ └── rs_elfloader // Rust FFI example
├── nix // nix build scripts
│ ├── examples
│ └── pkgs
├── resources // resources
└── src // spike C API implementation
├── CMakeLists.txt
├── spike_interfaces.cc
├── spike_interfaces.h
└── spike_interfaces_c.h
C-API
void spike_register_callback(ffi_callback callback);
spike_t* spike_new(const char* arch, const char* set, const char* lvl);
spike_processor_t* spike_get_proc(spike_t* spike);
void spike_destruct(spike_t* spike);
// ...
rust:
#[link(name = "spike_interfaces")]
extern "C" {
pub fn spike_register_callback(callback: FfiCallback);
fn spike_new(arch: *const c_char, set: *const c_char, lvl: *const c_char) -> *mut ();
fn spike_get_proc(spike: *mut ()) -> *mut ();
fn spike_destruct(spike: *mut ());
// ...
}
pub struct Spike {
spike: *mut (),
}
impl Spike {
pub fn new(arch: &str, set: &str, lvl: &str) -> Self {
let arch = CString::new(arch).unwrap();
let set = CString::new(set).unwrap();
let lvl = CString::new(lvl).unwrap();
let spike = unsafe { spike_new(arch.as_ptr(), set.as_ptr(), lvl.as_ptr()) };
Spike { spike }
}
pub fn get_proc(&self) -> Processor {
let processor = unsafe { spike_get_proc(self.spike as *mut ()) };
Processor { processor }
}
}
spike
的C API
并且贡献上游UB
检测Rust
的FFI
接口以及对应的example
offline difftest
的验证框架spike C-API
的更多使用场景RISC-V
的总线行为模型trace
的性能分析模型