27 save_waveform: bool =
False,
28 run_stdout_callback: Optional[Callable[[str],
None]] =
None,
29 run_stderr_callback: Optional[Callable[[str],
None]] =
None,
30 compile_stdout_callback: Optional[Callable[[str],
None]] =
None,
31 compile_stderr_callback: Optional[Callable[[str],
None]] =
None,
32 make_default_logs: bool =
True,
33 macro_definitions: Optional[Dict[str, str]] =
None,
39 save_waveform=save_waveform,
40 run_stdout_callback=run_stdout_callback,
41 run_stderr_callback=run_stderr_callback,
42 compile_stdout_callback=compile_stdout_callback,
43 compile_stderr_callback=compile_stderr_callback,
44 make_default_logs=make_default_logs,
45 macro_definitions=macro_definitions,
48 if "VERILATOR_PATH" in os.environ:
49 vpath = os.environ[
"VERILATOR_PATH"]
52 basename = Path(vpath).stem
53 if basename ==
"verilator":
54 self.
verilator_bin = str(Path(vpath).parent /
"verilator_bin")
91 """Return the commands for the full compile flow.
93 When cmake and ninja are available the returned list contains three
94 commands run sequentially:
95 1. ``verilator_bin`` – generates C++ from RTL.
96 2. ``cmake`` – configures the C++ build (Ninja generator).
97 3. ``ninja`` – builds the simulation executable.
99 Otherwise falls back to two commands:
100 1. ``verilator_bin --exe`` – generates C++ and a Makefile.
101 2. ``make`` – builds via the generated Makefile.
110 f
"+define+{k}={v}" if v
is not None else f
"+define+{k}"
129 "--trace-fst",
"--trace-params",
"--trace-structs",
134 cmd += [str(p)
for p
in self.
sources.rtl_sources]
135 build_dir = str(Path.cwd() /
"obj_dir" /
"cmake_build")
136 cmake_cmd = [
"cmake",
"-G",
"Ninja",
"-S", build_dir,
"-B", build_dir]
137 ninja_cmd = [
"ninja",
"-C", build_dir]
138 return [cmd, cmake_cmd, ninja_cmd]
143 cmd += [
"--exe", str(Verilator.DefaultDriver)]
144 cflags = [
"-DTOP_MODULE=" + self.
sources.top]
146 cflags.append(
"-DTRACE")
147 cmd += [
"-CFLAGS",
" ".join(cflags)]
149 cmd += [
"-LDFLAGS",
" ".join([
"-l" + so
for so
in self.
sources.dpi_so])]
150 cmd += [str(p)
for p
in self.
sources.rtl_sources]
152 make_cmd = [
"make",
"-C",
"obj_dir",
"-f", f
"V{top}.mk",
"-j"]
153 return [cmd, make_cmd]
156 """Write a CMakeLists.txt for building the verilated simulation.
158 Returns the path to the CMake build directory."""
160 include_dir = verilator_root /
"include"
161 exe_name =
"V" + self.
sources.top
164 include_dir /
"verilated.cpp",
165 include_dir /
"verilated_threads.cpp",
168 runtime_sources.append(include_dir /
"verilated_dpi.cpp")
170 runtime_sources.append(include_dir /
"verilated_fst_c.cpp")
172 rt_src =
"\n ".join(str(s)
for s
in runtime_sources)
173 driver = str(Verilator.DefaultDriver)
174 inc = str(include_dir)
175 vltstd = str(include_dir /
"vltstd")
177 defs = [f
"TOP_MODULE={self.sources.top}"]
180 defs_str =
"\n ".join(defs)
185 dpi_paths = self.
sources.dpi_so_paths()
186 dpi_link =
"\n ".join(str(p)
for p
in dpi_paths)
189cmake_minimum_required(VERSION 3.20)
190project({exe_name} CXX)
192file(GLOB GENERATED_SOURCES "${{CMAKE_CURRENT_SOURCE_DIR}}/../*.cpp")
194add_executable({exe_name}
195 ${{GENERATED_SOURCES}}
200target_include_directories({exe_name} PRIVATE
203 ${{CMAKE_CURRENT_SOURCE_DIR}}/..
206target_compile_definitions({exe_name} PRIVATE
210find_package(Threads REQUIRED)
211target_link_libraries({exe_name} PRIVATE
216 build_dir = obj_dir /
"cmake_build"
217 build_dir.mkdir(parents=
True, exist_ok=
True)
218 (build_dir /
"CMakeLists.txt").write_text(content)