opencos-eda 0.3.8__py3-none-any.whl → 0.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencos/eda.py +62 -8
- opencos/eda_config_defaults.yml +14 -5
- opencos/tools/modelsim_ase.py +19 -378
- opencos/tools/questa.py +42 -247
- opencos/tools/questa_common.py +481 -0
- opencos/tools/questa_fe.py +84 -0
- opencos/tools/questa_fse.py +7 -8
- opencos/tools/riviera.py +27 -10
- opencos/utils/vsim_helper.py +8 -1
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/METADATA +2 -1
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/RECORD +16 -14
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/WHEEL +0 -0
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/entry_points.txt +0 -0
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.3.8.dist-info → opencos_eda-0.3.9.dist-info}/top_level.txt +0 -0
opencos/tools/questa.py
CHANGED
|
@@ -1,287 +1,82 @@
|
|
|
1
|
-
''' opencos.tools.questa - Used by opencos.eda commands
|
|
1
|
+
''' opencos.tools.questa - Used by opencos.eda for sim/elab commands w/ --tool=questa.
|
|
2
|
+
|
|
3
|
+
Contains classes for CommandSimQuesta, CommandElabQuesta.
|
|
4
|
+
For: Questa Edition-64 vsim 20XX.X Simulator
|
|
2
5
|
|
|
3
|
-
Also a base class for tools.modelsim_ase.
|
|
4
6
|
'''
|
|
5
7
|
|
|
6
8
|
# pylint: disable=R0801 # (setting similar, but not identical, self.defines key/value pairs)
|
|
7
9
|
|
|
8
10
|
# TODO(drew): fix these pylint eventually:
|
|
9
|
-
# pylint: disable=too-many-branches
|
|
11
|
+
# pylint: disable=too-many-branches, too-many-ancestors
|
|
10
12
|
|
|
11
13
|
import os
|
|
12
|
-
import re
|
|
13
|
-
import shutil
|
|
14
14
|
|
|
15
|
-
from opencos import
|
|
16
|
-
from opencos.eda_base import Tool
|
|
17
|
-
from opencos.commands import CommandSim, CommandFList
|
|
15
|
+
from opencos.tools.questa_common import CommonSimQuesta, CommonFListQuesta
|
|
18
16
|
|
|
19
|
-
class ToolQuesta(Tool):
|
|
20
|
-
'''Base class for CommandSimQuesta, collects version information about qrun'''
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
class CommandSimQuesta(CommonSimQuesta):
|
|
19
|
+
'''CommandSimQuesta is a command handler for: eda sim --tool=questa
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
questa_minor = None
|
|
21
|
+
Note this inherits 99% from CommonSimQuesta for command handling
|
|
22
|
+
'''
|
|
23
|
+
_TOOL = 'questa'
|
|
24
|
+
_EXE = 'vsim'
|
|
25
|
+
use_vopt = True
|
|
31
26
|
|
|
32
27
|
def __init__(self, config: dict):
|
|
33
|
-
|
|
34
|
-
self
|
|
35
|
-
|
|
36
|
-
def get_versions(self) -> str:
|
|
37
|
-
if self._VERSION:
|
|
38
|
-
return self._VERSION
|
|
39
|
-
path = shutil.which(self._EXE)
|
|
40
|
-
if not path:
|
|
41
|
-
self.error(f"{self._EXE} not in path, need to setup",
|
|
42
|
-
"(i.e. source /opt/intelFPGA_pro/23.4/settings64.sh")
|
|
43
|
-
util.debug(f"{path=}")
|
|
44
|
-
if self._EXE.endswith('qrun') and \
|
|
45
|
-
any(x in path for x in ('modelsim_ase', 'questa_fse')):
|
|
46
|
-
util.warning(f"{self._EXE=} Questa path is for starter edition",
|
|
47
|
-
"(modelsim_ase, questa_fse), consider using --tool=modelsim_ase",
|
|
48
|
-
"or --tool=questa_fse")
|
|
49
|
-
else:
|
|
50
|
-
self.sim_exe = path
|
|
51
|
-
self.sim_exe_base_path, _ = os.path.split(path)
|
|
52
|
-
|
|
53
|
-
if self._EXE.endswith('vsim'):
|
|
54
|
-
self.starter_edition = True
|
|
55
|
-
|
|
56
|
-
m = re.search(r'(\d+)\.(\d+)', path)
|
|
57
|
-
if m:
|
|
58
|
-
self.questa_major = int(m.group(1))
|
|
59
|
-
self.questa_minor = int(m.group(2))
|
|
60
|
-
self._VERSION = str(self.questa_major) + '.' + str(self.questa_minor)
|
|
61
|
-
else:
|
|
62
|
-
self.error("Questa path doesn't specificy version, expecting (d+.d+)")
|
|
63
|
-
return self._VERSION
|
|
64
|
-
|
|
65
|
-
def set_tool_defines(self):
|
|
66
|
-
# Will only be called from an object which also inherits from CommandDesign,
|
|
67
|
-
# i.e. has self.defines
|
|
68
|
-
self.defines['OC_TOOL_QUESTA'] = None
|
|
69
|
-
self.defines[f'OC_TOOL_QUESTA_{self.questa_major:d}_{self.questa_minor:d}'] = None
|
|
28
|
+
# this will setup with self._TOOL = questa, optionally repair it later
|
|
29
|
+
CommonSimQuesta.__init__(self, config=config)
|
|
70
30
|
|
|
71
|
-
|
|
72
|
-
|
|
31
|
+
# repairs: override self._TOOL, and run get_versions() again.
|
|
32
|
+
self._TOOL = 'questa'
|
|
73
33
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
ToolQuesta.__init__(self, config=self.config)
|
|
77
|
-
# add args specific to this simulator
|
|
34
|
+
self.shell_command = os.path.join(self.sim_exe_base_path, 'vsim')
|
|
35
|
+
self.starter_edition = False
|
|
78
36
|
self.args.update({
|
|
37
|
+
'tool': self._TOOL, # override
|
|
79
38
|
'gui': False,
|
|
80
|
-
'tcl-file': 'sim.tcl',
|
|
81
|
-
'work-lib': 'work',
|
|
82
|
-
})
|
|
83
|
-
self.args_help.update({
|
|
84
|
-
'gui': 'Run Questa in GUI mode',
|
|
85
|
-
'tcl-file': 'name of TCL file to be created for Questa simulation',
|
|
86
|
-
'work-lib': 'Questa work library name',
|
|
87
39
|
})
|
|
88
40
|
|
|
89
|
-
self.shell_command = self.sim_exe # set by ToolQuesta.get_versions(self)
|
|
90
|
-
self.vlog_commands = []
|
|
91
|
-
self.vopt_commands = []
|
|
92
|
-
self.vsim_commands = []
|
|
93
41
|
|
|
94
42
|
def set_tool_defines(self):
|
|
95
|
-
ToolQuesta
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
self.write_sh_scripts_to_work_dir(
|
|
105
|
-
compile_lists=self.vlog_commands,
|
|
106
|
-
elaborate_lists=self.vopt_commands,
|
|
107
|
-
simulate_lists=self.vsim_commands
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
def compile(self):
|
|
111
|
-
if self.args['stop-before-compile']:
|
|
112
|
-
return
|
|
113
|
-
self.run_commands_check_logs(
|
|
114
|
-
self.vlog_commands, check_logs=True, log_filename='vlog.log'
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
def elaborate(self):
|
|
118
|
-
if self.args['stop-before-compile'] or self.args['stop-after-compile']:
|
|
119
|
-
return
|
|
120
|
-
self.run_commands_check_logs(
|
|
121
|
-
self.vopt_commands, check_logs=True, log_filename='vopt.log'
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
def simulate(self):
|
|
125
|
-
if self.args['stop-before-compile'] or self.args['stop-after-compile'] or \
|
|
126
|
-
self.args['stop-after-elaborate']:
|
|
127
|
-
return
|
|
128
|
-
self.run_commands_check_logs(
|
|
129
|
-
self.vsim_commands, check_logs=True, log_filename='vsim.log'
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
def get_compile_command_lists(self, **kwargs) -> list:
|
|
133
|
-
self.set_tool_defines()
|
|
134
|
-
ret = []
|
|
135
|
-
|
|
136
|
-
# Create work library
|
|
137
|
-
vlib_cmd = [os.path.join(self.sim_exe_base_path, 'vlib'), self.args['work-lib']]
|
|
138
|
-
ret.append(vlib_cmd)
|
|
139
|
-
|
|
140
|
-
# Map work library
|
|
141
|
-
vmap_cmd = [os.path.join(self.sim_exe_base_path, 'vmap'), 'work', self.args['work-lib']]
|
|
142
|
-
ret.append(vmap_cmd)
|
|
143
|
-
|
|
144
|
-
# Compile files
|
|
145
|
-
if self.files_v or self.files_sv:
|
|
146
|
-
vlog_cmd = [os.path.join(self.sim_exe_base_path, 'vlog'), '-64', '-sv']
|
|
147
|
-
|
|
148
|
-
# Add include directories
|
|
149
|
-
for incdir in self.incdirs:
|
|
150
|
-
vlog_cmd += [f'+incdir+{incdir}']
|
|
151
|
-
|
|
152
|
-
# Add defines
|
|
153
|
-
for key, value in self.defines.items():
|
|
154
|
-
if value is None:
|
|
155
|
-
vlog_cmd += [f'+define+{key}']
|
|
156
|
-
else:
|
|
157
|
-
vlog_cmd += [f'+define+{key}={value}']
|
|
158
|
-
|
|
159
|
-
# Add suppression flags
|
|
160
|
-
vlog_cmd += [
|
|
161
|
-
'-svinputport=net',
|
|
162
|
-
'-suppress', 'vlog-2275',
|
|
163
|
-
'-suppress', 'vlog-2583',
|
|
164
|
-
]
|
|
165
|
-
|
|
166
|
-
# Add source files
|
|
167
|
-
vlog_cmd += self.files_v + self.files_sv
|
|
168
|
-
|
|
169
|
-
ret.append(vlog_cmd)
|
|
170
|
-
|
|
171
|
-
# Compile VHDL files if any
|
|
172
|
-
if self.files_vhd:
|
|
173
|
-
vcom_cmd = [os.path.join(self.sim_exe_base_path, 'vcom'), '-64']
|
|
174
|
-
vcom_cmd += self.files_vhd
|
|
175
|
-
ret.append(vcom_cmd)
|
|
176
|
-
|
|
177
|
-
return ret
|
|
178
|
-
|
|
179
|
-
def get_elaborate_command_lists(self, **kwargs) -> list:
|
|
180
|
-
if self.args['stop-after-compile']:
|
|
181
|
-
return []
|
|
182
|
-
|
|
183
|
-
vopt_cmd = [os.path.join(self.sim_exe_base_path, 'vopt'), '-64']
|
|
184
|
-
|
|
185
|
-
# Add optimization flags
|
|
186
|
-
vopt_cmd += [
|
|
187
|
-
'-suppress', 'vopt-13159',
|
|
188
|
-
'-suppress', 'vopt-2685',
|
|
189
|
-
'-note', 'vopt-2718',
|
|
190
|
-
]
|
|
191
|
-
|
|
192
|
-
if self.args['gui'] or self.args['waves']:
|
|
193
|
-
vopt_cmd += ['+acc']
|
|
194
|
-
|
|
195
|
-
# Add top module and output
|
|
196
|
-
vopt_cmd += [self.args['top'], '-o', 'opt_design']
|
|
197
|
-
|
|
198
|
-
return [vopt_cmd]
|
|
199
|
-
|
|
200
|
-
def get_simulate_command_lists(self, **kwargs) -> list:
|
|
201
|
-
# Create TCL file
|
|
202
|
-
tcl_name = os.path.abspath(os.path.join(self.args['work-dir'], self.args['tcl-file']))
|
|
203
|
-
|
|
204
|
-
if self.args['waves']:
|
|
205
|
-
util.artifacts.add_extension(
|
|
206
|
-
search_paths=self.args['work-dir'], file_extension='wlf',
|
|
207
|
-
typ='waveform', description='Questa Waveform WLF file'
|
|
43
|
+
'''Override from questa.ToolQuesta'''
|
|
44
|
+
# Update any defines from config.tools.questa_fse:
|
|
45
|
+
self.defines.update(
|
|
46
|
+
self.tool_config.get(
|
|
47
|
+
'defines',
|
|
48
|
+
# defaults, if not set:
|
|
49
|
+
{
|
|
50
|
+
'OC_TOOL_QUESTA': 1
|
|
51
|
+
}
|
|
208
52
|
)
|
|
209
|
-
|
|
210
|
-
with open(tcl_name, 'w', encoding='utf-8') as fo:
|
|
211
|
-
if self.args['waves']:
|
|
212
|
-
if self.args['waves-start']:
|
|
213
|
-
print(f"run {self.args['waves-start']} ns", file=fo)
|
|
214
|
-
print("add wave -r /*", file=fo)
|
|
215
|
-
print("run -all", file=fo)
|
|
216
|
-
if self.run_in_batch_mode():
|
|
217
|
-
print("quit", file=fo)
|
|
218
|
-
|
|
219
|
-
# Create vsim command
|
|
220
|
-
vsim_cmd = [os.path.join(self.sim_exe_base_path, 'vsim'), '-64']
|
|
221
|
-
|
|
222
|
-
if not self.run_in_batch_mode():
|
|
223
|
-
vsim_cmd += ['-gui']
|
|
224
|
-
else:
|
|
225
|
-
vsim_cmd += ['-c']
|
|
226
|
-
|
|
227
|
-
if util.args['verbose']:
|
|
228
|
-
vsim_cmd += ['-verbose']
|
|
229
|
-
|
|
230
|
-
# Add simulation arguments
|
|
231
|
-
vsim_cmd += ['-do', tcl_name, 'opt_design']
|
|
232
|
-
|
|
233
|
-
return [vsim_cmd]
|
|
234
|
-
|
|
235
|
-
def get_post_simulate_command_lists(self, **kwargs) -> list:
|
|
236
|
-
return []
|
|
237
|
-
|
|
238
|
-
def run_in_batch_mode(self) -> bool:
|
|
239
|
-
'''Returns bool if we should run in batch mode (-c) from command line'''
|
|
240
|
-
if self.args['test-mode']:
|
|
241
|
-
return True
|
|
242
|
-
if self.args['gui']:
|
|
243
|
-
return False
|
|
244
|
-
return True
|
|
245
|
-
|
|
246
|
-
def artifacts_add(self, name: str, typ: str, description: str) -> None:
|
|
247
|
-
'''Override from Command.artifacts_add for better descriptions'''
|
|
248
|
-
_, leafname = os.path.split(name)
|
|
249
|
-
if leafname == 'vsim.log':
|
|
250
|
-
description = 'Questa simulation step (3/3) log from stdout/stderr'
|
|
251
|
-
elif leafname == 'vopt.log':
|
|
252
|
-
description = 'Questa elaboration step (2/3) log from stdout/stderr'
|
|
253
|
-
elif leafname == 'vlog.log':
|
|
254
|
-
description = 'Questa compile step (1/3) log from stdout/stderr'
|
|
255
|
-
|
|
256
|
-
super().artifacts_add(name=name, typ=typ, description=description)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
class CommandFListQuesta(CommandFList, ToolQuesta):
|
|
260
|
-
'''CommandFListQuesta is a command handler for: eda flist --tool=questa'''
|
|
261
|
-
|
|
262
|
-
def __init__(self, config: dict):
|
|
263
|
-
CommandFList.__init__(self, config=config)
|
|
264
|
-
ToolQuesta.__init__(self, config=self.config)
|
|
53
|
+
)
|
|
265
54
|
|
|
266
55
|
|
|
267
56
|
class CommandElabQuesta(CommandSimQuesta):
|
|
268
|
-
'''
|
|
57
|
+
'''CommandElabQuesta is a command handler for: eda elab --tool=questa'''
|
|
269
58
|
|
|
270
59
|
command_name = 'elab'
|
|
271
60
|
|
|
272
61
|
def __init__(self, config:dict):
|
|
273
|
-
|
|
274
|
-
# add args specific to this simulator
|
|
62
|
+
super().__init__(config)
|
|
275
63
|
self.args['stop-after-elaborate'] = True
|
|
276
64
|
|
|
277
65
|
|
|
278
66
|
class CommandLintQuesta(CommandSimQuesta):
|
|
279
|
-
'''
|
|
67
|
+
'''CommandLintQuesta is a command handler for: eda lint --tool=questa'''
|
|
280
68
|
|
|
281
69
|
command_name = 'lint'
|
|
282
70
|
|
|
283
71
|
def __init__(self, config:dict):
|
|
284
|
-
|
|
285
|
-
# add args specific to this simulator
|
|
72
|
+
super().__init__(config)
|
|
286
73
|
self.args['stop-after-compile'] = True
|
|
287
74
|
self.args['stop-after-elaborate'] = True
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CommandFListQuesta(CommonFListQuesta):
|
|
78
|
+
'''CommandFListQuesta is a command handler for: eda flist --tool=questa'''
|
|
79
|
+
|
|
80
|
+
def __init__(self, config: dict):
|
|
81
|
+
CommonFListQuesta.__init__(self, config=config)
|
|
82
|
+
self._TOOL = 'questa'
|