From c4d5f56424d9cad167d6d0f3428c85d033648fc3 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Sun, 28 Jul 2024 23:22:29 +0800 Subject: [PATCH] [difftest] add rtl unexcepted quit check in difftest [difftest] refactor dpi_pre_link.cc to use std::shared_ptr for VerilatedContext and deal with chisel error [difftest] use return code instead of panic when exiting offline difftest [difftest] fix wrong unique ptr usage --- difftest/offline/src/difftest.rs | 2 +- difftest/offline/src/dut.rs | 2 +- difftest/online_drive/dpi_c/dpi_pre_link.cc | 18 +++++++++++------- difftest/online_drive/src/dpi.rs | 16 ++++++++++------ difftest/online_drive/src/main.rs | 2 +- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/difftest/offline/src/difftest.rs b/difftest/offline/src/difftest.rs index 66a0173d9..4bcefcd92 100644 --- a/difftest/offline/src/difftest.rs +++ b/difftest/offline/src/difftest.rs @@ -41,7 +41,7 @@ impl Difftest { JsonEvents::SimulationStop { reason, cycle } => { info!("simulation stopped at cycle {}, reason {}", cycle, reason); self.runner.cycle = *cycle; - Ok(()) + Err(anyhow::anyhow!("quit: no more events")) } JsonEvents::Issue { idx, cycle } => { self.runner.cycle = *cycle; diff --git a/difftest/offline/src/dut.rs b/difftest/offline/src/dut.rs index a4cc80821..273b06257 100644 --- a/difftest/offline/src/dut.rs +++ b/difftest/offline/src/dut.rs @@ -39,7 +39,7 @@ impl Dut { pub fn step(&mut self) -> anyhow::Result<&JsonEvents> { let event = match self.events.get(self.idx as usize) { Some(event) => event, - None => return Err(anyhow::anyhow!("no more events")), + None => return Err(anyhow::anyhow!("error: rtl quit unexpectedly")), }; self.idx += 1; diff --git a/difftest/online_drive/dpi_c/dpi_pre_link.cc b/difftest/online_drive/dpi_c/dpi_pre_link.cc index 914a70997..7ff07f97c 100644 --- a/difftest/online_drive/dpi_c/dpi_pre_link.cc +++ b/difftest/online_drive/dpi_c/dpi_pre_link.cc @@ -1,15 +1,16 @@ #include #include +#include class VTestBench; -static VerilatedContext *contextp; -static VTestBench *topp; +static std::unique_ptr contextp; +static std::unique_ptr topp; extern "C" int verilator_main_c(int argc, char **argv) { // Setup context, defaults, and parse command line Verilated::debug(0); - contextp = new VerilatedContext(); + contextp = std::make_unique(); contextp->fatalOnError(false); contextp->commandArgs(argc, argv); #ifdef VM_TRACE @@ -17,7 +18,7 @@ extern "C" int verilator_main_c(int argc, char **argv) { #endif // Construct the Verilated model, from Vtop.h generated from Verilating - topp = new VTestBench(contextp); + topp = std::make_unique(contextp.get()); // Simulate until $finish while (!contextp->gotFinish()) { @@ -31,14 +32,17 @@ extern "C" int verilator_main_c(int argc, char **argv) { if (!contextp->gotFinish()) { VL_DEBUG_IF(VL_PRINTF("+ Exiting without $finish; no events left\n");); + return 1; + } + + if (contextp->gotError()) { + VL_DEBUG_IF(VL_PRINTF("+ Exiting due to errors\n");); + return 1; } // Final model cleanup topp->final(); - delete topp; - delete contextp; - return 0; } diff --git a/difftest/online_drive/src/dpi.rs b/difftest/online_drive/src/dpi.rs index fb360386b..ff47779b5 100644 --- a/difftest/online_drive/src/dpi.rs +++ b/difftest/online_drive/src/dpi.rs @@ -5,7 +5,7 @@ use clap::Parser; use std::ffi::{c_char, c_int, c_longlong, CString}; use std::ptr; use std::sync::Mutex; -use tracing::debug; +use tracing::{debug, error}; use crate::drive::Driver; use crate::OfflineArgs; @@ -280,7 +280,7 @@ pub(crate) fn get_t() -> u64 { unsafe { get_t_c() / 20 } } -pub(crate) fn verilator_main() { +pub(crate) fn verilator_main() -> i32 { let c_args: Vec = std::env::args().map(|arg| CString::new(arg).unwrap()).collect(); let mut c_args_ptr: Vec<*const c_char> = c_args.iter().map(|arg| arg.as_ptr()).collect(); @@ -289,12 +289,16 @@ pub(crate) fn verilator_main() { let argc = c_args.len() as c_int; let argv = c_args_ptr.as_ptr() as *mut *mut c_char; - unsafe { - verilator_main_c(argc, argv); + let verilator_ret = unsafe { verilator_main_c(argc, argv) }; + + if verilator_ret == 0 { + std::fs::write("perf.txt", format!("total_cycles: {}", get_t())) + .expect("fail to write into perf.txt"); + } else { + error!("verilator_main_c return unexpectedly"); } - std::fs::write("perf.txt", format!("total_cycles: {}", get_t())) - .expect("fail to write into perf.txt"); + verilator_ret } #[cfg(feature = "trace")] diff --git a/difftest/online_drive/src/main.rs b/difftest/online_drive/src/main.rs index d13181a37..ff47c0bc6 100644 --- a/difftest/online_drive/src/main.rs +++ b/difftest/online_drive/src/main.rs @@ -23,5 +23,5 @@ pub(crate) struct OfflineArgs { } fn main() { - verilator_main(); + std::process::exit(verilator_main()); }