CIRCT 23.0.0git
Loading...
Searching...
No Matches
questa.py
Go to the documentation of this file.
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5import os
6from pathlib import Path
7from typing import List, Optional, Callable, Dict
8
9from .simulator import CosimCollateralDir, Simulator, SourceFiles
10
11
13 """Run and compile funcs for Questasim."""
14
15 DefaultDriver = CosimCollateralDir / "driver.sv"
16
18 self,
19 sources: SourceFiles,
20 run_dir: Path,
21 debug: bool,
22 save_waveform: bool = False,
23 run_stdout_callback: Optional[Callable[[str], None]] = None,
24 run_stderr_callback: Optional[Callable[[str], None]] = None,
25 compile_stdout_callback: Optional[Callable[[str], None]] = None,
26 compile_stderr_callback: Optional[Callable[[str], None]] = None,
27 make_default_logs: bool = True,
28 macro_definitions: Optional[Dict[str, str]] = None,
29 # An optional list of questa error codes to suppress
30 suppressed_questa_errors: Optional[List[int]] = None):
31 super().__init__(
32 sources=sources,
33 run_dir=run_dir,
34 debug=debug,
35 save_waveform=save_waveform,
36 run_stdout_callback=run_stdout_callback,
37 run_stderr_callback=run_stderr_callback,
38 compile_stdout_callback=compile_stdout_callback,
39 compile_stderr_callback=compile_stderr_callback,
40 make_default_logs=make_default_logs,
41 macro_definitions=macro_definitions,
42 )
43 self.suppressed_questa_errors = suppressed_questa_errors
44
45 # Questa doesn't use stderr for error messages. Everything goes to stdout.
46 UsesStderr = False
47
48 def internal_compile_commands(self) -> List[str]:
49 cmds = [
50 "onerror { quit -f -code 1 }",
51 ]
52 sources = self.sources.rtl_sources
53 sources.append(Questa.DefaultDriver)
54
55 # Format macro definition command
56 if self.macro_definitions:
57 macro_definitions_cmd = " ".join([
58 f"+define+{k}={v}" if v is not None else f"+define+{k}"
59 for k, v in self.macro_definitions.items()
60 ])
61 else:
62 macro_definitions_cmd = ""
63
64 # Format error suppression command
66 suppressed_questa_errors_cmd = " ".join(
67 [f"-suppress {ec}" for ec in self.suppressed_questa_errors])
68 else:
69 suppressed_questa_errors_cmd = ""
70
71 for src in sources:
72 cmds.append(
73 f"vlog -incr +acc -sv {macro_definitions_cmd} {suppressed_questa_errors_cmd} +define+TOP_MODULE={self.sources.top}"
74 f" +define+SIMULATION {src.as_posix()}")
75 cmds.append(f"vopt -incr driver -o driver_opt +acc")
76 return cmds
77
78 def compile_commands(self) -> List[List[str]]:
79 with open("compile.do", "w") as f:
80 for cmd in self.internal_compile_commands():
81 f.write(cmd)
82 f.write("\n")
83 f.write("quit\n")
84 return [
85 ["vsim", "-batch", "-do", "compile.do"],
86 ]
87
88 def run_command(self, gui: bool) -> List[str]:
89 vsim = "vsim"
90 # Note: vsim exit codes say nothing about the test run's pass/fail even
91 # if $fatal is encountered in the simulation.
92 if gui:
93 cmd = [
94 vsim,
95 "driver_opt",
96 ]
97 else:
98 cmd = [
99 vsim,
100 "driver_opt",
101 "-batch",
102 ]
103
104 if self.debug:
105 # Create waveform dump .do file
106 wave_file = Path("wave.do")
107 with wave_file.open("w") as f:
108 f.write("log -r /*\n")
109 cmd += [
110 "-do",
111 str(wave_file.resolve()),
112 ]
113 # Questa will by default log to a vsim.wlf file in the current
114 # directory.
115 print(
116 f"Debug mode enabled - waveform will be in {wave_file.resolve().parent / 'vsim.wlf'}"
117 )
118
119 cmd += [
120 "-do",
121 "run -all",
122 ]
123
124 for lib in self.sources.dpi_so_paths():
125 svLib = os.path.splitext(lib)[0]
126 cmd.append("-sv_lib")
127 cmd.append(svLib)
128 return cmd
129
130 def run(self,
131 inner_command: str,
132 gui: bool = False,
133 server_only: bool = False) -> int:
134 """Override the Simulator.run() to add a soft link in the run directory (to
135 the work directory) before running vsim the usual way."""
136
137 # Create a soft link to the work directory.
138 workDir = self.run_dir / "work"
139 if not workDir.exists():
140 os.symlink(Path(os.getcwd()) / "work", workDir)
141
142 # Run the simulation.
143 return super().run(inner_command, gui, server_only=server_only)
static void print(TypedAttr val, llvm::raw_ostream &os)
__init__(self, SourceFiles sources, Path run_dir, bool debug, bool save_waveform=False, Optional[Callable[[str], None]] run_stdout_callback=None, Optional[Callable[[str], None]] run_stderr_callback=None, Optional[Callable[[str], None]] compile_stdout_callback=None, Optional[Callable[[str], None]] compile_stderr_callback=None, bool make_default_logs=True, Optional[Dict[str, str]] macro_definitions=None, Optional[List[int]] suppressed_questa_errors=None)
Definition questa.py:30
List[List[str]] compile_commands(self)
Definition questa.py:78
List[str] internal_compile_commands(self)
Definition questa.py:48
suppressed_questa_errors
Definition questa.py:43
List[str] run_command(self, bool gui)
Definition questa.py:88
int run(self, str inner_command, bool gui=False, bool server_only=False)
Definition questa.py:133