opencos-eda 0.2.53__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.53/opencos_eda.egg-info → opencos_eda-0.2.55}/PKG-INFO +2 -2
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/__init__.py +2 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/flist.py +1 -1
- opencos_eda-0.2.55/opencos/commands/lint.py +51 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/sim.py +44 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps/deps_file.py +3 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda.py +16 -5
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_base.py +19 -14
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_config_defaults.yml +13 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/helpers.py +5 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_eda.py +1 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_eda_elab.py +26 -5
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/cocotb.py +7 -15
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/invio.py +8 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/invio_helpers.py +24 -6
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/invio_yosys.py +3 -2
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/iverilog.py +17 -24
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/modelsim_ase.py +16 -6
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/quartus.py +183 -86
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/questa.py +19 -16
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/questa_fse.py +13 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/riviera.py +13 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/slang.py +12 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/surelog.py +13 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/verilator.py +22 -14
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/vivado.py +38 -20
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/yosys.py +15 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/util.py +77 -14
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/status_constants.py +1 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/str_helpers.py +8 -4
- {opencos_eda-0.2.53 → opencos_eda-0.2.55/opencos_eda.egg-info}/PKG-INFO +2 -2
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos_eda.egg-info/SOURCES.txt +1 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos_eda.egg-info/requires.txt +1 -1
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/pyproject.toml +2 -2
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/LICENSE +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/LICENSE.spdx +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/README.md +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/_version.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/build.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/deps_help.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/export.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/lec.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/multi.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/open.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/proj.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/shell.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/sweep.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/synth.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/upload.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/commands/waves.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps/defaults.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps/deps_commands.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps/deps_processor.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/deps_schema.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_config.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_deps_sanitize.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_extract_targets.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/eda_tool_helper.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/export_helper.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/export_json_convert.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/files.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/hw/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/hw/oc_cli.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/hw/pcie.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/names.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/peakrdl_cleanup.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/seed.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_deps_helpers.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_eda_synth.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_oc_cli.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tests/test_tools.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/__init__.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/markup_helpers.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/subprocess_helpers.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/vscode_helper.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos/utils/vsim_helper.py +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos_eda.egg-info/entry_points.txt +0 -0
- {opencos_eda-0.2.53 → opencos_eda-0.2.55}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.2.53 → 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 []
|
|
@@ -355,6 +355,50 @@ class CommandSim(CommandDesign):
|
|
|
355
355
|
error_code=status_constants.EDA_SIM_LOG_MISSING_MUST_STRING
|
|
356
356
|
)
|
|
357
357
|
|
|
358
|
+
def write_sh_scripts_to_work_dir(
|
|
359
|
+
self, compile_lists: list, elaborate_lists: list, simulate_lists: list,
|
|
360
|
+
compile_line_breaks: bool = True,
|
|
361
|
+
elaborate_line_breaks: bool = False,
|
|
362
|
+
simulate_line_breaks: bool = False,
|
|
363
|
+
simulate_sh_fname: str = 'simulate.sh'
|
|
364
|
+
) -> None:
|
|
365
|
+
'''Writes compile.sh, elaborate.sh, simulate.sh (if present), all.sh to work-dir
|
|
366
|
+
|
|
367
|
+
Will include the pre_compile_dep_shell_commands.sh if those are present.
|
|
368
|
+
compile_line_breaks defaults to True (one word per line w/ line breaks added)
|
|
369
|
+
'''
|
|
370
|
+
|
|
371
|
+
all_lists = [] # list - of - (command-list)
|
|
372
|
+
if self.has_dep_shell_commands:
|
|
373
|
+
all_lists = [
|
|
374
|
+
['./pre_compile_dep_shell_commands.sh']
|
|
375
|
+
]
|
|
376
|
+
|
|
377
|
+
if compile_lists:
|
|
378
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='compile.sh',
|
|
379
|
+
command_lists=compile_lists,
|
|
380
|
+
line_breaks=compile_line_breaks)
|
|
381
|
+
all_lists.append(['./compile.sh'])
|
|
382
|
+
|
|
383
|
+
if elaborate_lists:
|
|
384
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='elaborate.sh',
|
|
385
|
+
command_lists=elaborate_lists,
|
|
386
|
+
line_breaks=elaborate_line_breaks)
|
|
387
|
+
all_lists.append(['./elaborate.sh'])
|
|
388
|
+
|
|
389
|
+
if simulate_lists:
|
|
390
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename=simulate_sh_fname,
|
|
391
|
+
command_lists=simulate_lists,
|
|
392
|
+
line_breaks=simulate_line_breaks)
|
|
393
|
+
all_lists.append(['./' + simulate_sh_fname])
|
|
394
|
+
|
|
395
|
+
util.write_shell_command_file(dirpath=self.args['work-dir'], filename='all.sh',
|
|
396
|
+
command_lists=all_lists)
|
|
397
|
+
|
|
398
|
+
self.write_eda_config_and_args()
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
358
402
|
# Methods that derived classes must override:
|
|
359
403
|
|
|
360
404
|
def compile(self) -> None:
|
|
@@ -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)
|
|
@@ -252,7 +252,7 @@ class Command: # pylint: disable=too-many-public-methods
|
|
|
252
252
|
})
|
|
253
253
|
self.modified_args = {}
|
|
254
254
|
self.config = copy.deepcopy(config) # avoid external modifications.
|
|
255
|
-
self.target = ""
|
|
255
|
+
self.target = "" # is set as the 'top' or final target short-name (no path info)
|
|
256
256
|
self.target_path = ""
|
|
257
257
|
self.status = 0
|
|
258
258
|
self.errors_log_f = None
|
|
@@ -943,6 +943,8 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
943
943
|
self.targets_dict = {} # key = targets that we've already processed in DEPS files
|
|
944
944
|
self.last_added_source_file_inferred_top = ''
|
|
945
945
|
|
|
946
|
+
self.has_dep_shell_commands = False
|
|
947
|
+
|
|
946
948
|
|
|
947
949
|
def run_dep_commands(self) -> None:
|
|
948
950
|
'''Run shell/peakrdl style commands from DEPS files
|
|
@@ -993,10 +995,12 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
993
995
|
|
|
994
996
|
d['exec_list'] = clist # update to tee_fpath is set.
|
|
995
997
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
998
|
+
if all_cmds_lists:
|
|
999
|
+
util.write_shell_command_file(
|
|
1000
|
+
dirpath=self.args['work-dir'], filename='pre_compile_dep_shell_commands.sh',
|
|
1001
|
+
command_lists=all_cmds_lists
|
|
1002
|
+
)
|
|
1003
|
+
self.has_dep_shell_commands = True
|
|
1000
1004
|
|
|
1001
1005
|
for i, d in enumerate(self.dep_shell_commands):
|
|
1002
1006
|
util.info(f'run_dep_shell_commands {i=}: {d=}')
|
|
@@ -1556,11 +1560,12 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1556
1560
|
|
|
1557
1561
|
# handle a missing self.args['top'] with last filepath or last target:
|
|
1558
1562
|
if not self.args.get('top', ''):
|
|
1563
|
+
top_path = ''
|
|
1559
1564
|
if not last_potential_top_isfile and last_potential_top_target[0]:
|
|
1560
1565
|
# If we have a target name from DEPS, prefer to use that.
|
|
1561
|
-
self.args['top'],
|
|
1566
|
+
self.args['top'], top_path = last_potential_top_target
|
|
1562
1567
|
util.info("--top not specified, inferred from target:",
|
|
1563
|
-
f"{self.args['top']} ({
|
|
1568
|
+
f"{self.args['top']} ({top_path})")
|
|
1564
1569
|
|
|
1565
1570
|
else:
|
|
1566
1571
|
best_top_fname = self.last_added_source_file_inferred_top
|
|
@@ -1570,26 +1575,29 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1570
1575
|
if not self.args['top'] and last_potential_top_file[0]:
|
|
1571
1576
|
# If we don't have a target name, and no top name yet, then go looking for the
|
|
1572
1577
|
# module name in the final source file added.
|
|
1573
|
-
|
|
1578
|
+
top_path = last_potential_top_file[1] # from tuple: (top, fpath)
|
|
1574
1579
|
self.args['top'] = util.get_inferred_top_module_name(
|
|
1575
1580
|
module_guess=last_potential_top_file[0],
|
|
1576
1581
|
module_fpath=last_potential_top_file[1]
|
|
1577
1582
|
)
|
|
1578
1583
|
if self.args['top']:
|
|
1579
1584
|
util.info("--top not specified, inferred from final source file:",
|
|
1580
|
-
f"{self.args['top']} ({
|
|
1585
|
+
f"{self.args['top']} ({top_path})")
|
|
1581
1586
|
# If top wasn't set, and we're using the final command-line 'arg' filename
|
|
1582
1587
|
# (not from DEPS.yml) we need to override self.target if that was set. Otherwise
|
|
1583
1588
|
# it won't save to the correct work-dir:
|
|
1584
1589
|
self.target = self.args['top']
|
|
1585
1590
|
|
|
1591
|
+
|
|
1592
|
+
util.info(f'{self.command_name}: top-most target name: {self.target}')
|
|
1593
|
+
|
|
1586
1594
|
if self.error_on_missing_top and not self.args.get('top', ''):
|
|
1587
1595
|
self.error("Did not get a --top or DEPS top, required to run command",
|
|
1588
1596
|
f"'{self.command_name}' for tool={self.args.get('tool', None)}",
|
|
1589
1597
|
error_code=status_constants.EDA_COMMAND_MISSING_TOP)
|
|
1590
1598
|
|
|
1591
1599
|
if self.tool_changed_respawn:
|
|
1592
|
-
util.
|
|
1600
|
+
util.info(
|
|
1593
1601
|
'CommandDesign: need to respawn due to tool change to',
|
|
1594
1602
|
f'\'{self.tool_changed_respawn["tool"]}\' from',
|
|
1595
1603
|
f'\'{self.tool_changed_respawn["orig_tool"]}\'',
|
|
@@ -1615,7 +1623,7 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1615
1623
|
for k,v in self.args.items():
|
|
1616
1624
|
|
|
1617
1625
|
# Some args cannot be extracted and work, so omit these:
|
|
1618
|
-
if k in
|
|
1626
|
+
if k in remove_args:
|
|
1619
1627
|
continue
|
|
1620
1628
|
if any(k.startswith(x) for x in remove_args_startswith):
|
|
1621
1629
|
continue
|
|
@@ -1637,9 +1645,6 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1637
1645
|
return ret
|
|
1638
1646
|
|
|
1639
1647
|
|
|
1640
|
-
#_THREADS_START = 0
|
|
1641
|
-
#_THREADS_DONE = 0
|
|
1642
|
-
|
|
1643
1648
|
class ThreadStats:
|
|
1644
1649
|
'''To avoid globals for two ints, keep a class holder so CommandParallel and
|
|
1645
1650
|
CommandParallelWorker can share values'''
|
|
@@ -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']
|
|
@@ -170,7 +170,7 @@ class TestsRequiresVerilator( # pylint: disable=too-many-public-methods
|
|
|
170
170
|
assert res.stderr == b''
|
|
171
171
|
|
|
172
172
|
res = subprocess.run(
|
|
173
|
-
[ './
|
|
173
|
+
[ './simulate.sh' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
174
174
|
check=True
|
|
175
175
|
)
|
|
176
176
|
rc = res.returncode
|
|
@@ -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
|
|
|
@@ -122,20 +122,12 @@ class CommandSimCocotb(CommandSim, ToolCocotb):
|
|
|
122
122
|
util.safe_mkdirs(base=self.args['work-dir'], new_dirs=paths)
|
|
123
123
|
|
|
124
124
|
# Write shell scripts
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
util.write_shell_command_file(
|
|
133
|
-
dirpath=self.args['work-dir'],
|
|
134
|
-
filename='all.sh',
|
|
135
|
-
command_lists=[
|
|
136
|
-
['./pre_compile_dep_shell_commands.sh'],
|
|
137
|
-
['./cocotb_test.sh'],
|
|
138
|
-
]
|
|
125
|
+
self.write_sh_scripts_to_work_dir(
|
|
126
|
+
compile_lists=[],
|
|
127
|
+
elaborate_lists=[],
|
|
128
|
+
simulate_lists=self.cocotb_command_lists,
|
|
129
|
+
simulate_line_breaks=True,
|
|
130
|
+
simulate_sh_fname='cocotb_test.sh'
|
|
139
131
|
)
|
|
140
132
|
|
|
141
133
|
def _find_cocotb_test_files(self):
|
|
@@ -317,7 +309,7 @@ def run_cocotb_test():
|
|
|
317
309
|
runner = get_runner(simulator)
|
|
318
310
|
|
|
319
311
|
build_args = []
|
|
320
|
-
|
|
312
|
+
|
|
321
313
|
if simulator == "verilator":
|
|
322
314
|
build_args.extend({list(self.args.get('verilate-args', []))!r})
|
|
323
315
|
|
|
@@ -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
|