CIRCT  20.0.0git
driver.cpp
Go to the documentation of this file.
1 //===- driver.cpp - ESI Verilator software driver -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A fairly standard, boilerplate Verilator C++ simulation driver. Assumes the
10 // top level exposes just two signals: 'clk' and 'rst'.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef TOP_MODULE
15 #define TOP_MODULE ESI_Cosim_Top
16 #endif // TOP_MODULE
17 
18 // Macro black magic to get the header file name and class name from the
19 // TOP_MODULE macro. Need to disable formatting for this section, as
20 // clang-format messes it up by inserting spaces.
21 
22 // clang-format off
23 #define STRINGIFY_MACRO(x) STR(x)
24 #define STR(x) #x
25 #define EXPAND(x)x
26 #define CONCAT3(n1, n2, n3) STRINGIFY_MACRO(EXPAND(n1)EXPAND(n2)EXPAND(n3))
27 #define TOKENPASTE(x, y) x ## y
28 #define CLASSNAME(x, y) TOKENPASTE(x, y)
29 
30 #include CONCAT3(V,TOP_MODULE,.h)
31 // clang-format on
32 
33 #include "verilated_vcd_c.h"
34 
35 #include "signal.h"
36 #include <iostream>
37 
38 vluint64_t timeStamp;
39 
40 // Stop the simulation gracefully on ctrl-c.
41 volatile bool stopSimulation = false;
42 void handle_sigint(int) { stopSimulation = true; }
43 
44 // Called by $time in Verilog.
45 double sc_time_stamp() { return timeStamp; }
46 
47 int main(int argc, char **argv) {
48  // Register graceful exit handler.
49  signal(SIGINT, handle_sigint);
50 
51  Verilated::commandArgs(argc, argv);
52 
53  // Construct the simulated module's C++ model.
54  auto &dut = *new CLASSNAME(V, TOP_MODULE)();
55  char *waveformFile = getenv("SAVE_WAVE");
56 
57  VerilatedVcdC *tfp = nullptr;
58  if (waveformFile) {
59 #ifdef TRACE
60  tfp = new VerilatedVcdC();
61  Verilated::traceEverOn(true);
62  dut.trace(tfp, 99); // Trace 99 levels of hierarchy
63  tfp->open(waveformFile);
64  std::cout << "[driver] Writing trace to " << waveformFile << std::endl;
65 #else
66  std::cout
67  << "[driver] Warning: waveform file specified, but not a debug build"
68  << std::endl;
69 #endif
70  }
71 
72  std::cout << "[driver] Starting simulation" << std::endl;
73 
74  // TODO: Add max speed (cycles per second) option for small, interactive
75  // simulations to reduce waveform for debugging. Should this be a command line
76  // option or configurable over the cosim interface?
77 
78  // Reset.
79  dut.rst = 1;
80  dut.clk = 0;
81 
82  // TODO: Support ESI reset handshake in the future.
83  // Run for a few cycles with reset held.
84  for (timeStamp = 0; timeStamp < 8 && !Verilated::gotFinish(); timeStamp++) {
85  dut.eval();
86  dut.clk = !dut.clk;
87  if (tfp)
88  tfp->dump(timeStamp);
89  }
90 
91  // Take simulation out of reset.
92  dut.rst = 0;
93 
94  // Run for the specified number of cycles out of reset.
95  for (; !Verilated::gotFinish() && !stopSimulation; timeStamp++) {
96  dut.eval();
97  dut.clk = !dut.clk;
98  if (tfp)
99  tfp->dump(timeStamp);
100  }
101 
102  // Tell the simulator that we're going to exit. This flushes the output(s) and
103  // frees whatever memory may have been allocated.
104  dut.final();
105  if (tfp)
106  tfp->close();
107 
108  std::cout << "[driver] Ending simulation at tick #" << timeStamp << std::endl;
109  return 0;
110 }
int main(int argc, char **argv)
Definition: driver.cpp:47
vluint64_t timeStamp
Definition: driver.cpp:38
#define CLASSNAME(x, y)
Definition: driver.cpp:28
void handle_sigint(int)
Definition: driver.cpp:42
volatile bool stopSimulation
Definition: driver.cpp:41
double sc_time_stamp()
Definition: driver.cpp:45
#define TOP_MODULE
Definition: driver.cpp:15