diff --git a/nemu/src/cpu/cpu-exec.c b/nemu/src/cpu/cpu-exec.c index 097c02f..d2b1f98 100644 --- a/nemu/src/cpu/cpu-exec.c +++ b/nemu/src/cpu/cpu-exec.c @@ -83,7 +83,7 @@ static void execute(uint64_t n) { g_nr_guest_inst ++; trace_and_difftest(&s, cpu.pc); if (wp_eval_all()) { - IFDEF(CONFIG_ITRACE, puts(logbuf[logbuf_rear])); + puts(logbuf[logbuf_rear]); break; } if (nemu_state.state != NEMU_RUNNING) break; @@ -132,7 +132,7 @@ void cpu_exec(uint64_t n) { ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))), nemu_state.halt_pc); if(nemu_state.halt_ret != 0) { - IFDEF(CONFIG_ITRACE, log_itrace_print()); + log_itrace_print(); } } // fall through case NEMU_QUIT: statistic(); diff --git a/npc/CMakeLists.txt b/npc/CMakeLists.txt index b40fa44..bd56708 100644 --- a/npc/CMakeLists.txt +++ b/npc/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.26) project(flow) -set (CMAKE_CXX_STANDARD 17) +set (CMAKE_CXX_STANDARD 14) cmake_policy(SET CMP0144 NEW) include(CMakeDependentOption) diff --git a/npc/csrc/Flow/main.cpp b/npc/csrc/Flow/main.cpp index 536716d..465e1f0 100644 --- a/npc/csrc/Flow/main.cpp +++ b/npc/csrc/Flow/main.cpp @@ -1,11 +1,7 @@ -#include -#include -#include -#include -#include #include #include #include +#include #include #include #include @@ -14,142 +10,77 @@ #define MAX_SIM_TIME 100 #define VERILATOR_TRACE -template -class Tracer { -#ifdef VERILATOR_TRACE - std::shared_ptr top; - std::unique_ptr m_trace; - uint64_t cycle = 0; -#endif - public: - Tracer(T *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(cycle++); -#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'); - } -}; +std::vector regsHandle; +int regs[32]; -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; +static void init_vpi_regs() { + std::string regfile = "TOP.Flow.reg_0.regFile_"; + for(int i = 0; i < 32; i++) { + std::string regname = regfile + std::to_string(i); + vpiHandle vh = vpi_handle_by_name((PLI_BYTE8 *)regname.c_str(), NULL); + regsHandle.push_back(vh); } - 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; - } - } -}; +} -typedef _RegistersVPI Registers; +static void init_vpi() { + init_vpi_regs(); +} -template -class Memory { - std::array mem; - size_t addr_to_index(size_t addr) { - // Linear mapping - return addr - 0x80000000; +static int vpi_get_int(vpiHandle vh) { + s_vpi_value v; + v.format = vpiIntVal; + vpi_get_value(vh, &v); + return v.value.integer; +} + +static void update_regs() { + for(int i = 0; i < 32; i++) { + regs[i] = vpi_get_int(regsHandle[i]); } - public: - const T& operator[](size_t addr) { - return mem[addr_to_index(index)]; - } -}; +} -template -class VlModuleInterfaceCommon : public T { - uint64_t sim_time = 0; - uint64_t posedge_cnt = 0; - std::unique_ptr> tracer; - public: - VlModuleInterfaceCommon(bool do_trace, std::filesystem::path wavefile = "waveform.vcd") { - if(do_trace) tracer = std::make_unique>(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; - } -}; +static void print_regs() { + for(int i = 0; i < 32; i++) { + printf("%d: %d\t", i, regs[i]); + if(i % 8 == 7) putchar('\n'); + } + putchar('\n'); +} -typedef VlModuleInterfaceCommon VlModule; +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(false, "waveform.vcd"); + std::unique_ptr top{new VFlow}; + Verilated::traceEverOn(true); + VerilatedVcdC *m_trace = new VerilatedVcdC; +#ifdef VERILATOR_TRACE + top->trace(m_trace, 5); + m_trace->open("waveform.vcd"); +#endif - Registers regs("TOP.Flow.reg_0.regFile_"); + init_vpi(); - top->reset_eval(10); - for (int i = 0; i < MAX_SIM_TIME; i++) { - if(top->is_posedge()) { - // Posedge - regs.update(); - regs.print_regs(); - } + top->reset = 0; + for (sim_time = 10; sim_time < MAX_SIM_TIME; sim_time++) { top->eval(); + top->clock = !top->clock; + if(top->clock == 1) { + // Posedge + ++posedge_cnt; + update_regs(); + print_regs(); + } + +#ifdef VERILATOR_TRACE + m_trace->dump(sim_time); +#endif } - return 0; +#ifdef VERILATOR_TRACE + m_trace->close(); +#endif + exit(EXIT_SUCCESS); }