opencos-eda 0.2.49__py3-none-any.whl → 0.2.51__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/commands/lec.py +7 -4
- opencos/commands/multi.py +1 -1
- opencos/commands/shell.py +11 -8
- opencos/commands/sim.py +43 -22
- opencos/deps/deps_file.py +67 -14
- opencos/eda.py +15 -3
- opencos/eda_base.py +54 -20
- opencos/eda_config.py +6 -0
- opencos/eda_config_defaults.yml +36 -14
- opencos/eda_deps_sanitize.py +73 -0
- opencos/tests/test_eda_elab.py +2 -1
- opencos/tests/test_tools.py +1 -0
- opencos/tools/modelsim_ase.py +22 -0
- opencos/tools/questa.py +5 -3
- opencos/tools/questa_fse.py +59 -0
- opencos/tools/slang.py +8 -2
- opencos/tools/verilator.py +25 -0
- opencos/tools/vivado.py +33 -26
- opencos/tools/yosys.py +21 -5
- opencos/util.py +183 -8
- opencos/utils/markup_helpers.py +31 -2
- opencos/utils/status_constants.py +27 -0
- opencos/utils/vsim_helper.py +55 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/METADATA +1 -1
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/RECORD +30 -26
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/entry_points.txt +1 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/WHEEL +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/top_level.txt +0 -0
opencos/eda_config_defaults.yml
CHANGED
|
@@ -230,17 +230,39 @@ tools:
|
|
|
230
230
|
compile-args: |
|
|
231
231
|
-sv -svinputport=net -lint
|
|
232
232
|
compile-waivers:
|
|
233
|
-
- 2275 # 2275 - Existing package '
|
|
234
|
-
- 2555 # 2555 - assignment to input port
|
|
233
|
+
- 2275 # 2275 - Existing package 'myname_pkg' will be overwritten.
|
|
234
|
+
- 2555 # 2555 - assignment to input port myname
|
|
235
235
|
- 2583 # 2583 - [SVCHK] - Extra checking for conflicts with always_comb and
|
|
236
236
|
# always_latch variables is done at vopt time.
|
|
237
237
|
simulate-waivers:
|
|
238
|
-
- 3009 # 3009: [TSCALE] - Module '
|
|
238
|
+
- 3009 # 3009: [TSCALE] - Module 'myname' does not have a timeunit/timeprecision
|
|
239
239
|
# specification in effect, but other modules do.
|
|
240
240
|
simulate-waves-args: |
|
|
241
241
|
+acc
|
|
242
242
|
|
|
243
243
|
|
|
244
|
+
questa_fse:
|
|
245
|
+
defines:
|
|
246
|
+
OC_TOOL_QUESTA_FSE: 1
|
|
247
|
+
log-bad-strings:
|
|
248
|
+
- "Error:"
|
|
249
|
+
log-must-strings:
|
|
250
|
+
- " vsim "
|
|
251
|
+
- "Errors: 0"
|
|
252
|
+
compile-args: |
|
|
253
|
+
-sv -svinputport=net -lint
|
|
254
|
+
compile-waivers:
|
|
255
|
+
- 2275 # 2275 - Existing package 'myname_pkg' will be overwritten.
|
|
256
|
+
- 2555 # 2555 - assignment to input port myname
|
|
257
|
+
- 2583 # 2583 - [SVCHK] - Extra checking for conflicts with always_comb and
|
|
258
|
+
# always_latch variables is done at vopt time.
|
|
259
|
+
simulate-waivers:
|
|
260
|
+
- 3009 # 3009: [TSCALE] - Module 'myname' does not have a timeunit/timeprecision
|
|
261
|
+
# specification in effect, but other modules do.
|
|
262
|
+
simulate-waves-args: |
|
|
263
|
+
-voptargs=+acc=bcgnprst
|
|
264
|
+
|
|
265
|
+
|
|
244
266
|
iverilog:
|
|
245
267
|
log-bad-strings:
|
|
246
268
|
- "Error:"
|
|
@@ -303,7 +325,7 @@ auto_tools_order:
|
|
|
303
325
|
# TODO(drew): surelog is disabled from `eda tools-multi`. It is still
|
|
304
326
|
# enabled for `eda [multi] elab --tool surelog`. It does not support
|
|
305
327
|
# type comparisons:
|
|
306
|
-
# if type(
|
|
328
|
+
# if type(myname) == type(othername)
|
|
307
329
|
# [ERR:UH0700] ... Unsupported expression
|
|
308
330
|
# modelsim_ase also doesn't, but it won't fail elab, whereas surelog does.
|
|
309
331
|
surelog:
|
|
@@ -376,9 +398,7 @@ auto_tools_order:
|
|
|
376
398
|
|
|
377
399
|
questa:
|
|
378
400
|
exe: qrun
|
|
379
|
-
|
|
380
|
-
- qrun -version
|
|
381
|
-
- vsim -version
|
|
401
|
+
requires_vsim_helper: True
|
|
382
402
|
handlers:
|
|
383
403
|
elab: opencos.tools.queta.CommandElabQuesta
|
|
384
404
|
sim: opencos.tools.queta.CommandSimQuesta
|
|
@@ -386,24 +406,26 @@ auto_tools_order:
|
|
|
386
406
|
riviera:
|
|
387
407
|
exe: vsim
|
|
388
408
|
requires_cmd:
|
|
389
|
-
- vsim -version
|
|
390
409
|
- which riviera # Do not run it, make sure it's in PATH
|
|
391
|
-
|
|
392
|
-
- riviera
|
|
410
|
+
requires_vsim_helper: True
|
|
393
411
|
handlers:
|
|
394
412
|
elab: opencos.tools.riviera.CommandElabRiviera
|
|
395
413
|
sim: opencos.tools.riviera.CommandSimRiviera
|
|
396
414
|
|
|
397
415
|
modelsim_ase:
|
|
398
416
|
exe: vsim
|
|
399
|
-
|
|
400
|
-
- vsim -version
|
|
401
|
-
requires_in_exe_path:
|
|
402
|
-
- modelsim
|
|
417
|
+
requires_vsim_helper: True
|
|
403
418
|
handlers:
|
|
404
419
|
elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
|
|
405
420
|
sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
|
|
406
421
|
|
|
422
|
+
questa_fse: # free student edition, works similar to modelsim_ase
|
|
423
|
+
exe: vsim
|
|
424
|
+
requires_vsim_helper: True
|
|
425
|
+
handlers:
|
|
426
|
+
elab: opencos.tools.questa_fse.CommandElabQuestaFse
|
|
427
|
+
sim: opencos.tools.questa_fse.CommandSimQuestaFse
|
|
428
|
+
|
|
407
429
|
iverilog:
|
|
408
430
|
exe: iverilog
|
|
409
431
|
handlers:
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
'''opencos.eda_deps_sanitize is an executable script
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
eda_deps_sanitize --dir=<path>
|
|
7
|
+
|
|
8
|
+
Will print santized JSON data for the DEPS file found in --dir=<path>
|
|
9
|
+
'''
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from opencos import util
|
|
18
|
+
from opencos.deps import deps_file
|
|
19
|
+
from opencos.utils import status_constants
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run(*args) -> (int, str):
|
|
23
|
+
'''Runs the DEPS sanitizer, prints results to stdout'''
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
bool_kwargs = util.get_argparse_bool_action_kwargs()
|
|
27
|
+
|
|
28
|
+
parser = argparse.ArgumentParser(
|
|
29
|
+
prog='opencos eda_deps_sanitize', add_help=True, allow_abbrev=False
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
parser.add_argument('--yaml', **bool_kwargs,
|
|
33
|
+
help='Print output as YAML text, otherwise default is JSON text')
|
|
34
|
+
parser.add_argument('dir', type=str, default=str(Path('.')),
|
|
35
|
+
help='Directory to look for DEPS.[markup] file')
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
parsed, unparsed = parser.parse_known_args(list(args) + [''])
|
|
39
|
+
unparsed = list(filter(None, unparsed))
|
|
40
|
+
except argparse.ArgumentError:
|
|
41
|
+
return 1, f'problem attempting to parse_known_args for {args=}'
|
|
42
|
+
|
|
43
|
+
deps_path = parsed.dir
|
|
44
|
+
if os.path.isfile(deps_path):
|
|
45
|
+
deps_path, _ = os.path.split(deps_path)
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
my_depsfile_obj = deps_file.DepsFile(None, deps_path, {})
|
|
49
|
+
if not my_depsfile_obj.deps_file:
|
|
50
|
+
return status_constants.EDA_DEPS_FILE_NOT_FOUND, f'No DEPS markup file at {parsed.dir}'
|
|
51
|
+
|
|
52
|
+
ret_str = my_depsfile_obj.str_sanitized_markup(as_yaml=parsed.yaml)
|
|
53
|
+
rc = util.get_return_code()
|
|
54
|
+
return rc, ret_str
|
|
55
|
+
except Exception as e:
|
|
56
|
+
rc = 1, str(e)
|
|
57
|
+
|
|
58
|
+
return 0, ''
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main() -> None:
|
|
62
|
+
'''calls sys.exit(), main entrypoint'''
|
|
63
|
+
args = []
|
|
64
|
+
if len(sys.argv) > 1 and not args:
|
|
65
|
+
args = sys.argv[1:]
|
|
66
|
+
|
|
67
|
+
rc, deps_str = run(*args)
|
|
68
|
+
print(deps_str)
|
|
69
|
+
sys.exit(rc)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == '__main__':
|
|
73
|
+
main()
|
opencos/tests/test_eda_elab.py
CHANGED
opencos/tests/test_tools.py
CHANGED
opencos/tools/modelsim_ase.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
''' opencos.tools.modelsim_ase - Used by opencos.eda for sim/elab commands w/ --tool=modelsim_ase.
|
|
2
2
|
|
|
3
3
|
Contains classes for ToolModelsimAse, CommandSimModelsimAse, CommandElabModelsimAse.
|
|
4
|
+
|
|
5
|
+
Note that this is for 32-bit Modelsim Student Edition. Consider using --tool=questa_fse instead.
|
|
4
6
|
'''
|
|
5
7
|
|
|
6
8
|
# pylint: disable=R0801 # (duplicate code in derived classes, such as if-condition return.)
|
|
@@ -151,6 +153,9 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
|
|
|
151
153
|
]):
|
|
152
154
|
vlog_dot_f_lines += ['-suppress', str(waiver)]
|
|
153
155
|
|
|
156
|
+
if self.args['gui'] or self.args['waves']:
|
|
157
|
+
vlog_dot_f_lines += self.tool_config.get('compile-waves-args', '').split()
|
|
158
|
+
|
|
154
159
|
vlog_dot_f_fname = filename
|
|
155
160
|
vlog_dot_f_fpath = os.path.join(self.args['work-dir'], vlog_dot_f_fname)
|
|
156
161
|
|
|
@@ -203,6 +208,10 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
|
|
|
203
208
|
voptargs_str = ""
|
|
204
209
|
if self.args['gui'] or self.args['waves']:
|
|
205
210
|
voptargs_str = self.tool_config.get('simulate-waves-args', '+acc')
|
|
211
|
+
util.artifacts.add_extension(
|
|
212
|
+
search_paths=self.args['work-dir'], file_extension='wlf',
|
|
213
|
+
typ='waveform', description='Modelsim/Questa Waveform WLF (Wave Log Format) file'
|
|
214
|
+
)
|
|
206
215
|
|
|
207
216
|
# TODO(drew): support self.args['sim_libary', 'elab-args', sim-args'] (3 lists)
|
|
208
217
|
# to add to vsim_one_liner.
|
|
@@ -331,6 +340,19 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
|
|
|
331
340
|
return ' '.join(vsim_suppress_list)
|
|
332
341
|
|
|
333
342
|
|
|
343
|
+
def artifacts_add(self, name: str, typ: str, description: str) -> None:
|
|
344
|
+
'''Override from Command.artifacts_add, so we can catch known file
|
|
345
|
+
|
|
346
|
+
names to make their typ/description better, such as CommandSim using
|
|
347
|
+
sim.log
|
|
348
|
+
'''
|
|
349
|
+
_, leafname = os.path.split(name)
|
|
350
|
+
if leafname == 'sim.log':
|
|
351
|
+
description = 'Modelsim/Questa Transcript log file'
|
|
352
|
+
|
|
353
|
+
super().artifacts_add(name=name, typ=typ, description=description)
|
|
354
|
+
|
|
355
|
+
|
|
334
356
|
class CommandElabModelsimAse(CommandSimModelsimAse):
|
|
335
357
|
'''CommandElabModelsimAse is a command handler for: eda elab --tool=modelsim_ase'''
|
|
336
358
|
|
opencos/tools/questa.py
CHANGED
|
@@ -40,9 +40,11 @@ class ToolQuesta(Tool):
|
|
|
40
40
|
self.error(f"{self._EXE} not in path, need to setup",
|
|
41
41
|
"(i.e. source /opt/intelFPGA_pro/23.4/settings64.sh")
|
|
42
42
|
util.debug(f"{path=}")
|
|
43
|
-
if self._EXE.endswith('qrun') and
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if self._EXE.endswith('qrun') and \
|
|
44
|
+
any(x in path for x in ('modelsim_ase', 'questa_fse')):
|
|
45
|
+
util.warning(f"{self._EXE=} Questa path is for starter edition",
|
|
46
|
+
"(modelsim_ase, questa_fse), consider using --tool=modelsim_ase",
|
|
47
|
+
"or --tool=questa_fse")
|
|
46
48
|
else:
|
|
47
49
|
self.sim_exe = path
|
|
48
50
|
self.sim_exe_base_path, _ = os.path.split(path)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
''' opencos.tools.questa_fse - Used by opencos.eda for sim/elab commands w/ --tool=questa_fse.
|
|
2
|
+
|
|
3
|
+
Contains classes for CommandSimQuestaFse, CommandElabQuestaFse.
|
|
4
|
+
For: Questa Intel Starter FPGA Edition-64 vsim 20XX.X Simulator
|
|
5
|
+
|
|
6
|
+
'''
|
|
7
|
+
|
|
8
|
+
# pylint: disable=R0801 # (duplicate code in derived classes, such as if-condition return.)
|
|
9
|
+
# pylint: disable=too-many-ancestors
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
from opencos.tools.modelsim_ase import CommandSimModelsimAse
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CommandSimQuestaFse(CommandSimModelsimAse):
|
|
17
|
+
'''CommandSimQuestaFse is a command handler for: eda sim --tool=questa_fse
|
|
18
|
+
|
|
19
|
+
Note this inherits 99% from CommandSimModelSimAse for command handling
|
|
20
|
+
'''
|
|
21
|
+
_TOOL = 'questa_fse'
|
|
22
|
+
_EXE = 'vsim'
|
|
23
|
+
|
|
24
|
+
def __init__(self, config: dict):
|
|
25
|
+
# this will setup with self._TOOL = modelsim_ase, which is not ideal so
|
|
26
|
+
# we have to repait it later.
|
|
27
|
+
CommandSimModelsimAse.__init__(self, config=config)
|
|
28
|
+
|
|
29
|
+
# repairs: override self._TOOL, and run get_versions() again.
|
|
30
|
+
self._TOOL = 'questa_fse'
|
|
31
|
+
|
|
32
|
+
self.shell_command = os.path.join(self.sim_exe_base_path, 'vsim')
|
|
33
|
+
self.starter_edition = True
|
|
34
|
+
self.args.update({
|
|
35
|
+
'tool': self._TOOL, # override
|
|
36
|
+
'gui': False,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def set_tool_defines(self):
|
|
41
|
+
'''Override from questa.ToolQuesta'''
|
|
42
|
+
# Update any defines from config.tools.questa_fse:
|
|
43
|
+
self.defines.update(
|
|
44
|
+
self.tool_config.get(
|
|
45
|
+
'defines',
|
|
46
|
+
# defaults, if not set:
|
|
47
|
+
{
|
|
48
|
+
'OC_TOOL_QUESTA_FSE': 1
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CommandElabQuestaFse(CommandSimQuestaFse):
|
|
55
|
+
'''CommandElabQuestaFse is a command handler for: eda elab --tool=questa_fse'''
|
|
56
|
+
|
|
57
|
+
def __init__(self, config:dict):
|
|
58
|
+
super().__init__(config)
|
|
59
|
+
self.args['stop-after-elaborate'] = True
|
opencos/tools/slang.py
CHANGED
|
@@ -191,14 +191,20 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
191
191
|
|
|
192
192
|
return command_list
|
|
193
193
|
|
|
194
|
-
def _get_slang_json_args(self, command_exe:str) -> list:
|
|
194
|
+
def _get_slang_json_args(self, command_exe: str) -> list:
|
|
195
195
|
command_list = []
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
_, command_exe_leaf = os.path.split(command_exe)
|
|
198
|
+
if self.args.get('slang-json', False) and command_exe_leaf == 'slang':
|
|
198
199
|
for arg in self.all_json_args:
|
|
199
200
|
if arg not in command_list:
|
|
200
201
|
command_list.append(arg)
|
|
201
202
|
if arg == '--ast-json': # needs filename
|
|
202
203
|
command_list.append('slang.json')
|
|
204
|
+
util.artifacts.add(
|
|
205
|
+
name=os.path.join(self.args['work-dir'], 'slang.json'),
|
|
206
|
+
typ='json',
|
|
207
|
+
description='Abstract syntax tree from slang --ast-json'
|
|
208
|
+
)
|
|
203
209
|
|
|
204
210
|
return command_list
|
opencos/tools/verilator.py
CHANGED
|
@@ -346,6 +346,16 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
346
346
|
util.info(f'--waves arg present, no $dumpfile found, adding SV file: {file_to_add}')
|
|
347
347
|
self.add_file(file_to_add)
|
|
348
348
|
|
|
349
|
+
# register .vcd or .fst artifacts:
|
|
350
|
+
util.artifacts.add_extension(
|
|
351
|
+
search_paths=self.args['work-dir'], file_extension='fst',
|
|
352
|
+
typ='waveform', description='Simulation Waveform FST (Fast Signal Trace) file'
|
|
353
|
+
)
|
|
354
|
+
util.artifacts.add_extension(
|
|
355
|
+
search_paths=self.args['work-dir'], file_extension='vcd',
|
|
356
|
+
typ='waveform', description='Simulation Waveform VCD (Value Change Dump) file'
|
|
357
|
+
)
|
|
358
|
+
|
|
349
359
|
|
|
350
360
|
def _get_start_verilator_command_list(self, lint_only: bool = False) -> list:
|
|
351
361
|
|
|
@@ -447,6 +457,21 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
447
457
|
return verilate_args
|
|
448
458
|
|
|
449
459
|
|
|
460
|
+
def artifacts_add(self, name: str, typ: str, description: str) -> None:
|
|
461
|
+
'''Override from Command.artifacts_add, so we can catch known file
|
|
462
|
+
|
|
463
|
+
names to make their typ/description better, such as CommandSim using
|
|
464
|
+
sim.log or compile.log
|
|
465
|
+
'''
|
|
466
|
+
_, leafname = os.path.split(name)
|
|
467
|
+
if leafname == 'sim.log':
|
|
468
|
+
description = 'Verilated executable log from stdout/stderr'
|
|
469
|
+
elif leafname == 'compile.log':
|
|
470
|
+
description = 'Verilator compile step log from verilator call'
|
|
471
|
+
|
|
472
|
+
super().artifacts_add(name=name, typ=typ, description=description)
|
|
473
|
+
|
|
474
|
+
|
|
450
475
|
class VerilatorElab(VerilatorSim):
|
|
451
476
|
'''VerilatorElab is a command handler for: eda elab --tool=verilator'''
|
|
452
477
|
|
opencos/tools/vivado.py
CHANGED
|
@@ -63,29 +63,14 @@ class ToolVivado(Tool):
|
|
|
63
63
|
util.info("environment for XILINX_VIVADO is not set or doesn't match the vivado path:",
|
|
64
64
|
f"XILINX_VIVADO={xilinx_vivado} EXE PATH={self.vivado_exe}")
|
|
65
65
|
|
|
66
|
-
version
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# words = lines[0].split() # vivado v2024.2.1 (64-bit)
|
|
75
|
-
# version = words[1][1:] # 2024.2.1
|
|
76
|
-
# self._VERSION = version
|
|
77
|
-
#except:
|
|
78
|
-
# pass
|
|
79
|
-
|
|
80
|
-
if not version:
|
|
81
|
-
# Get version based on install path name:
|
|
82
|
-
util.debug(f"vivado path = {self.vivado_exe}")
|
|
83
|
-
m = re.search(r'(\d\d\d\d)\.(\d)', self.vivado_exe)
|
|
84
|
-
if m:
|
|
85
|
-
version = m.group(1) + '.' + m.group(2)
|
|
86
|
-
self._VERSION = version
|
|
87
|
-
else:
|
|
88
|
-
self.error("Vivado path doesn't specificy version, expecting (dddd.d)")
|
|
66
|
+
# Get version based on install path name. Calling vivado -verison is too slow.
|
|
67
|
+
util.debug(f"vivado path = {self.vivado_exe}")
|
|
68
|
+
m = re.search(r'(\d\d\d\d)\.(\d)', self.vivado_exe)
|
|
69
|
+
if m:
|
|
70
|
+
version = m.group(1) + '.' + m.group(2)
|
|
71
|
+
self._VERSION = version
|
|
72
|
+
else:
|
|
73
|
+
self.error("Vivado path doesn't specificy version, expecting (dddd.d)")
|
|
89
74
|
|
|
90
75
|
if version:
|
|
91
76
|
numbers_list = version.split('.')
|
|
@@ -260,6 +245,14 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
260
245
|
def get_simulate_command_lists(self, **kwargs) -> list:
|
|
261
246
|
# create TCL
|
|
262
247
|
tcl_name = os.path.abspath(os.path.join(self.args['work-dir'], self.args['tcl-file']))
|
|
248
|
+
|
|
249
|
+
if self.args['waves']:
|
|
250
|
+
util.artifacts.add_extension(
|
|
251
|
+
search_paths=self.args['work-dir'], file_extension='wdb',
|
|
252
|
+
typ='waveform', description='Vivado XSim Waveform WDB (Wave DataBase) file'
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
|
|
263
256
|
with open( tcl_name, 'w', encoding='utf-8' ) as fo:
|
|
264
257
|
if self.args['waves']:
|
|
265
258
|
if self.args['waves-start']:
|
|
@@ -345,6 +338,23 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
345
338
|
self.files_v.insert(0, glbl_v)
|
|
346
339
|
|
|
347
340
|
|
|
341
|
+
def artifacts_add(self, name: str, typ: str, description: str) -> None:
|
|
342
|
+
'''Override from Command.artifacts_add, so we can catch known file
|
|
343
|
+
|
|
344
|
+
names to make their typ/description better, such as CommandSim using
|
|
345
|
+
sim.log or compile.log
|
|
346
|
+
'''
|
|
347
|
+
_, leafname = os.path.split(name)
|
|
348
|
+
if leafname == 'xsim.log':
|
|
349
|
+
description = 'Vivado XSim simulation step (3/3) log from stdout/stderr'
|
|
350
|
+
elif leafname == 'xelab.log':
|
|
351
|
+
description = 'Vivado XSim elaboration step (2/3) log from stdout/stderr'
|
|
352
|
+
elif leafname == 'xvlog.log':
|
|
353
|
+
description = 'Vivado XSim compile step (1/3) log from stdout/stderr'
|
|
354
|
+
|
|
355
|
+
super().artifacts_add(name=name, typ=typ, description=description)
|
|
356
|
+
|
|
357
|
+
|
|
348
358
|
class CommandElabVivado(CommandSimVivado):
|
|
349
359
|
'''CommandElabVivado is a command handler for: eda elab --tool=vivado, uses xvlog, xelab'''
|
|
350
360
|
def __init__(self, config: dict):
|
|
@@ -933,9 +943,6 @@ class CommandUploadVivado(CommandUpload, ToolVivado):
|
|
|
933
943
|
util.info("Upload done")
|
|
934
944
|
|
|
935
945
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
946
|
class CommandOpenVivado(CommandOpen, ToolVivado):
|
|
940
947
|
'''CommandOpenVivado command handler class used by: eda open --tool vivado'''
|
|
941
948
|
def __init__(self, config: dict):
|
opencos/tools/yosys.py
CHANGED
|
@@ -117,6 +117,7 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
117
117
|
'yosys-blackbox': [], # list of modules that yosys will blackbox.
|
|
118
118
|
'yosys-scriptfile': [],
|
|
119
119
|
'sta-scriptfile': [],
|
|
120
|
+
'rename-module': ''
|
|
120
121
|
})
|
|
121
122
|
self.args_help.update({
|
|
122
123
|
'sta': (
|
|
@@ -150,12 +151,14 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
150
151
|
' via: sta -no_init -exit <this-arg>. You can set multiple args for multiple'
|
|
151
152
|
' scriptfile (appends)'
|
|
152
153
|
),
|
|
154
|
+
'rename-module': 'Renames the output .v and module name',
|
|
153
155
|
})
|
|
154
156
|
|
|
155
157
|
self.yosys_out_dir = ''
|
|
156
158
|
self.yosys_v_path = ''
|
|
157
159
|
self.full_work_dir = ''
|
|
158
160
|
self.blackbox_list = []
|
|
161
|
+
self.top_module = ''
|
|
159
162
|
|
|
160
163
|
def do_it(self) -> None:
|
|
161
164
|
self.set_tool_defines()
|
|
@@ -333,6 +336,13 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
333
336
|
]
|
|
334
337
|
lines += [
|
|
335
338
|
'opt_clean',
|
|
339
|
+
]
|
|
340
|
+
if self.args['rename-module']:
|
|
341
|
+
lines += [f'rename {self.args["top"]} {self.args["rename-module"]}']
|
|
342
|
+
self.top_module = self.args['rename-module']
|
|
343
|
+
else:
|
|
344
|
+
self.top_module = self.args["top"]
|
|
345
|
+
lines += [
|
|
336
346
|
f'write_verilog {self.yosys_v_path}',
|
|
337
347
|
f'write_json {self.yosys_v_path}.json',
|
|
338
348
|
]
|
|
@@ -388,7 +398,7 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
388
398
|
lines = [
|
|
389
399
|
'read_liberty ' + self.args['liberty-file'],
|
|
390
400
|
'read_verilog ' + self.yosys_v_path,
|
|
391
|
-
'link_design ' + self.
|
|
401
|
+
'link_design ' + self.top_module,
|
|
392
402
|
]
|
|
393
403
|
for _file in self.files_sdc:
|
|
394
404
|
lines.append('read_sdc ' + _file)
|
|
@@ -505,12 +515,13 @@ class CommandLecYosys(CommandLec, ToolYosys):
|
|
|
505
515
|
})
|
|
506
516
|
|
|
507
517
|
self.synth_work_dirs = [
|
|
508
|
-
os.path.join('eda.work', 'lec.
|
|
509
|
-
os.path.join('eda.work', 'lec.
|
|
518
|
+
os.path.join('eda.work', 'lec.Design1.synth'),
|
|
519
|
+
os.path.join('eda.work', 'lec.Design2.synth')
|
|
510
520
|
]
|
|
511
521
|
|
|
512
522
|
self.synth_designs_tops = [None, None]
|
|
513
523
|
self.synth_designs_fpaths = [None, None]
|
|
524
|
+
self.synth_design_top_module_names = [None, None]
|
|
514
525
|
|
|
515
526
|
def get_synth_result_fpath(self, target: str) -> str:
|
|
516
527
|
'''Overridden from CommandLec'''
|
|
@@ -534,9 +545,12 @@ class CommandLecYosys(CommandLec, ToolYosys):
|
|
|
534
545
|
|
|
535
546
|
synth_cmd_list += [
|
|
536
547
|
'--work-dir=' + self.synth_work_dirs[design_num],
|
|
537
|
-
self.args['designs'][design_num]
|
|
548
|
+
self.args['designs'][design_num],
|
|
549
|
+
f'--rename-module=Design{design_num + 1}'
|
|
538
550
|
]
|
|
539
551
|
|
|
552
|
+
self.synth_design_top_module_names[design_num] = f'Design{design_num + 1}'
|
|
553
|
+
|
|
540
554
|
return synth_cmd_list
|
|
541
555
|
|
|
542
556
|
|
|
@@ -663,10 +677,12 @@ class CommandLecYosys(CommandLec, ToolYosys):
|
|
|
663
677
|
else:
|
|
664
678
|
self.error(f' --pre-read-verilog file {x} does not exist')
|
|
665
679
|
lec_cmd_f_list += [
|
|
680
|
+
'# Design1 (module):',
|
|
666
681
|
f'read_verilog -sv -icells {self.synth_designs_fpaths[0]}',
|
|
682
|
+
'# Design2 (module):',
|
|
667
683
|
f'read_verilog -sv -icells {self.synth_designs_fpaths[1]}',
|
|
668
684
|
'clk2fflogic;',
|
|
669
|
-
f'miter -equiv -flatten {" ".join(self.
|
|
685
|
+
f'miter -equiv -flatten {" ".join(self.synth_design_top_module_names)} miter',
|
|
670
686
|
('sat -seq 50 -verify -prove trigger 0 -show-all -show-inputs -show-outputs'
|
|
671
687
|
' -set-init-zero miter'),
|
|
672
688
|
]
|