opencos-eda 0.2.54__tar.gz → 0.2.55__tar.gz
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-0.2.54/opencos_eda.egg-info → opencos_eda-0.2.55}/PKG-INFO +2 -2
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/__init__.py +2 -0
- opencos_eda-0.2.55/opencos/commands/lint.py +51 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps/deps_file.py +3 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda.py +16 -5
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_config_defaults.yml +13 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/helpers.py +5 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_eda_elab.py +26 -5
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/invio.py +8 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/invio_helpers.py +24 -6
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/invio_yosys.py +3 -2
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/iverilog.py +13 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/modelsim_ase.py +13 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/quartus.py +61 -6
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/questa.py +14 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/questa_fse.py +13 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/riviera.py +13 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/slang.py +12 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/surelog.py +13 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/verilator.py +14 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/vivado.py +11 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/yosys.py +15 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/util.py +7 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/str_helpers.py +8 -4
- {opencos_eda-0.2.54 → opencos_eda-0.2.55/opencos_eda.egg-info}/PKG-INFO +2 -2
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos_eda.egg-info/SOURCES.txt +1 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos_eda.egg-info/requires.txt +1 -1
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/pyproject.toml +2 -2
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/LICENSE +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/LICENSE.spdx +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/README.md +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/_version.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/build.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/deps_help.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/export.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/flist.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/lec.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/multi.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/open.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/proj.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/shell.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/sim.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/sweep.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/synth.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/upload.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/commands/waves.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps/defaults.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps/deps_commands.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps/deps_processor.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/deps_schema.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_base.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_config.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_deps_sanitize.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_extract_targets.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/eda_tool_helper.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/export_helper.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/export_json_convert.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/files.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/hw/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/hw/oc_cli.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/hw/pcie.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/names.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/peakrdl_cleanup.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/seed.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_deps_helpers.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_eda.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_eda_synth.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_oc_cli.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tests/test_tools.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/cocotb.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/__init__.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/markup_helpers.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/status_constants.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/subprocess_helpers.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/vscode_helper.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos/utils/vsim_helper.py +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos_eda.egg-info/entry_points.txt +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.2.54 → opencos_eda-0.2.55}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.55
|
|
4
4
|
Summary: A simple Python package for wrapping RTL simuliatons and synthesis
|
|
5
5
|
Author-email: Simon Sabato <simon@cognichip.ai>, Drew Ranck <drew@cognichip.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/cognichip/opencos
|
|
@@ -15,5 +15,5 @@ Requires-Dist: schema>=0.7.7
|
|
|
15
15
|
Requires-Dist: toml>=0.10.2
|
|
16
16
|
Requires-Dist: yamllint>=1.35.1
|
|
17
17
|
Requires-Dist: PySerial>=3.5
|
|
18
|
-
Requires-Dist: cocotb>=2.0
|
|
18
|
+
Requires-Dist: cocotb>=2.0
|
|
19
19
|
Dynamic: license-file
|
|
@@ -10,6 +10,7 @@ from .elab import CommandElab
|
|
|
10
10
|
from .export import CommandExport
|
|
11
11
|
from .flist import CommandFList
|
|
12
12
|
from .multi import CommandMulti, CommandToolsMulti
|
|
13
|
+
from .lint import CommandLint
|
|
13
14
|
from .open import CommandOpen
|
|
14
15
|
from .proj import CommandProj
|
|
15
16
|
from .sim import CommandSim
|
|
@@ -28,6 +29,7 @@ __all__ = [
|
|
|
28
29
|
'CommandExport',
|
|
29
30
|
'CommandFList',
|
|
30
31
|
'CommandMulti',
|
|
32
|
+
'CommandLint',
|
|
31
33
|
'CommandOpen',
|
|
32
34
|
'CommandProj',
|
|
33
35
|
'CommandSim',
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'''opencos.commands.lint - Base class command handler for: eda lint ...
|
|
2
|
+
|
|
3
|
+
Intended to be overriden by Tool based classes (such as CommandLintVivado, etc)
|
|
4
|
+
|
|
5
|
+
Note that many 'lint' command handlers that also can perform simulations, such
|
|
6
|
+
as VerilatorLint, will instead inherit from VerilatorSim and simply perform a
|
|
7
|
+
shortened sim as the lint, instead of inheriting CommandLint.
|
|
8
|
+
|
|
9
|
+
Tools that don't support a 'sim' command will generally use CommandLint, such
|
|
10
|
+
as CommandLintSlang.'''
|
|
11
|
+
|
|
12
|
+
from opencos.commands.sim import CommandSim
|
|
13
|
+
|
|
14
|
+
class CommandLint(CommandSim):
|
|
15
|
+
'''Base class command handler for: eda lint ...'''
|
|
16
|
+
|
|
17
|
+
command_name = 'lint'
|
|
18
|
+
|
|
19
|
+
def __init__(self, config: dict):
|
|
20
|
+
CommandSim.__init__(self, config=config)
|
|
21
|
+
# add args specific to this simulator
|
|
22
|
+
self.args['stop-after-compile'] = True
|
|
23
|
+
self.args['lint'] = True
|
|
24
|
+
self.args['verilate-args'] = []
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def compile(self) -> None:
|
|
29
|
+
raise NotImplementedError
|
|
30
|
+
|
|
31
|
+
def elaborate(self) -> None:
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
|
|
34
|
+
def get_compile_command_lists(self, **kwargs) -> list:
|
|
35
|
+
''' Returns a list of lists (list of command lists).'''
|
|
36
|
+
raise NotImplementedError
|
|
37
|
+
|
|
38
|
+
def get_elaborate_command_lists(self, **kwargs) -> list:
|
|
39
|
+
''' Returns a list of lists (list of command lists).'''
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
# CommandSim methods that elab does not use:
|
|
43
|
+
|
|
44
|
+
def simulate(self):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
def get_simulate_command_lists(self, **kwargs) -> list:
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
def get_post_simulate_command_lists(self, **kwargs) -> list:
|
|
51
|
+
return []
|
|
@@ -306,7 +306,9 @@ class DepsFile:
|
|
|
306
306
|
return False
|
|
307
307
|
|
|
308
308
|
if not is_valid_target_name(target_node):
|
|
309
|
-
util.warning(
|
|
309
|
+
util.warning(
|
|
310
|
+
f"In file {self.rel_deps_file}, {target_node} {VALID_TARGET_INFO_STR}"
|
|
311
|
+
)
|
|
310
312
|
|
|
311
313
|
if not caller_info:
|
|
312
314
|
# If we don't have caller_info, likely came from command line (or DEPS JSON data):
|
|
@@ -23,7 +23,7 @@ from opencos import util, eda_config, eda_base
|
|
|
23
23
|
from opencos.eda_base import Tool, which_tool, get_eda_exec
|
|
24
24
|
from opencos.utils import vsim_helper, vscode_helper
|
|
25
25
|
from opencos.utils.subprocess_helpers import subprocess_run_background
|
|
26
|
-
from opencos.utils import status_constants
|
|
26
|
+
from opencos.utils import status_constants, str_helpers
|
|
27
27
|
|
|
28
28
|
# Configure util:
|
|
29
29
|
util.progname = "EDA"
|
|
@@ -78,7 +78,7 @@ def get_all_commands_help_str(config: dict) -> str:
|
|
|
78
78
|
return '\n'.join(all_commands_help)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
def usage(tokens: list, config: dict, command="") -> int:
|
|
81
|
+
def usage(tokens: list, config: dict, command: str = "", tool: str = "") -> int:
|
|
82
82
|
'''Returns an int shell return code, given remaining args (tokens list) and eda command.
|
|
83
83
|
|
|
84
84
|
config is the config dict. Used to check valid commands in config['command_handler']
|
|
@@ -112,6 +112,9 @@ And <files|targets, ...> is one or more source file or DEPS markup file target,
|
|
|
112
112
|
|
|
113
113
|
if command in config['command_handler'].keys():
|
|
114
114
|
sco = config['command_handler'][command](config=config) # sub command object
|
|
115
|
+
sco_tool = getattr(sco, '_TOOL', '')
|
|
116
|
+
if tool and tool != sco_tool:
|
|
117
|
+
util.warning(f'{tool=} does not support {command=}')
|
|
115
118
|
sco.help(tokens=tokens)
|
|
116
119
|
return util.exit(0)
|
|
117
120
|
|
|
@@ -282,9 +285,15 @@ def tool_setup(tool: str, config: dict, quiet: bool = False, auto_setup: bool =
|
|
|
282
285
|
if tool not in config['auto_tools_order'][0]:
|
|
283
286
|
tools = list(config.get('auto_tools_order', [{}])[0].keys())
|
|
284
287
|
cfg_yaml_fname = config.get('config-yml', None)
|
|
288
|
+
util.warning(f'Unknown tool: {tool}')
|
|
289
|
+
if tools:
|
|
290
|
+
util.info('Known tools:')
|
|
291
|
+
pretty_tools = str_helpers.pretty_list_columns_manual(data=tools)
|
|
292
|
+
for row in pretty_tools:
|
|
293
|
+
if row:
|
|
294
|
+
util.info(row)
|
|
285
295
|
util.error(f"Don't know how to run tool_setup({tool=}), is not in",
|
|
286
|
-
f"config['auto_tools_order']
|
|
287
|
-
f"from {cfg_yaml_fname}")
|
|
296
|
+
f"config['auto_tools_order'] from {cfg_yaml_fname}")
|
|
288
297
|
return
|
|
289
298
|
|
|
290
299
|
if tool not in config['auto_tools_found']:
|
|
@@ -394,7 +403,9 @@ def process_tokens( # pylint: disable=too-many-branches,too-many-statements,too-
|
|
|
394
403
|
for arg in unparsed:
|
|
395
404
|
if not arg.startswith('-'):
|
|
396
405
|
command = arg
|
|
397
|
-
|
|
406
|
+
if parsed.tool:
|
|
407
|
+
tool_setup(parsed.tool, config=config)
|
|
408
|
+
return usage(tokens=unparsed, config=config, command=command, tool=parsed.tool)
|
|
398
409
|
|
|
399
410
|
if parsed.tool:
|
|
400
411
|
tool_setup(parsed.tool, config=config)
|
|
@@ -7,6 +7,7 @@ DEFAULT_HANDLERS:
|
|
|
7
7
|
# These commands (sim, elab, etc) require a tool, but have a default handler
|
|
8
8
|
# base class:
|
|
9
9
|
sim : opencos.commands.CommandSim
|
|
10
|
+
lint : opencos.commands.CommandLint
|
|
10
11
|
elab : opencos.commands.CommandElab
|
|
11
12
|
synth : opencos.commands.CommandSynth
|
|
12
13
|
proj : opencos.commands.CommandProj
|
|
@@ -29,7 +30,8 @@ DEFAULT_HANDLERS:
|
|
|
29
30
|
|
|
30
31
|
DEFAULT_HANDLERS_HELP:
|
|
31
32
|
sim: Simulates a DEPS target.
|
|
32
|
-
|
|
33
|
+
lint: Syntax check, lint a DEPS target
|
|
34
|
+
elab: Elaborates a DEPS target (lint + elab, tool specific).
|
|
33
35
|
synth: Synthesizes a DEPS target.
|
|
34
36
|
flist: Create dependency from a DEPS target.
|
|
35
37
|
proj: Create a project from a DEPS target for GUI sim/waves/debug.
|
|
@@ -362,11 +364,13 @@ auto_tools_order:
|
|
|
362
364
|
requires_cmd:
|
|
363
365
|
- slang --version
|
|
364
366
|
handlers:
|
|
367
|
+
lint: opencos.tools.slang.CommandLintSlang
|
|
365
368
|
elab: opencos.tools.slang.CommandElabSlang
|
|
366
369
|
|
|
367
370
|
verilator:
|
|
368
371
|
exe: verilator
|
|
369
372
|
handlers:
|
|
373
|
+
lint: opencos.tools.verilator.VerilatorLint
|
|
370
374
|
elab: opencos.tools.verilator.VerilatorElab
|
|
371
375
|
sim: opencos.tools.verilator.VerilatorSim
|
|
372
376
|
|
|
@@ -382,6 +386,7 @@ auto_tools_order:
|
|
|
382
386
|
requires_cmd:
|
|
383
387
|
- surelog --version
|
|
384
388
|
handlers:
|
|
389
|
+
lint: opencos.tools.surelog.CommandLintSurelog
|
|
385
390
|
elab: opencos.tools.surelog.CommandElabSurelog
|
|
386
391
|
|
|
387
392
|
invio:
|
|
@@ -391,6 +396,7 @@ auto_tools_order:
|
|
|
391
396
|
requires_py:
|
|
392
397
|
- invio
|
|
393
398
|
handlers:
|
|
399
|
+
lint: opencos.tools.invio.CommandLintInvio
|
|
394
400
|
elab: opencos.tools.invio.CommandElabInvio
|
|
395
401
|
|
|
396
402
|
vaporview:
|
|
@@ -422,6 +428,7 @@ auto_tools_order:
|
|
|
422
428
|
vivado:
|
|
423
429
|
exe: vivado
|
|
424
430
|
handlers:
|
|
431
|
+
lint: opencos.tools.vivado.CommandLintVivado
|
|
425
432
|
elab: opencos.tools.vivado.CommandElabVivado
|
|
426
433
|
sim: opencos.tools.vivado.CommandSimVivado
|
|
427
434
|
synth: opencos.tools.vivado.CommandSynthVivado
|
|
@@ -469,6 +476,7 @@ auto_tools_order:
|
|
|
469
476
|
exe: qrun
|
|
470
477
|
requires_vsim_helper: True
|
|
471
478
|
handlers:
|
|
479
|
+
lint: opencos.tools.questa.CommandLintQuesta
|
|
472
480
|
elab: opencos.tools.questa.CommandElabQuesta
|
|
473
481
|
sim: opencos.tools.questa.CommandSimQuesta
|
|
474
482
|
flist: opencos.tools.questa.CommandFListQuesta
|
|
@@ -479,6 +487,7 @@ auto_tools_order:
|
|
|
479
487
|
- which riviera # Do not run it, make sure it's in PATH
|
|
480
488
|
requires_vsim_helper: True
|
|
481
489
|
handlers:
|
|
490
|
+
lint: opencos.tools.riviera.CommandLintRiviera
|
|
482
491
|
elab: opencos.tools.riviera.CommandElabRiviera
|
|
483
492
|
sim: opencos.tools.riviera.CommandSimRiviera
|
|
484
493
|
|
|
@@ -486,6 +495,7 @@ auto_tools_order:
|
|
|
486
495
|
exe: vsim
|
|
487
496
|
requires_vsim_helper: True
|
|
488
497
|
handlers:
|
|
498
|
+
lint: opencos.tools.modelsim_ase.CommandLintModelsimAse
|
|
489
499
|
elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
|
|
490
500
|
sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
|
|
491
501
|
|
|
@@ -493,6 +503,7 @@ auto_tools_order:
|
|
|
493
503
|
exe: vsim
|
|
494
504
|
requires_vsim_helper: True
|
|
495
505
|
handlers:
|
|
506
|
+
lint: opencos.tools.questa_fse.CommandLintQuestaFse
|
|
496
507
|
elab: opencos.tools.questa_fse.CommandElabQuestaFse
|
|
497
508
|
sim: opencos.tools.questa_fse.CommandSimQuestaFse
|
|
498
509
|
flist: opencos.tools.questa_fse.CommandFListQuestaFse
|
|
@@ -500,6 +511,7 @@ auto_tools_order:
|
|
|
500
511
|
iverilog:
|
|
501
512
|
exe: iverilog
|
|
502
513
|
handlers:
|
|
514
|
+
lint: opencos.tools.iverilog.CommandLintIverilog
|
|
503
515
|
elab: opencos.tools.iverilog.CommandElabIverilog
|
|
504
516
|
sim: opencos.tools.iverilog.CommandSimIverilog
|
|
505
517
|
|
|
@@ -65,6 +65,11 @@ def eda_elab_wrap(*args):
|
|
|
65
65
|
main_args = [x for x in list(args) if (x != 'elab' and '--seed' not in x)]
|
|
66
66
|
return eda.main('elab', *main_args)
|
|
67
67
|
|
|
68
|
+
def eda_lint_wrap(*args):
|
|
69
|
+
'''Calls eda.main for 'elab'.'''
|
|
70
|
+
main_args = [x for x in list(args) if (x != 'lint' and '--seed' not in x)]
|
|
71
|
+
return eda.main('lint', *main_args)
|
|
72
|
+
|
|
68
73
|
def assert_sim_log_passes(
|
|
69
74
|
filepath: str, want_str: str = 'TEST PASS',
|
|
70
75
|
err_strs: list = ['Error', 'ERROR', 'TEST FAIL']
|
|
@@ -5,7 +5,7 @@ import pytest
|
|
|
5
5
|
|
|
6
6
|
from opencos import eda_tool_helper
|
|
7
7
|
from opencos.tests import helpers
|
|
8
|
-
from opencos.tests.helpers import eda_wrap, eda_elab_wrap
|
|
8
|
+
from opencos.tests.helpers import eda_wrap, eda_elab_wrap, eda_lint_wrap
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
thispath = os.path.dirname(__file__)
|
|
@@ -29,6 +29,16 @@ list_of_elab_tools = [
|
|
|
29
29
|
'invio_yosys',
|
|
30
30
|
]
|
|
31
31
|
|
|
32
|
+
list_of_lint_tools = [
|
|
33
|
+
'slang',
|
|
34
|
+
'verilator',
|
|
35
|
+
'vivado',
|
|
36
|
+
'modelsim_ase'
|
|
37
|
+
'questa_fse',
|
|
38
|
+
'invio',
|
|
39
|
+
'surelog',
|
|
40
|
+
]
|
|
41
|
+
|
|
32
42
|
list_of_elab_tools_cant_sim = [
|
|
33
43
|
'slang',
|
|
34
44
|
'invio',
|
|
@@ -36,6 +46,11 @@ list_of_elab_tools_cant_sim = [
|
|
|
36
46
|
'invio_yosys',
|
|
37
47
|
]
|
|
38
48
|
|
|
49
|
+
list_of_commands = [
|
|
50
|
+
'elab',
|
|
51
|
+
'lint',
|
|
52
|
+
]
|
|
53
|
+
|
|
39
54
|
def skip_it(tool) -> bool:
|
|
40
55
|
'''Returns True if this test should be skipped
|
|
41
56
|
|
|
@@ -44,27 +59,33 @@ def skip_it(tool) -> bool:
|
|
|
44
59
|
'''
|
|
45
60
|
return bool( tool not in tools_loaded )
|
|
46
61
|
|
|
62
|
+
@pytest.mark.parametrize("command", list_of_commands)
|
|
47
63
|
@pytest.mark.parametrize("tool", list_of_elab_tools)
|
|
48
64
|
class Tests:
|
|
49
65
|
'''Test tools from list_of_elab_tools for 'eda elab' and 'eda multi elab'.'''
|
|
50
66
|
|
|
51
|
-
def test_args_elab(self, tool):
|
|
67
|
+
def test_args_elab(self, command, tool):
|
|
52
68
|
'''tests: eda elab --tool oclib_priarb'''
|
|
69
|
+
if command == 'lint' and tool not in list_of_lint_tools:
|
|
70
|
+
pytest.skip(f"lint skipped for {tool=} b/c it can't run lint")
|
|
53
71
|
if skip_it(tool):
|
|
54
72
|
pytest.skip(f"{tool=} skipped, {tools_loaded=}")
|
|
55
73
|
return # skip/pass
|
|
56
74
|
chdir_remove_work_dir('../../lib')
|
|
57
|
-
|
|
75
|
+
if command == 'elab':
|
|
76
|
+
rc = eda_elab_wrap('--tool', tool, 'oclib_priarb')
|
|
77
|
+
else:
|
|
78
|
+
rc = eda_lint_wrap('--tool', tool, 'oclib_priarb')
|
|
58
79
|
print(f'{rc=}')
|
|
59
80
|
assert rc == 0
|
|
60
81
|
|
|
61
|
-
def test_args_multi_elab(self, tool):
|
|
82
|
+
def test_args_multi_elab(self, command, tool):
|
|
62
83
|
'''tests: eda multi elab --tool oclib_*arb'''
|
|
63
84
|
if skip_it(tool):
|
|
64
85
|
pytest.skip(f"{tool=} skipped, {tools_loaded=}")
|
|
65
86
|
return # skip/pass
|
|
66
87
|
chdir_remove_work_dir('../../lib')
|
|
67
|
-
rc = eda_wrap('multi',
|
|
88
|
+
rc = eda_wrap('multi', command, '--tool', tool, 'oclib_*arb')
|
|
68
89
|
print(f'{rc=}')
|
|
69
90
|
assert rc == 0
|
|
70
91
|
|
|
@@ -38,6 +38,8 @@ class ToolInvio(Tool):
|
|
|
38
38
|
class CommandElabInvio(CommandElab, ToolInvio):
|
|
39
39
|
'''Command handler for: eda elab --tool=invio'''
|
|
40
40
|
|
|
41
|
+
command_name = 'elab'
|
|
42
|
+
|
|
41
43
|
def __init__(self, config:dict):
|
|
42
44
|
CommandElab.__init__(self, config)
|
|
43
45
|
ToolInvio.__init__(self, config=self.config)
|
|
@@ -72,7 +74,7 @@ class CommandElabInvio(CommandElab, ToolInvio):
|
|
|
72
74
|
'''Returns list of util.ShellCommandList, for slang we'll run this in elaborate()'''
|
|
73
75
|
invio_blackbox_list = self.args.get('invio-blackbox', [])
|
|
74
76
|
invio_dict = invio_helpers.get_invio_command_dict(
|
|
75
|
-
self, blackbox_list=invio_blackbox_list,
|
|
77
|
+
self, blackbox_list=invio_blackbox_list,
|
|
76
78
|
)
|
|
77
79
|
return invio_dict['command_lists']
|
|
78
80
|
|
|
@@ -84,3 +86,8 @@ class CommandElabInvio(CommandElab, ToolInvio):
|
|
|
84
86
|
def get_elaborate_command_lists(self, **kwargs) -> list:
|
|
85
87
|
'''We only use 'compile' commands for invio elab, do not use elaborate commands'''
|
|
86
88
|
return []
|
|
89
|
+
|
|
90
|
+
class CommandLintInvio(CommandElabInvio):
|
|
91
|
+
'''Command handler for: eda lint --tool=invio'''
|
|
92
|
+
|
|
93
|
+
command_name = 'lint'
|
|
@@ -34,6 +34,7 @@ def write_py_file(
|
|
|
34
34
|
py_filename: str = 'run_invio.py',
|
|
35
35
|
v_filename: str = '',
|
|
36
36
|
blackbox_list: list = [],
|
|
37
|
+
sim_lint: bool = False,
|
|
37
38
|
sim_elab: bool = False,
|
|
38
39
|
**kwargs
|
|
39
40
|
) -> dict:
|
|
@@ -137,7 +138,15 @@ def write_py_file(
|
|
|
137
138
|
tee_fpath = 'invio.log')]
|
|
138
139
|
})
|
|
139
140
|
|
|
140
|
-
if
|
|
141
|
+
if sim_lint:
|
|
142
|
+
# lint (skip elaborate steps -- from eda.CommandLintInvio)
|
|
143
|
+
lines += [
|
|
144
|
+
'assert analyze()',
|
|
145
|
+
'',
|
|
146
|
+
'report_analyzed_files()',
|
|
147
|
+
'print_instance_hierarchy()',
|
|
148
|
+
]
|
|
149
|
+
elif sim_elab:
|
|
141
150
|
# elab (non-synthesis), runs the following (from eda.CommandElabInvio)
|
|
142
151
|
lines += [
|
|
143
152
|
'assert analyze()',
|
|
@@ -206,14 +215,23 @@ def write_py_file(
|
|
|
206
215
|
|
|
207
216
|
|
|
208
217
|
|
|
209
|
-
def get_invio_command_dict(
|
|
210
|
-
|
|
218
|
+
def get_invio_command_dict(
|
|
219
|
+
command_design_obj:object, v_filename='', py_filename='run_invio.py',
|
|
220
|
+
blackbox_list=[],
|
|
221
|
+
**kwargs
|
|
222
|
+
) -> dict:
|
|
211
223
|
'''Creates a .py file from an eda.CommandDesign. Returns a dict with
|
|
212
224
|
|
|
213
225
|
information about what to run.'''
|
|
214
226
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
227
|
+
cmd_name = getattr(command_design_obj, 'command_name', '')
|
|
228
|
+
sim_lint = cmd_name == 'lint'
|
|
229
|
+
sim_elab = cmd_name == 'elab'
|
|
230
|
+
|
|
231
|
+
invio_dict = write_py_file(
|
|
232
|
+
command_design_obj, v_filename=v_filename,
|
|
233
|
+
py_filename=py_filename, blackbox_list=blackbox_list,
|
|
234
|
+
sim_elab=sim_elab, sim_lint=sim_lint, **kwargs
|
|
235
|
+
)
|
|
218
236
|
|
|
219
237
|
return invio_dict
|
|
@@ -59,7 +59,7 @@ class CommandSynthInvioYosys(CommonSynthYosys, ToolInvioYosys):
|
|
|
59
59
|
|
|
60
60
|
# Generate run_invio.py:
|
|
61
61
|
invio_dict = invio_helpers.get_invio_command_dict(
|
|
62
|
-
self, blackbox_list=invio_blackbox_list,
|
|
62
|
+
self, blackbox_list=invio_blackbox_list,
|
|
63
63
|
)
|
|
64
64
|
# run run_invio.py:
|
|
65
65
|
if not self.args.get('stop-before-compile', False):
|
|
@@ -146,9 +146,10 @@ class CommandSynthInvioYosys(CommonSynthYosys, ToolInvioYosys):
|
|
|
146
146
|
class CommandElabInvioYosys(CommandSynthInvioYosys):
|
|
147
147
|
'''Run invio + yosys as elab only (does not run the synthesis portion)'''
|
|
148
148
|
|
|
149
|
+
command_name = 'elab'
|
|
150
|
+
|
|
149
151
|
def __init__(self, config):
|
|
150
152
|
super().__init__(config)
|
|
151
|
-
self.command_name = 'elab'
|
|
152
153
|
self.args.update({
|
|
153
154
|
'stop-after-compile': True, # In the case of Invio/Yosys we run the Invio step
|
|
154
155
|
'lint': True
|
|
@@ -164,6 +164,19 @@ class CommandSimIverilog(CommandSim, ToolIverilog):
|
|
|
164
164
|
class CommandElabIverilog(CommandSimIverilog):
|
|
165
165
|
'''CommandElabIverilog is a command handler for: eda elab --tool=iverilog'''
|
|
166
166
|
|
|
167
|
+
command_name = 'elab'
|
|
168
|
+
|
|
169
|
+
def __init__(self, config:dict):
|
|
170
|
+
super().__init__(config)
|
|
171
|
+
self.args['stop-after-elaborate'] = True
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class CommandLintIverilog(CommandSimIverilog):
|
|
175
|
+
'''CommandLintIverilog is a command handler for: eda lint --tool=iverilog'''
|
|
176
|
+
|
|
177
|
+
command_name = 'lint'
|
|
178
|
+
|
|
167
179
|
def __init__(self, config:dict):
|
|
168
180
|
super().__init__(config)
|
|
181
|
+
self.args['stop-after-compile'] = True
|
|
169
182
|
self.args['stop-after-elaborate'] = True
|
|
@@ -369,6 +369,19 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
|
|
|
369
369
|
class CommandElabModelsimAse(CommandSimModelsimAse):
|
|
370
370
|
'''CommandElabModelsimAse is a command handler for: eda elab --tool=modelsim_ase'''
|
|
371
371
|
|
|
372
|
+
command_name = 'elab'
|
|
373
|
+
|
|
374
|
+
def __init__(self, config:dict):
|
|
375
|
+
super().__init__(config)
|
|
376
|
+
self.args['stop-after-elaborate'] = True
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
class CommandLintModelsimAse(CommandSimModelsimAse):
|
|
380
|
+
'''CommandLintModelsimAse is a command handler for: eda lint --tool=modelsim_ase'''
|
|
381
|
+
|
|
382
|
+
command_name = 'lint'
|
|
383
|
+
|
|
372
384
|
def __init__(self, config:dict):
|
|
373
385
|
super().__init__(config)
|
|
386
|
+
self.args['stop-after-compile'] = True
|
|
374
387
|
self.args['stop-after-elaborate'] = True
|
|
@@ -150,6 +150,7 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
|
|
|
150
150
|
self.write_tcl_file(tcl_file=tcl_file)
|
|
151
151
|
|
|
152
152
|
# execute Quartus synthesis
|
|
153
|
+
command_list_gui = [self.quartus_gui_exe, '-t', tcl_file]
|
|
153
154
|
command_list = [
|
|
154
155
|
self.quartus_exe, '-t', tcl_file
|
|
155
156
|
]
|
|
@@ -170,9 +171,27 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
|
|
|
170
171
|
typ='text', description='Quartus Synthesis Report'
|
|
171
172
|
)
|
|
172
173
|
|
|
173
|
-
self.
|
|
174
|
+
if self.args['gui'] and self.quartus_gui_exe:
|
|
175
|
+
self.exec(self.args['work-dir'], command_list_gui)
|
|
176
|
+
else:
|
|
177
|
+
self.exec(self.args['work-dir'], command_list)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
saved_qpf_filename = self.args["top"] + '.qpf'
|
|
181
|
+
if not os.path.isfile(os.path.join(self.args['work-dir'], saved_qpf_filename)):
|
|
182
|
+
self.error('Saved project file does not exist:',
|
|
183
|
+
os.path.join(self.args['work-dir'], saved_qpf_filename))
|
|
184
|
+
|
|
174
185
|
util.info(f"Synthesis done, results are in: {self.args['work-dir']}")
|
|
175
186
|
|
|
187
|
+
# Note: in GUI mode, if you ran: quaruts -t build.tcl, it will exit on completion,
|
|
188
|
+
# so we'll re-open the project.
|
|
189
|
+
if self.args['gui'] and self.quartus_gui_exe:
|
|
190
|
+
self.exec(
|
|
191
|
+
work_dir=self.args['work-dir'],
|
|
192
|
+
command_list=[self.quartus_gui_exe, saved_qpf_filename]
|
|
193
|
+
)
|
|
194
|
+
|
|
176
195
|
def write_tcl_file(self, tcl_file: str) -> None: # pylint: disable=too-many-locals,too-many-branches
|
|
177
196
|
'''Writes synthesis capable Quartus tcl file to filepath 'tcl_file'.'''
|
|
178
197
|
|
|
@@ -221,11 +240,27 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
|
|
|
221
240
|
tcl_lines.append(f"set_global_assignment -name VERILOG_MACRO \"{key}={value}\"")
|
|
222
241
|
|
|
223
242
|
# Add constraints
|
|
243
|
+
default_sdc = False
|
|
244
|
+
sdc_files = []
|
|
224
245
|
if self.args['sdc']:
|
|
225
|
-
|
|
246
|
+
sdc_files = [os.path.abspath(self.args['sdc'])]
|
|
226
247
|
elif self.files_sdc:
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
# Use files from DEPS target or command line.
|
|
249
|
+
sdc_files = self.files_sdc
|
|
250
|
+
else:
|
|
251
|
+
default_sdc = True
|
|
252
|
+
sdc_file = self.args['top'] + '.sdc'
|
|
253
|
+
sdc_files = [sdc_file]
|
|
254
|
+
|
|
255
|
+
for f in sdc_files:
|
|
256
|
+
for attr in ('SDC_FILE', 'SYN_SDC_FILE', 'RTL_SDC_FILE'):
|
|
257
|
+
tcl_lines.extend([
|
|
258
|
+
f"set_global_assignment -name {attr} \"{f}\""
|
|
259
|
+
])
|
|
260
|
+
tcl_lines.append("set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON")
|
|
261
|
+
|
|
262
|
+
if default_sdc:
|
|
263
|
+
self.write_default_sdc(sdc_file=os.path.join(self.args['work-dir'], sdc_file))
|
|
229
264
|
|
|
230
265
|
tcl_lines += [
|
|
231
266
|
"# Run synthesis",
|
|
@@ -237,6 +272,25 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
|
|
|
237
272
|
ftcl.write('\n'.join(tcl_lines))
|
|
238
273
|
|
|
239
274
|
|
|
275
|
+
def write_default_sdc(self, sdc_file: str) -> None:
|
|
276
|
+
'''Writes a default SDC file to filepath 'sdc_file'.'''
|
|
277
|
+
|
|
278
|
+
sdc_lines = []
|
|
279
|
+
util.info("Creating default constraints: clock:",
|
|
280
|
+
f"{self.args['clock-name']}, {self.args['clock-ns']} (ns),")
|
|
281
|
+
|
|
282
|
+
clock_name = self.args['clock-name']
|
|
283
|
+
period = self.args['clock-ns']
|
|
284
|
+
|
|
285
|
+
sdc_lines += [
|
|
286
|
+
("create_clock -name {" + clock_name + "} -period {" + str(period) + "} [get_ports "
|
|
287
|
+
"{" + clock_name + "}]")
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
with open( sdc_file, 'w', encoding='utf-8' ) as fsdc:
|
|
291
|
+
fsdc.write('\n'.join(sdc_lines))
|
|
292
|
+
|
|
293
|
+
|
|
240
294
|
class CommandBuildQuartus(CommandBuild, ToolQuartus):
|
|
241
295
|
'''CommandBuildQuartus is a command handler for: eda build --tool=quartus'''
|
|
242
296
|
|
|
@@ -371,7 +425,8 @@ class CommandBuildQuartus(CommandBuild, ToolQuartus):
|
|
|
371
425
|
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='run_quartus_gui.sh',
|
|
372
426
|
command_lists=[
|
|
373
427
|
command_list_gui,
|
|
374
|
-
|
|
428
|
+
# reopen when done.
|
|
429
|
+
[self.quartus_gui_exe, saved_qpf_filename],
|
|
375
430
|
], line_breaks=True)
|
|
376
431
|
|
|
377
432
|
# Add artifact tracking for build
|
|
@@ -422,7 +477,7 @@ class CommandBuildQuartus(CommandBuild, ToolQuartus):
|
|
|
422
477
|
if self.args['gui'] and self.quartus_gui_exe:
|
|
423
478
|
self.exec(
|
|
424
479
|
work_dir=self.args['work-dir'],
|
|
425
|
-
command_list=[
|
|
480
|
+
command_list=[self.quartus_gui_exe, saved_qpf_filename]
|
|
426
481
|
)
|
|
427
482
|
|
|
428
483
|
|
|
@@ -267,7 +267,21 @@ class CommandFListQuesta(CommandFList, ToolQuesta):
|
|
|
267
267
|
class CommandElabQuesta(CommandSimQuesta):
|
|
268
268
|
'''Command handler for: eda elab --tool=questa'''
|
|
269
269
|
|
|
270
|
+
command_name = 'elab'
|
|
271
|
+
|
|
272
|
+
def __init__(self, config:dict):
|
|
273
|
+
CommandSimQuesta.__init__(self, config)
|
|
274
|
+
# add args specific to this simulator
|
|
275
|
+
self.args['stop-after-elaborate'] = True
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class CommandLintQuesta(CommandSimQuesta):
|
|
279
|
+
'''Command handler for: eda lint --tool=questa'''
|
|
280
|
+
|
|
281
|
+
command_name = 'lint'
|
|
282
|
+
|
|
270
283
|
def __init__(self, config:dict):
|
|
271
284
|
CommandSimQuesta.__init__(self, config)
|
|
272
285
|
# add args specific to this simulator
|
|
286
|
+
self.args['stop-after-compile'] = True
|
|
273
287
|
self.args['stop-after-elaborate'] = True
|
|
@@ -56,8 +56,21 @@ class CommandSimQuestaFse(CommandSimModelsimAse):
|
|
|
56
56
|
class CommandElabQuestaFse(CommandSimQuestaFse):
|
|
57
57
|
'''CommandElabQuestaFse is a command handler for: eda elab --tool=questa_fse'''
|
|
58
58
|
|
|
59
|
+
command_name = 'elab'
|
|
60
|
+
|
|
61
|
+
def __init__(self, config:dict):
|
|
62
|
+
super().__init__(config)
|
|
63
|
+
self.args['stop-after-elaborate'] = True
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class CommandLintQuestaFse(CommandSimQuestaFse):
|
|
67
|
+
'''CommandLintQuestaFse is a command handler for: eda lint --tool=questa_fse'''
|
|
68
|
+
|
|
69
|
+
command_name = 'lint'
|
|
70
|
+
|
|
59
71
|
def __init__(self, config:dict):
|
|
60
72
|
super().__init__(config)
|
|
73
|
+
self.args['stop-after-compile'] = True
|
|
61
74
|
self.args['stop-after-elaborate'] = True
|
|
62
75
|
|
|
63
76
|
|
|
@@ -289,6 +289,19 @@ class CommandSimRiviera(CommandSimModelsimAse, ToolRiviera):
|
|
|
289
289
|
class CommandElabRiviera(CommandSimRiviera):
|
|
290
290
|
'''CommandElabRiviera is a command handler for: eda elab --tool=riviera'''
|
|
291
291
|
|
|
292
|
+
command_name = 'elab'
|
|
293
|
+
|
|
294
|
+
def __init__(self, config:dict):
|
|
295
|
+
super().__init__(config)
|
|
296
|
+
self.args['stop-after-elaborate'] = True
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class CommandLintRiviera(CommandSimRiviera):
|
|
300
|
+
'''CommandLintRiviera is a command handler for: eda lint --tool=riviera'''
|
|
301
|
+
|
|
302
|
+
command_name = 'lint'
|
|
303
|
+
|
|
292
304
|
def __init__(self, config:dict):
|
|
293
305
|
super().__init__(config)
|
|
306
|
+
self.args['stop-after-compile'] = True
|
|
294
307
|
self.args['stop-after-elaborate'] = True
|
|
@@ -115,7 +115,7 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
115
115
|
pass
|
|
116
116
|
|
|
117
117
|
def elaborate(self):
|
|
118
|
-
''' elaborate() - following parent
|
|
118
|
+
''' elaborate() - following parent CommandSim's run() flow, runs slang_command_lists'''
|
|
119
119
|
if self.args['stop-before-compile'] or \
|
|
120
120
|
self.args['stop-after-compile']:
|
|
121
121
|
return
|
|
@@ -208,3 +208,14 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
208
208
|
)
|
|
209
209
|
|
|
210
210
|
return command_list
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class CommandLintSlang(CommandElabSlang):
|
|
214
|
+
'''CommandLintSlang is a command handler for: eda lint --tool=slang.'''
|
|
215
|
+
|
|
216
|
+
command_name = 'lint'
|
|
217
|
+
|
|
218
|
+
def __init__(self, config: dict):
|
|
219
|
+
super().__init__(config)
|
|
220
|
+
# keep stop-after-compile=False, allow's CommandElabSlang.elaborate() to run.
|
|
221
|
+
self.args['slang-args'] = ['--lint-only', '--ignore-unknown-modules']
|
|
@@ -63,6 +63,7 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
|
|
|
63
63
|
ToolSurelog.__init__(self, config=self.config)
|
|
64
64
|
self.args.update({
|
|
65
65
|
'surelog-top': '',
|
|
66
|
+
'surelog-args': [],
|
|
66
67
|
})
|
|
67
68
|
|
|
68
69
|
self.surelog_command_lists = []
|
|
@@ -98,6 +99,7 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
|
|
|
98
99
|
'compile-args',
|
|
99
100
|
'-parse').split()
|
|
100
101
|
command_list += config_compile_args
|
|
102
|
+
command_list += self.args['surelog-args']
|
|
101
103
|
|
|
102
104
|
if util.args.get('debug', None) or \
|
|
103
105
|
util.args.get('verbose', None):
|
|
@@ -139,3 +141,14 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
|
|
|
139
141
|
dirpath=self.args['work-dir'], filename='run_surelog.sh',
|
|
140
142
|
command_lists=self.surelog_command_lists, line_breaks=True
|
|
141
143
|
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class CommandLintSurelog(CommandElabSurelog):
|
|
147
|
+
'''CommandLintSurelog is a command handler for: eda lint --tool=surelog.'''
|
|
148
|
+
command_name = 'lint'
|
|
149
|
+
|
|
150
|
+
def __init__(self, config: dict):
|
|
151
|
+
super().__init__(config)
|
|
152
|
+
# keep stop-after-compile=False, allow's CommandElabSurelog.elaborate() to run.
|
|
153
|
+
# run the "compile" step only for surelog by setting -noelab:
|
|
154
|
+
self.args['surelog-args'] = ['-noelab']
|
|
@@ -499,8 +499,22 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
499
499
|
|
|
500
500
|
class VerilatorElab(VerilatorSim):
|
|
501
501
|
'''VerilatorElab is a command handler for: eda elab --tool=verilator'''
|
|
502
|
+
command_name = 'elab'
|
|
502
503
|
|
|
503
504
|
def __init__(self, config: dict):
|
|
504
505
|
super().__init__(config)
|
|
505
506
|
self.args['stop-after-elaborate'] = True
|
|
506
507
|
self.args['lint-only'] = True
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
class VerilatorLint(VerilatorSim):
|
|
511
|
+
'''VerilatorLint is a command handler for: eda lint --tool=verilator.
|
|
512
|
+
|
|
513
|
+
For practical reasons, this is identical to VerilatorElab with --stop-after-compile.'''
|
|
514
|
+
command_name = 'lint'
|
|
515
|
+
|
|
516
|
+
def __init__(self, config: dict):
|
|
517
|
+
super().__init__(config)
|
|
518
|
+
self.args['stop-after-compile'] = True
|
|
519
|
+
self.args['stop-after-elaborate'] = True
|
|
520
|
+
self.args['lint-only'] = True
|
|
@@ -347,12 +347,23 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
347
347
|
|
|
348
348
|
class CommandElabVivado(CommandSimVivado):
|
|
349
349
|
'''CommandElabVivado is a command handler for: eda elab --tool=vivado, uses xvlog, xelab'''
|
|
350
|
+
command_name = 'elab'
|
|
350
351
|
def __init__(self, config: dict):
|
|
351
352
|
CommandSimVivado.__init__(self, config)
|
|
352
353
|
# add args specific to this tool
|
|
353
354
|
self.args['stop-after-elaborate'] = True
|
|
354
355
|
|
|
355
356
|
|
|
357
|
+
class CommandLintVivado(CommandSimVivado):
|
|
358
|
+
'''CommandLintVivado is a command handler for: eda lint --tool=vivado, uses xvlog'''
|
|
359
|
+
command_name = 'lint'
|
|
360
|
+
def __init__(self, config: dict):
|
|
361
|
+
CommandSimVivado.__init__(self, config)
|
|
362
|
+
# add args specific to this tool
|
|
363
|
+
self.args['stop-after-compile'] = True
|
|
364
|
+
self.args['stop-after-elaborate'] = True
|
|
365
|
+
|
|
366
|
+
|
|
356
367
|
class CommandSynthVivado(CommandSynth, ToolVivado):
|
|
357
368
|
'''CommandSynthVivado is a command handler for: eda synth --tool=vivado'''
|
|
358
369
|
def __init__(self, config: dict):
|
|
@@ -219,6 +219,9 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
219
219
|
if not self.args['sta-scriptfile']:
|
|
220
220
|
return []
|
|
221
221
|
|
|
222
|
+
# Add URL info for OpenSTA source code:
|
|
223
|
+
self._add_opensta_info()
|
|
224
|
+
|
|
222
225
|
ret_list = []
|
|
223
226
|
for i,fpath in enumerate(self.args['sta-scriptfile']):
|
|
224
227
|
if not os.path.isfile(fpath):
|
|
@@ -377,6 +380,9 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
377
380
|
if not self.sta_exe:
|
|
378
381
|
self.error(f'--sta is set, but "sta" was not found in PATH, see: {self._URL}')
|
|
379
382
|
|
|
383
|
+
# Add URL info for OpenSTA source code:
|
|
384
|
+
self._add_opensta_info()
|
|
385
|
+
|
|
380
386
|
sta_command_list = util.ShellCommandList(
|
|
381
387
|
[ self.sta_exe, '-no_init', '-exit', 'sta.f' ],
|
|
382
388
|
tee_fpath = 'sta.log'
|
|
@@ -439,6 +445,15 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
439
445
|
]
|
|
440
446
|
f.write('\n'.join(lines))
|
|
441
447
|
|
|
448
|
+
def _add_opensta_info(self) -> None:
|
|
449
|
+
'''Adds OpenSTA URL information to artifacts and logs'''
|
|
450
|
+
|
|
451
|
+
opensta_repo_url = 'https://github.com/The-OpenROAD-Project/OpenSTA'
|
|
452
|
+
|
|
453
|
+
# Log GPL3.0 license information
|
|
454
|
+
util.info(f'Using OpenSTA (see URL for license and source): {opensta_repo_url}')
|
|
455
|
+
if hasattr(self, 'sta_version') and self.sta_version:
|
|
456
|
+
util.info(f'OpenSTA version: {self.sta_version}')
|
|
442
457
|
|
|
443
458
|
def _get_read_verilog_one_liner(self) -> str:
|
|
444
459
|
'''Returns a string, intended to be used w/out Slang, for Verilog or simple
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'''opencos.util -- support global logging, argparser for printing (colors)'''
|
|
2
2
|
|
|
3
|
+
# pylint: disable=too-many-lines
|
|
4
|
+
|
|
3
5
|
import argparse
|
|
4
6
|
import atexit
|
|
5
7
|
import datetime
|
|
@@ -89,6 +91,7 @@ class ArtifactTypes(Enum):
|
|
|
89
91
|
TCL = 5
|
|
90
92
|
SHELL = 6
|
|
91
93
|
BITSTREAM = 7
|
|
94
|
+
LICENSE = 8
|
|
92
95
|
|
|
93
96
|
class Artifacts:
|
|
94
97
|
'''Class to hold file artifacts, for logs generated by EDA, or other artifcats created
|
|
@@ -198,7 +201,10 @@ class Artifacts:
|
|
|
198
201
|
# Update all file sizes:
|
|
199
202
|
remove_keys = set()
|
|
200
203
|
for key, entry in self.data.items():
|
|
201
|
-
if
|
|
204
|
+
if entry['type'] == 'license':
|
|
205
|
+
# License entries are metadata, not files - keep them as-is
|
|
206
|
+
entry['size'] = 0
|
|
207
|
+
elif os.path.isfile(entry['name']):
|
|
202
208
|
entry['size'] = os.path.getsize(entry['name'])
|
|
203
209
|
else:
|
|
204
210
|
# file doesn't exist, remove it from artifacts.
|
|
@@ -7,14 +7,18 @@ import shlex
|
|
|
7
7
|
import textwrap
|
|
8
8
|
|
|
9
9
|
VALID_TARGET_INFO_STR = (
|
|
10
|
-
"should start with
|
|
10
|
+
"should start with a . or underscore/letter, rest should be"
|
|
11
|
+
" ., alpha-numeric, dashes, or underscores."
|
|
11
12
|
)
|
|
12
13
|
|
|
13
14
|
def is_valid_target_name(s: str) -> bool:
|
|
14
|
-
'''Returns True if str starts with underscore/letter, rest
|
|
15
|
-
|
|
15
|
+
'''Returns True if str starts with . or underscore/letter, rest alphanum, dash, dot,
|
|
16
|
+
|
|
17
|
+
or underscores. We allow '.' otherwise deps_file.py posts warnings about badly named
|
|
18
|
+
targets for files that are missing.'''
|
|
19
|
+
if not s or not (s[0].isalpha() or s[0] == '_' or s[0] == '.'):
|
|
16
20
|
return False
|
|
17
|
-
return s.replace('_', '').replace('-', '').isalnum()
|
|
21
|
+
return s.replace('_', '').replace('-', '').replace('.', '').isalnum()
|
|
18
22
|
|
|
19
23
|
def strip_all_quotes(s: str) -> str:
|
|
20
24
|
'''Returns str with all ' and " removed'''
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.55
|
|
4
4
|
Summary: A simple Python package for wrapping RTL simuliatons and synthesis
|
|
5
5
|
Author-email: Simon Sabato <simon@cognichip.ai>, Drew Ranck <drew@cognichip.ai>
|
|
6
6
|
Project-URL: Homepage, https://github.com/cognichip/opencos
|
|
@@ -15,5 +15,5 @@ Requires-Dist: schema>=0.7.7
|
|
|
15
15
|
Requires-Dist: toml>=0.10.2
|
|
16
16
|
Requires-Dist: yamllint>=1.35.1
|
|
17
17
|
Requires-Dist: PySerial>=3.5
|
|
18
|
-
Requires-Dist: cocotb>=2.0
|
|
18
|
+
Requires-Dist: cocotb>=2.0
|
|
19
19
|
Dynamic: license-file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[project]
|
|
4
4
|
name = "opencos-eda"
|
|
5
|
-
version = "0.2.
|
|
5
|
+
version = "0.2.55"
|
|
6
6
|
dependencies = [
|
|
7
7
|
# opencos/eda.py dependencies
|
|
8
8
|
"mergedeep >= 1.3.4",
|
|
@@ -14,7 +14,7 @@ dependencies = [
|
|
|
14
14
|
"yamllint >= 1.35.1",
|
|
15
15
|
# opencos/oc_cli.py dependencies
|
|
16
16
|
"PySerial >= 3.5",
|
|
17
|
-
"cocotb >= 2.0
|
|
17
|
+
"cocotb >= 2.0",
|
|
18
18
|
]
|
|
19
19
|
requires-python = ">= 3.8"
|
|
20
20
|
authors = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|