#include "VFlow___024root.h" #include "tracer.h" #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_SIM_TIME 100 #define VERILATOR_TRACE std::vector regsHandle; int regs[32]; template class Tracer { #ifdef VERILATOR_TRACE std::shared_ptr top; std::unique_ptr m_trace; uint64_t time = 0; #endif public: Tracer(std::shared_ptr top, std::filesystem::path wavefile) { #ifdef VERILATOR_TRACE top = top; Verilated::traceEverOn(true); m_trace = std::make_unique(); top->trace(m_trace.get(), 5); m_trace->open(wavefile.c_str()); #endif } ~Tracer() { #ifdef VERILATOR_TRACE m_trace->close(); #endif } /** * Dump signals to waveform file. Must be called once after every top->eval() call. */ void update() { #ifdef VERILATOR_TRACE m_trace->dump(time++); #endif } }; template class _RegistersBase { std::array regs; virtual T fetch_reg(size_t id); public: void update() { for(int i = 0; i < regs.size(); i++) { regs[i] = fetch_reg(i); } } void print_regs() { for(int i = 0; i < regs.size(); i++) { printf("%d: %d\t", i, regs[i]); if(i % 8 == 7) putchar('\n'); } putchar('\n'); } }; template class _RegistersVPI : public _RegistersBase { std::array reg_handles; T fetch_reg(size_t id) { s_vpi_value v; v.format = vpiIntVal; vpi_get_value(reg_handles[id], &v); return v.value.integer; } public: _RegistersVPI(const std::string regs_prefix) { for(int i = 0; i < nr; i++) { std::string regname = regs_prefix + std::to_string(i); vpiHandle vh = vpi_handle_by_name((PLI_BYTE8 *)regname.c_str(), NULL); reg_handles[i] = vh; } } }; template class Memory { std::array mem; size_t addr_to_index(size_t addr) { // Linear mapping return addr - 0x80000000; } public: const T& operator[](size_t addr) { return mem[addr_to_index(index)]; } }; typedef _RegistersVPI Registers; static int sim_time = 0; int main(int argc, char **argv, char **env) { int sim_time = 0; int posedge_cnt = 0; Verilated::commandArgs(argc, argv); auto top = std::make_shared(); auto top_tracer = std::make_unique>(top, "waveform.vcd"); Registers regs("TOP.Flow.reg_0.regFile_"); top->reset = 0; top->eval(); for (sim_time = 10; sim_time < MAX_SIM_TIME; sim_time++) { top->clock = !top->clock; if(top->clock == 1) { // Posedge ++posedge_cnt; regs.update(); regs.print_regs(); } top->eval(); } exit(EXIT_SUCCESS); }