From 82d199fcc77dc5c6a9f9477007c23b798d983857 Mon Sep 17 00:00:00 2001 From: Josse Van Delm Date: Thu, 28 Nov 2024 14:21:54 +0100 Subject: [PATCH] Add `--disable-tracing` and `--prefix-trace` options to HeMAiA (#90) * Switch to newer snitch version * Add --disable-tracing and --prefix-trace option * Fix issues * Fix HeMAiA styling * Copy verilator_lib.cc from snax_cluster * Add tb_bin from snax_cluster * Revert "Switch to newer snitch version" This reverts commit 72381a17eed43d89036ff187b3926dec057a241d. --------- Co-authored-by: Josse Van Delm --- target/rtl/test/tb_bin.cc | 59 +++++++++++- target/rtl/test/verilator_lib.cc | 26 +++++ target/sim_chip/testharness/testharness.cc | 106 ++++++++++++++++++--- 3 files changed, 176 insertions(+), 15 deletions(-) diff --git a/target/rtl/test/tb_bin.cc b/target/rtl/test/tb_bin.cc index bf895ac6c..38e2a722a 100644 --- a/target/rtl/test/tb_bin.cc +++ b/target/rtl/test/tb_bin.cc @@ -3,9 +3,26 @@ // SPDX-License-Identifier: SHL-0.51 #include +#include +#include +#include #include "sim.hh" +// Declare these as global variables +bool WRAPPER_disable_tracing = false; +char *WRAPPER_trace_prefix = nullptr; + +void print_usage(const char *prog_name) { + std::cout << "Usage: " << prog_name + << " [HeMAiA WRAPPER Options] [HTIF Options]\n" + << " Wrap Rocket Chip Emulator in HeMAiA RTL Simulator\n\n" + << "HeMAiA WRAPPER Options:\n" + << " --disable-tracing Disable Snitch tracing\n" + << " --prefix-trace Set trace prefix (cannot be used " + "with --disable-tracing)\n\n"; +} + int main(int argc, char **argv, char **env) { // Write binary path to logs/binary for the `make annotate` target FILE *fd; @@ -17,7 +34,47 @@ int main(int argc, char **argv, char **env) { fprintf(stderr, "Warning: Failed to write binary name to logs/.rtlbinary\n"); } + // Parse custom wrapper arguments + for (int i = 1; i < argc; ++i) { + if (strcmp(argv[i], "--disable-tracing") == 0) { + WRAPPER_disable_tracing = true; + } else if (strncmp(argv[i], "--prefix-trace ", 15) == 0) { + WRAPPER_trace_prefix = + argv[i] + 15; // Extract the value after `--prefix-trace=` + } else if (strcmp(argv[i], "-h") == 0 || + strcmp(argv[i], "--help") == 0) { + print_usage(argv[0]); + // Also show help from underlying fesvr function + // Note: + // If a binary is supplied, it will show both the snax wrapper help, + // AND continue with the execution of the program... + auto sim = std::make_unique(argc, argv); + return sim->run(); + return -1; + } + } + // Validate conflicting options + if (WRAPPER_disable_tracing && WRAPPER_trace_prefix != nullptr) { + std::cerr << "Error: --disable-tracing and --prefix-trace cannot be " + "used together.\n"; + return 1; + } + // Prepare filtered arguments + std::vector filtered_argv; + for (int i = 0; i < argc; ++i) { + // Skip custom options + if (strcmp(argv[i], "--disable-tracing") == 0 || + strncmp(argv[i], "--prefix-trace ", 15) == 0) { + continue; + } + filtered_argv.push_back(argv[i]); + } + filtered_argv.push_back(nullptr); // Null-terminate for compatibility - auto sim = std::make_unique(argc, argv); + // Pass the filtered arguments to fesvr argument handling + int filtered_argc = + static_cast(filtered_argv.size()) - 1; // Exclude null terminator + char **filtered_argv_ptr = filtered_argv.data(); + auto sim = std::make_unique(filtered_argc, filtered_argv_ptr); return sim->run(); } diff --git a/target/rtl/test/verilator_lib.cc b/target/rtl/test/verilator_lib.cc index 3e1ae89e1..88d99dc13 100644 --- a/target/rtl/test/verilator_lib.cc +++ b/target/rtl/test/verilator_lib.cc @@ -3,6 +3,8 @@ // SPDX-License-Identifier: SHL-0.51 #include +#include +#include #include "Vtestharness.h" #include "Vtestharness__Dpi.h" @@ -10,6 +12,11 @@ #include "tb_lib.hh" #include "verilated.h" #include "verilated_vcd_c.h" + +// Declare these as globally declared (and parsed) in tb_bin.cc +extern bool WRAPPER_disable_tracing; +extern char *WRAPPER_trace_prefix; + namespace sim { // Number of cycles between HTIF checks. @@ -106,6 +113,25 @@ void tb_memory_write(long long addr, int len, const svOpenArrayHandle data, (const uint8_t *)strb_ptr); } +svBit disable_tracing() { + // function to enable/disable tracers + return WRAPPER_disable_tracing; +} + +const char *get_trace_file_prefix() { + if (WRAPPER_trace_prefix == nullptr) { + // Use the standard prefix, and create a logs directory if necessary + std::string foldername = "logs/"; + std::filesystem::create_directories(foldername); + static std::string log_file_name = "logs/"; + return log_file_name.c_str(); + } + // Return the one parsed from the command line otherwise + else { + return WRAPPER_trace_prefix; + } +} + const long long clint_addr = sim::BOOTDATA.clint_base; const long num_cores = sim::BOOTDATA.core_count; diff --git a/target/sim_chip/testharness/testharness.cc b/target/sim_chip/testharness/testharness.cc index 3b12617d4..02e9bb360 100644 --- a/target/sim_chip/testharness/testharness.cc +++ b/target/sim_chip/testharness/testharness.cc @@ -1,35 +1,113 @@ -#include // For std::cout -#include "Vtestharness.h" // Verilated generated module +#include +#include +#include // For std::cout +#include "Vtestharness.h" // Verilated generated module +#include "Vtestharness__Dpi.h" #include "verilated.h" // Verilator library #include "verilated_vcd_c.h" // For VCD tracing (optional) -int main(int argc, char** argv, char** env) { +// Function to print help message +void print_help() { + std::cout + << "HeMAiA Verilator Simulation Driver\n" + << " -h :\t\t\t Show this help message\n" + << " --vcd :\t\t\t Enable VCD trace dumping\n" + << " --disable-tracing : \t Disable DASM tracing\n" + << " --prefix-trace : \t Prefix DASM files with prefix\n" + << " \t(cannot be used together with " + "--disable-tracing)\n"; +} + +// Global variables +bool WRAPPER_disable_tracing = false; +std::string WRAPPER_trace_prefix; + +// DPI calls +svBit disable_tracing() { + // function to enable/disable tracers + return WRAPPER_disable_tracing; +} + +const char* get_trace_file_prefix() { + if (WRAPPER_trace_prefix.empty()) { + // Use the standard prefix, and create a logs directory if necessary + std::string foldername = "logs/"; + std::filesystem::create_directories(foldername); + static std::string log_file_name = "logs/"; + return log_file_name.c_str(); + } + // Return the one parsed from the command line otherwise + else { + return WRAPPER_trace_prefix.c_str(); + } +} + +int main(int argc, char** argv) { Verilated::commandArgs(argc, argv); // Pass command-line arguments to Verilator Vtestharness* top = new Vtestharness; // Instantiate the top module - // Variables for tracing - VerilatedVcdC* tfp = nullptr; - bool enable_vcd = false; // Flag to enable VCD tracing + // Variables for options + bool enable_vcd = false; - // Check if the --vcd flag was passed - for (int i = 1; i < argc; i++) { - if (std::string(argv[i]) == "--vcd") { - enable_vcd = true; - break; + // Define the long options + static struct option long_options[] = { + {"vcd", no_argument, nullptr, 0}, + {"disable-tracing", no_argument, nullptr, 1}, + {"prefix-trace", required_argument, nullptr, 2}, + {"help", no_argument, nullptr, 'h'}, + {nullptr, 0, nullptr, 0} // Terminate the option array + }; + + // Parse the command-line arguments + int option_index = 0; + int c; + while ((c = getopt_long(argc, argv, "h", long_options, &option_index)) != + -1) { + switch (c) { + case 0: // --vcd + enable_vcd = true; + break; + case 1: // --disable-tracing + WRAPPER_disable_tracing = true; + break; + case 2: // --trace-prefix + WRAPPER_trace_prefix = optarg; + break; + case 'h': // -h or --help + print_help(); + return 0; + default: + std::cerr << "Unknown option. Use -h for help.\n"; + return 1; } } - // Enable tracing if --vcd was passed + // Validate conflicting options + if (WRAPPER_disable_tracing && !WRAPPER_trace_prefix.empty()) { + std::cerr << "Error: --trace-prefix cannot be used together with " + "--disable-tracing\n"; + return 1; + } + + // Handle VCD tracing + VerilatedVcdC* tfp = nullptr; if (enable_vcd) { Verilated::traceEverOn(true); // Enable trace logic tfp = new VerilatedVcdC; top->trace(tfp, 99); // Trace 99 levels of hierarchy tfp->open("sim.vcd"); // Open the VCD dump file - std::cout << "VCD trace enabled. Dumping to sim.vcd..." << std::endl; + std::cout << "VCD trace enabled. Dumping to sim.vcd...\n"; + } + + // Additional logging based on other options + if (WRAPPER_disable_tracing) { + std::cout << "DASM tracing is disabled.\n"; + } else if (!WRAPPER_trace_prefix.empty()) { + std::cout << "DASM tracing enabled with prefix: " + << WRAPPER_trace_prefix << "\n"; } - // unsigned long main_time = 0; // Current simulation time unsigned long main_time = 0; // Current simulation time // Simulation loop while (!Verilated::gotFinish()) {