#include #include #include "Vtop.h" double sc_time_stamp() { return 0; } int main(int argc, char** argv, char** env) { // Prevent unused variable warnings if (false && argc && argv && env) { } // Create logs/ directory in case we have traces to put under it Verilated::mkdir("logs"); // Construct a VerilatedContext to hold simulation time, etc. // Multiple modules (made later below with Vtop) may share the same // context to share time, or modules may have different contexts if // they should be independent from each other. // Using unique_ptr is similar to // "VerilatedContext* contextp = new VerilatedContext" then deleting at end. const std::unique_ptr contextp{new VerilatedContext}; // Set debug level, 0 is off, 9 is highest presently used // May be overridden by commandArgs argument parsing contextp->debug(0); // Randomization reset policy // May be overridden by commandArgs argument parsing contextp->randReset(2); // Verilator must compute traced signals contextp->traceEverOn(true); // Pass arguments so Verilated code can see them, e.g. $value$plusargs // This needs to be called before you create any model contextp->commandArgs(argc, argv); // Construct the Verilated model, from Vtop.h generated from Verilating // "top.v". Using unique_ptr is similar to "Vtop* top = new Vtop" then // deleting at end. "TOP" will be the hierarchical name of the module. const std::unique_ptr top{new Vtop{contextp.get(), "TOP"}}; // Set Vtop's input signals top->reset_l = !0; top->clk = 0; top->in_small = 1; top->in_quad = 0x1234; top->in_wide[0] = 0x11111111; top->in_wide[1] = 0x22222222; top->in_wide[2] = 0x3; uint64_t steps = 1000; // Simulate until $finish while (!contextp->gotFinish() && steps) { // Historical note, before Verilator 4.200 Verilated::gotFinish() // was used above in place of contextp->gotFinish(). // Most of the contextp-> calls can use Verilated:: calls instead; // the Verilated:: versions simply assume there's a single context // being used (per thread). It's faster and clearer to use the // newer contextp-> versions. contextp->timeInc(1); // 1 timeprecision period passes... // Historical note, before Verilator 4.200 a sc_time_stamp() // function was required instead of using timeInc. Once timeInc() // is called (with non-zero), the Verilated libraries assume the // new API, and sc_time_stamp() will no longer work. // Toggle a fast (time/2 period) clock top->clk = !top->clk; // Toggle control signals on an edge that doesn't correspond // to where the controls are sampled; in this example we do // this only on a negedge of clk, because we know // reset is not sampled there. if (!top->clk) { if (contextp->time() > 1 && contextp->time() < 10) { top->reset_l = !1; // Assert reset } else { top->reset_l = !0; // Deassert reset } // Assign some other inputs top->in_quad += 0x12; } // Evaluate model // (If you have multiple models being simulated in the same // timestep then instead of eval(), call eval_step() on each, then // eval_end_step() on each. See the manual.) top->eval(); // Read outputs // VL_PRINTF("[%" PRId64 "] clk=%x rstl=%x iquad=%" PRIx64 " -> oquad=%" PRIx64 // " owide=%x_%08x_%08x\n", // contextp->time(), top->clk, top->reset_l, top->in_quad, // top->out_quad, top->out_wide[2], top->out_wide[1], // top->out_wide[0]); steps--; } // Final model cleanup top->final(); // Coverage analysis (calling write only after the test is known to pass) #if VM_COVERAGE Verilated::mkdir("logs"); contextp->coveragep()->write("logs/coverage.dat"); #endif return 0; }