From a91adb3a7dc636ee61a714aad97bdff424d94569 Mon Sep 17 00:00:00 2001 From: xinyangli <lixinyang411@gmail.com> Date: Tue, 2 Apr 2024 14:30:14 +0800 Subject: [PATCH] wrap verilated model --- npc/csrc/Flow/main.cpp | 69 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/npc/csrc/Flow/main.cpp b/npc/csrc/Flow/main.cpp index 3fd0129..536716d 100644 --- a/npc/csrc/Flow/main.cpp +++ b/npc/csrc/Flow/main.cpp @@ -1,12 +1,11 @@ -#include "VFlow___024root.h" -#include "tracer.h" #include <array> #include <cstddef> +#include <cstdint> #include <filesystem> +#include <sys/types.h> #include <vpi_user.h> #include <VFlow.h> #include <cstdlib> -#include <vector> #include <memory> #include <verilated.h> #include <verilated_vcd_c.h> @@ -15,18 +14,15 @@ #define MAX_SIM_TIME 100 #define VERILATOR_TRACE -std::vector<vpiHandle> regsHandle; -int regs[32]; - template <class T> class Tracer { #ifdef VERILATOR_TRACE std::shared_ptr<T> top; std::unique_ptr<VerilatedVcdC> m_trace; - uint64_t time = 0; + uint64_t cycle = 0; #endif public: - Tracer(std::shared_ptr<T> top, std::filesystem::path wavefile) { + Tracer(T *top, std::filesystem::path wavefile) { #ifdef VERILATOR_TRACE top = top; Verilated::traceEverOn(true); @@ -46,7 +42,7 @@ class Tracer { */ void update() { #ifdef VERILATOR_TRACE - m_trace->dump(time++); + m_trace->dump(cycle++); #endif } }; @@ -88,6 +84,8 @@ class _RegistersVPI : public _RegistersBase<T, nr> { } }; +typedef _RegistersVPI<uint32_t, 32> Registers; + template <typename T, std::size_t n> class Memory { std::array<T, n> mem; @@ -101,30 +99,57 @@ class Memory { } }; -typedef _RegistersVPI<uint32_t, 32> Registers; -static int sim_time = 0; +template <typename T> +class VlModuleInterfaceCommon : public T { + uint64_t sim_time = 0; + uint64_t posedge_cnt = 0; + std::unique_ptr<Tracer<T>> tracer; + public: + VlModuleInterfaceCommon<T>(bool do_trace, std::filesystem::path wavefile = "waveform.vcd") { + if(do_trace) tracer = std::make_unique<Tracer<T>>(this, wavefile); + } + void eval() { + if(this->is_posedge()) { + posedge_cnt++; + } + T::clock = !T::clock; + sim_time++; + T::eval(); + if(tracer) tracer->update(); + } + void eval(int n) { + for(int i = 0; i < n; i++) { + this->eval(); + } + } + void reset_eval(int n) { + this->reset = 1; + this->eval(n); + this->reset = 0; + } + bool is_posedge() { + // Will be posedge when eval is called + return T::clock == 0; + } +}; + +typedef VlModuleInterfaceCommon<VFlow> VlModule; 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<VFlow>(); - auto top_tracer = std::make_unique<Tracer<VFlow>>(top, "waveform.vcd"); + auto top = std::make_shared<VlModule>(false, "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) { + top->reset_eval(10); + for (int i = 0; i < MAX_SIM_TIME; i++) { + if(top->is_posedge()) { // Posedge - ++posedge_cnt; regs.update(); regs.print_regs(); } top->eval(); } - exit(EXIT_SUCCESS); + return 0; }