opencos-eda 0.3.1__tar.gz → 0.3.3__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.3.1/opencos_eda.egg-info → opencos_eda-0.3.3}/PKG-INFO +2 -1
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps/deps_file.py +42 -21
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_base.py +37 -17
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_config_defaults.yml +2 -1
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/helpers.py +36 -7
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_eda.py +3 -13
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_tools.py +6 -8
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/slang.py +6 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/verilator.py +48 -39
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/util.py +8 -6
- {opencos_eda-0.3.1 → opencos_eda-0.3.3/opencos_eda.egg-info}/PKG-INFO +2 -1
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos_eda.egg-info/requires.txt +1 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/pyproject.toml +2 -1
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/LICENSE +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/LICENSE.spdx +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/README.md +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/_version.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/build.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/deps_help.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/export.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/flist.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/lec.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/lint.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/multi.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/open.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/proj.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/shell.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/sim.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/sweep.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/synth.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/upload.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/commands/waves.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps/defaults.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps/deps_commands.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps/deps_processor.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/deps_schema.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_config.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_deps_sanitize.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_extract_targets.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/eda_tool_helper.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/export_helper.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/export_json_convert.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/files.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/hw/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/hw/oc_cli.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/hw/pcie.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/names.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/peakrdl_cleanup.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/seed.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_deps_helpers.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_eda_elab.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_eda_synth.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tests/test_oc_cli.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/cocotb.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/invio.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/invio_helpers.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/invio_yosys.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/iverilog.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/modelsim_ase.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/quartus.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/questa.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/questa_fse.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/riviera.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/surelog.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/vivado.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/tools/yosys.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/__init__.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/markup_helpers.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/status_constants.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/str_helpers.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/subprocess_helpers.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/vscode_helper.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos/utils/vsim_helper.py +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos_eda.egg-info/SOURCES.txt +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos_eda.egg-info/entry_points.txt +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.3.1 → opencos_eda-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
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
|
|
@@ -17,4 +17,5 @@ Requires-Dist: toml>=0.10.2
|
|
|
17
17
|
Requires-Dist: yamllint>=1.35.1
|
|
18
18
|
Requires-Dist: PySerial>=3.5
|
|
19
19
|
Requires-Dist: cocotb>=2.0
|
|
20
|
+
Requires-Dist: supports_color>=0.2.0
|
|
20
21
|
Dynamic: license-file
|
|
@@ -249,8 +249,11 @@ class DepsFile:
|
|
|
249
249
|
self.rel_deps_file = os.path.join(os.path.relpath(deps_path), deps_leaf)
|
|
250
250
|
|
|
251
251
|
self.error = getattr(command_design_ref, 'error', None)
|
|
252
|
+
self.error_ifarg = getattr(command_design_ref, 'error_ifarg', None)
|
|
252
253
|
if not self.error:
|
|
253
254
|
self.error = util.error
|
|
255
|
+
if not self.error_ifarg:
|
|
256
|
+
self.error_ifarg = util.error
|
|
254
257
|
|
|
255
258
|
|
|
256
259
|
def found(self) -> bool:
|
|
@@ -320,19 +323,28 @@ class DepsFile:
|
|
|
320
323
|
# If we don't have caller_info, likely came from command line (or DEPS JSON data):
|
|
321
324
|
if '.' in target_node:
|
|
322
325
|
# Likely a filename (target_node does not include path)
|
|
323
|
-
self.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
+
self.error_ifarg(
|
|
327
|
+
f'Trying to resolve command-line target={t_full} (file?):',
|
|
328
|
+
f'File={t_node} not found in directory={t_path}',
|
|
329
|
+
arg='error-unknown-args',
|
|
330
|
+
error_code=EDA_DEPS_FILE_NOT_FOUND
|
|
331
|
+
)
|
|
326
332
|
elif not self.rel_deps_file:
|
|
327
333
|
# target, but there's no DEPS file
|
|
328
|
-
self.
|
|
329
|
-
|
|
330
|
-
|
|
334
|
+
self.error_ifarg(
|
|
335
|
+
f'Trying to resolve command-line target={t_full}:',
|
|
336
|
+
f'but path {t_path} has no DEPS markup file (DEPS.yml)',
|
|
337
|
+
arg='error-unknown-args',
|
|
338
|
+
error_code=EDA_DEPS_FILE_NOT_FOUND
|
|
339
|
+
)
|
|
331
340
|
else:
|
|
332
341
|
self.warning_show_available_targets()
|
|
333
|
-
self.
|
|
334
|
-
|
|
335
|
-
|
|
342
|
+
self.error_ifarg(
|
|
343
|
+
f'Trying to resolve command-line target={t_full}:',
|
|
344
|
+
f'was not found in deps_file={self.rel_deps_file}',
|
|
345
|
+
arg='error-unknown-args',
|
|
346
|
+
error_code=EDA_DEPS_TARGET_NOT_FOUND
|
|
347
|
+
)
|
|
336
348
|
|
|
337
349
|
else:
|
|
338
350
|
# If we have caller_info, then this was a recursive call from another
|
|
@@ -340,22 +352,31 @@ class DepsFile:
|
|
|
340
352
|
|
|
341
353
|
if '.' in target_node:
|
|
342
354
|
# Likely a filename (target_node does not include path)
|
|
343
|
-
self.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
355
|
+
self.error_ifarg(
|
|
356
|
+
f'Trying to resolve target={t_full} (file?):',
|
|
357
|
+
f'called from {caller_info},',
|
|
358
|
+
f'File={t_node} not found in directory={t_path}',
|
|
359
|
+
arg='error-unknown-args',
|
|
360
|
+
error_code=EDA_DEPS_FILE_NOT_FOUND
|
|
361
|
+
)
|
|
347
362
|
elif not self.rel_deps_file:
|
|
348
363
|
# target, but there's no DEPS file
|
|
349
|
-
self.
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
364
|
+
self.error_ifarg(
|
|
365
|
+
f'Trying to resolve target={t_full}:',
|
|
366
|
+
f'called from {caller_info},',
|
|
367
|
+
f'but {t_path} has no DEPS markup file (DEPS.yml)',
|
|
368
|
+
arg='error-unknown-args',
|
|
369
|
+
error_code=EDA_DEPS_FILE_NOT_FOUND
|
|
370
|
+
)
|
|
353
371
|
else:
|
|
354
372
|
self.warning_show_available_targets()
|
|
355
|
-
self.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
373
|
+
self.error_ifarg(
|
|
374
|
+
f'Trying to resolve target={t_full}:',
|
|
375
|
+
f'called from {caller_info},',
|
|
376
|
+
f'Target not found in deps_file={self.rel_deps_file}',
|
|
377
|
+
arg='error-unknown-args',
|
|
378
|
+
error_code=EDA_DEPS_TARGET_NOT_FOUND
|
|
379
|
+
)
|
|
359
380
|
else:
|
|
360
381
|
debug(f'Found {target_node=} in deps_file={self.rel_deps_file}')
|
|
361
382
|
found_target = True
|
|
@@ -250,7 +250,9 @@ class Command: # pylint: disable=too-many-public-methods
|
|
|
250
250
|
' --disable-tags has higher precedence than --enable-tags.'),
|
|
251
251
|
'test-mode': ('command and tool dependent, usually stops the command early without'
|
|
252
252
|
' executing.'),
|
|
253
|
-
'error-unknown-args':
|
|
253
|
+
'error-unknown-args': (
|
|
254
|
+
'Enable errors on unknown/unparsable args, or unknown/nonexistent files, or targets'
|
|
255
|
+
),
|
|
254
256
|
})
|
|
255
257
|
self.modified_args = {}
|
|
256
258
|
self.config = copy.deepcopy(config) # avoid external modifications.
|
|
@@ -497,9 +499,11 @@ class Command: # pylint: disable=too-many-public-methods
|
|
|
497
499
|
|
|
498
500
|
# Do some minimal type handling, preserving the type(self.args[key])
|
|
499
501
|
if key not in self.args:
|
|
500
|
-
self.
|
|
502
|
+
self.error_ifarg(
|
|
501
503
|
f'set_arg, {key=} not in self.args {value=}',
|
|
502
|
-
f'({self.command_name=}, {self.__class__.__name__=})'
|
|
504
|
+
f'({self.command_name=}, {self.__class__.__name__=})',
|
|
505
|
+
arg='error-unknown-args',
|
|
506
|
+
error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
503
507
|
)
|
|
504
508
|
|
|
505
509
|
cur_value = self.args[key]
|
|
@@ -695,9 +699,11 @@ class Command: # pylint: disable=too-many-public-methods
|
|
|
695
699
|
_, unparsed = self.run_argparser_on_list(tokens)
|
|
696
700
|
if process_all and unparsed:
|
|
697
701
|
self.warning_show_known_args()
|
|
698
|
-
self.
|
|
702
|
+
self.error_ifarg(
|
|
699
703
|
f"Didn't understand argument: '{unparsed=}' in",
|
|
700
|
-
f"{self.command_name=} context, {pwd=}"
|
|
704
|
+
f"{self.command_name=} context, {pwd=}",
|
|
705
|
+
arg='error-unknown-args',
|
|
706
|
+
error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
701
707
|
)
|
|
702
708
|
|
|
703
709
|
return unparsed
|
|
@@ -914,13 +920,17 @@ class Command: # pylint: disable=too-many-public-methods
|
|
|
914
920
|
lines.append(self.pretty_str_known_args(command=commands[-1])) # use last command if > 1
|
|
915
921
|
util.warning("\n".join(lines))
|
|
916
922
|
|
|
917
|
-
def
|
|
923
|
+
def error_ifarg(
|
|
924
|
+
self, *msg, arg: str, error_code: int = status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
925
|
+
) -> None:
|
|
918
926
|
'''For errors involving an unknown --arg, they can be optionally disabled
|
|
919
927
|
|
|
920
|
-
using --no-error-unknown-args
|
|
928
|
+
using CLI: --no-error-unknown-args, and this method arg='error-uknown-arg'
|
|
929
|
+
|
|
930
|
+
Note if arg is not present in self.args, the error is enabled.
|
|
921
931
|
'''
|
|
922
|
-
if self.args
|
|
923
|
-
self.error(*msg, error_code=
|
|
932
|
+
if self.args.get(arg, True):
|
|
933
|
+
self.error(*msg, error_code=error_code)
|
|
924
934
|
else:
|
|
925
935
|
util.warning(*msg)
|
|
926
936
|
|
|
@@ -1497,8 +1507,12 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1497
1507
|
found_target = True
|
|
1498
1508
|
break # move on to the next target
|
|
1499
1509
|
if not found_target and error_on_not_found: # if STILL not found_this_target...
|
|
1500
|
-
|
|
1501
|
-
|
|
1510
|
+
# allow this if --no-error-unknown-args:
|
|
1511
|
+
self.error_ifarg(
|
|
1512
|
+
f"Unable to resolve {target=}",
|
|
1513
|
+
arg='error-unknown-args',
|
|
1514
|
+
error_code=status_constants.EDA_DEPS_TARGET_NOT_FOUND
|
|
1515
|
+
)
|
|
1502
1516
|
|
|
1503
1517
|
# if we've found any target since being called, it means we found the one we were called for
|
|
1504
1518
|
return found_target
|
|
@@ -1660,9 +1674,11 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1660
1674
|
if process_all and possible_unparsed_args:
|
|
1661
1675
|
_tool = self.safe_which_tool()
|
|
1662
1676
|
self.warning_show_known_args()
|
|
1663
|
-
self.
|
|
1677
|
+
self.error_ifarg(
|
|
1664
1678
|
f"Didn't understand unparsed args: {possible_unparsed_args}, for command",
|
|
1665
|
-
f"'{self.command_name}', tool '{_tool}'"
|
|
1679
|
+
f"'{self.command_name}', tool '{_tool}'",
|
|
1680
|
+
arg='error-unknown-args',
|
|
1681
|
+
error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
1666
1682
|
)
|
|
1667
1683
|
|
|
1668
1684
|
remove_list = []
|
|
@@ -1721,9 +1737,11 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1721
1737
|
# we were unable to figure out what this command line token is for...
|
|
1722
1738
|
if process_all and unparsed:
|
|
1723
1739
|
self.warning_show_known_args()
|
|
1724
|
-
self.
|
|
1740
|
+
self.error_ifarg(
|
|
1725
1741
|
f"Didn't understand remaining args or targets {unparsed=} for command",
|
|
1726
|
-
f"'{self.command_name}'"
|
|
1742
|
+
f"'{self.command_name}'",
|
|
1743
|
+
arg='error-unknown-args',
|
|
1744
|
+
error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
1727
1745
|
)
|
|
1728
1746
|
|
|
1729
1747
|
# handle a missing self.args['top'] with last filepath or last target:
|
|
@@ -2269,9 +2287,11 @@ class CommandParallel(Command):
|
|
|
2269
2287
|
bad_remaining_args = [x for x in single_cmd_unparsed if x.startswith('-')]
|
|
2270
2288
|
if bad_remaining_args:
|
|
2271
2289
|
self.warning_show_known_args(command=f'{self.command_name} {command}')
|
|
2272
|
-
self.
|
|
2290
|
+
self.error_ifarg(
|
|
2273
2291
|
f'for {self.command_name} {command=} the following args are unknown',
|
|
2274
|
-
f'{bad_remaining_args}'
|
|
2292
|
+
f'{bad_remaining_args}',
|
|
2293
|
+
arg='error-unknown-args',
|
|
2294
|
+
error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR
|
|
2275
2295
|
)
|
|
2276
2296
|
|
|
2277
2297
|
# Remove unparsed args starting with '+', since those are commonly sent downstream to
|
|
@@ -145,6 +145,7 @@ tools:
|
|
|
145
145
|
--timescale=1ns/1ns
|
|
146
146
|
--allow-dup-initial-drivers
|
|
147
147
|
-Wno-missing-top
|
|
148
|
+
compile-waivers: []
|
|
148
149
|
|
|
149
150
|
verilator:
|
|
150
151
|
defines: { }
|
|
@@ -153,11 +154,11 @@ tools:
|
|
|
153
154
|
- "%Fatal"
|
|
154
155
|
log-must-strings:
|
|
155
156
|
- "R e p o r t: Verilator" # These come at end of compile or simulation, since we don't suppress it.
|
|
157
|
+
# Note: -j $(nproc) is handled in verilator.py, but you can override it in compile-args
|
|
156
158
|
compile-args: |
|
|
157
159
|
--timing
|
|
158
160
|
--assert
|
|
159
161
|
--autoflush
|
|
160
|
-
-j 2
|
|
161
162
|
-sv
|
|
162
163
|
compile-coverage-args: |
|
|
163
164
|
--coverage
|
|
@@ -9,12 +9,14 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
from contextlib import redirect_stdout, redirect_stderr
|
|
11
11
|
|
|
12
|
-
from opencos import eda
|
|
13
|
-
from opencos import deps_schema
|
|
12
|
+
from opencos import eda, eda_tool_helper, deps_schema
|
|
14
13
|
from opencos.utils.markup_helpers import yaml_safe_load
|
|
15
14
|
from opencos.utils import status_constants
|
|
16
15
|
from opencos.utils.subprocess_helpers import subprocess_run_background
|
|
17
16
|
|
|
17
|
+
# Figure out what tools the system has available, without calling eda.main(..)
|
|
18
|
+
config, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
def eda_wrap_is_sim_fail(rc: int, quiet: bool = False) -> bool:
|
|
20
22
|
'''Because eda_wrap calls eda_main(..) and will continue running
|
|
@@ -30,11 +32,11 @@ def eda_wrap_is_sim_fail(rc: int, quiet: bool = False) -> bool:
|
|
|
30
32
|
status_constants.EDA_DEFAULT_ERROR
|
|
31
33
|
)
|
|
32
34
|
|
|
33
|
-
def can_run_eda_command(*commands,
|
|
35
|
+
def can_run_eda_command(*commands, cfg: dict = config) -> bool:
|
|
34
36
|
'''Returns True if we have any installed tool that can run: eda <command>'''
|
|
35
37
|
runnable = []
|
|
36
38
|
for command in list(commands):
|
|
37
|
-
handler =
|
|
39
|
+
handler = cfg['command_handler'].get(command, None)
|
|
38
40
|
if not handler:
|
|
39
41
|
return False
|
|
40
42
|
if handler and getattr(handler, 'CHECK_REQUIRES', []):
|
|
@@ -44,7 +46,7 @@ def can_run_eda_command(*commands, config: dict) -> bool:
|
|
|
44
46
|
# We cannot run tools that have disable-auto set:
|
|
45
47
|
tool = getattr(handler, '_TOOL', '')
|
|
46
48
|
if handler and tool:
|
|
47
|
-
entry =
|
|
49
|
+
entry = cfg['auto_tools_order'][0].get(tool, {})
|
|
48
50
|
if entry and entry.get('disable-auto', False):
|
|
49
51
|
# This tool cannot automatically run our command.
|
|
50
52
|
return False
|
|
@@ -52,6 +54,14 @@ def can_run_eda_command(*commands, config: dict) -> bool:
|
|
|
52
54
|
runnable.append(True)
|
|
53
55
|
return runnable and all(runnable)
|
|
54
56
|
|
|
57
|
+
def can_run_eda_sim(cfg: dict = config) -> bool:
|
|
58
|
+
'''Returns True if we have any installed tool that can run: eda sim'''
|
|
59
|
+
return can_run_eda_command('sim', cfg=cfg)
|
|
60
|
+
|
|
61
|
+
def can_run_eda_elab(cfg: dict = config) -> bool:
|
|
62
|
+
'''Returns True if we have any installed tool that can run: eda elab'''
|
|
63
|
+
return can_run_eda_command('elab', cfg=cfg)
|
|
64
|
+
|
|
55
65
|
def chdir_remove_work_dir(startpath, relpath):
|
|
56
66
|
'''Changes dir to startpath/relpath, removes the work directories (eda.work, eda.export*)'''
|
|
57
67
|
os.chdir(os.path.join(str(Path(startpath)), str(Path(relpath))))
|
|
@@ -232,7 +242,9 @@ class Helpers:
|
|
|
232
242
|
|
|
233
243
|
return rc
|
|
234
244
|
|
|
235
|
-
def is_in_log(
|
|
245
|
+
def is_in_log(
|
|
246
|
+
self, *want_str, logfile=None, windows_path_support: bool = False
|
|
247
|
+
) -> bool:
|
|
236
248
|
'''Check if want_str (joined) is in the logfile, or self.DEFAULT_LOG'''
|
|
237
249
|
logfile = self._resolve_logfile(logfile)
|
|
238
250
|
want_str0 = ' '.join(list(want_str))
|
|
@@ -244,7 +256,9 @@ class Helpers:
|
|
|
244
256
|
return True
|
|
245
257
|
return False
|
|
246
258
|
|
|
247
|
-
def get_log_lines_with(
|
|
259
|
+
def get_log_lines_with(
|
|
260
|
+
self, *want_str, logfile=None, windows_path_support: bool = False
|
|
261
|
+
) -> list:
|
|
248
262
|
'''gets all log lines with any of want_str args are in the logfile, or self.DEFAULT_LOG'''
|
|
249
263
|
logfile = self._resolve_logfile(logfile)
|
|
250
264
|
ret_list = []
|
|
@@ -257,6 +271,21 @@ class Helpers:
|
|
|
257
271
|
ret_list.append(line)
|
|
258
272
|
return ret_list
|
|
259
273
|
|
|
274
|
+
def get_log_lines_with_all(
|
|
275
|
+
self, *want_str, logfile=None, windows_path_support: bool = False
|
|
276
|
+
) -> list:
|
|
277
|
+
'''gets all log lines with ALL of want_str args are in the logfile, or self.DEFAULT_LOG'''
|
|
278
|
+
logfile = self._resolve_logfile(logfile)
|
|
279
|
+
ret_list = []
|
|
280
|
+
with open(logfile, encoding='utf-8') as f:
|
|
281
|
+
for line in f.readlines():
|
|
282
|
+
if all(x in line for x in list(want_str)):
|
|
283
|
+
ret_list.append(line)
|
|
284
|
+
elif windows_path_support and \
|
|
285
|
+
all(x.replace('/', '\\') in line for x in list(want_str)):
|
|
286
|
+
ret_list.append(line)
|
|
287
|
+
return ret_list
|
|
288
|
+
|
|
260
289
|
def get_log_words_with(self, *want_str, logfile=None, windows_path_support=False):
|
|
261
290
|
'''gets all log words with any of *want_str within a single word
|
|
262
291
|
in the logfile or self.DEFAULT_LOG
|
|
@@ -23,11 +23,12 @@ import subprocess
|
|
|
23
23
|
|
|
24
24
|
import pytest
|
|
25
25
|
|
|
26
|
-
from opencos import eda
|
|
26
|
+
from opencos import eda
|
|
27
27
|
from opencos.utils.markup_helpers import yaml_safe_load
|
|
28
28
|
from opencos.tests import helpers
|
|
29
29
|
from opencos.tests.helpers import eda_wrap, eda_sim_wrap, eda_elab_wrap, \
|
|
30
|
-
Helpers
|
|
30
|
+
Helpers, tools_loaded, can_run_eda_sim
|
|
31
|
+
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
THISPATH = os.path.dirname(__file__)
|
|
@@ -36,17 +37,6 @@ def chdir_remove_work_dir(relpath):
|
|
|
36
37
|
'''Changes dir to relpath, removes the work directories (eda.work, eda.export*)'''
|
|
37
38
|
return helpers.chdir_remove_work_dir(THISPATH, relpath)
|
|
38
39
|
|
|
39
|
-
# Figure out what tools the system has available, without calling eda.main(..)
|
|
40
|
-
config, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
41
|
-
|
|
42
|
-
def can_run_eda_sim() -> bool:
|
|
43
|
-
'''Returns True if we have any installed tool that can run: eda sim'''
|
|
44
|
-
return helpers.can_run_eda_command('sim', config=config)
|
|
45
|
-
|
|
46
|
-
def can_run_eda_elab() -> bool:
|
|
47
|
-
'''Returns True if we have any installed tool that can run: eda elab'''
|
|
48
|
-
return helpers.can_run_eda_command('elab', config=config)
|
|
49
|
-
|
|
50
40
|
@pytest.mark.skipif(
|
|
51
41
|
'verilator' not in tools_loaded and 'vivado' not in tools_loaded,
|
|
52
42
|
reason="requires verilator OR vivado"
|
|
@@ -6,25 +6,23 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
-
from opencos import eda,
|
|
9
|
+
from opencos import eda, eda_base
|
|
10
10
|
|
|
11
11
|
from opencos.tools.verilator import ToolVerilator
|
|
12
12
|
from opencos.tools.vivado import ToolVivado
|
|
13
13
|
from opencos.tools.cocotb import ToolCocotb
|
|
14
14
|
from opencos.tests import helpers
|
|
15
|
-
from opencos.tests.helpers import eda_wrap, eda_wrap_is_sim_fail
|
|
15
|
+
from opencos.tests.helpers import eda_wrap, eda_wrap_is_sim_fail, config, tools_loaded
|
|
16
16
|
from opencos.utils.markup_helpers import yaml_safe_load
|
|
17
17
|
from opencos.utils import status_constants
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
THISPATH = os.path.dirname(__file__)
|
|
21
21
|
|
|
22
22
|
def chdir_remove_work_dir(relpath):
|
|
23
23
|
'''Changes dir to relpath, removes the work directories (eda.work, eda.export*)'''
|
|
24
|
-
return helpers.chdir_remove_work_dir(
|
|
24
|
+
return helpers.chdir_remove_work_dir(THISPATH, relpath)
|
|
25
25
|
|
|
26
|
-
# Figure out what tools the system has available, without calling eda.main(..)
|
|
27
|
-
config, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
28
26
|
|
|
29
27
|
def test_tools_loaded():
|
|
30
28
|
'''Does not directly call 'eda.main' instead create a few Tool
|
|
@@ -37,7 +35,7 @@ def test_tools_loaded():
|
|
|
37
35
|
# It's possible we're running in some container or install that has no tools, for example,
|
|
38
36
|
# Windows.
|
|
39
37
|
if sys.platform.startswith('win') and \
|
|
40
|
-
not helpers.can_run_eda_command('elab', 'sim',
|
|
38
|
+
not helpers.can_run_eda_command('elab', 'sim', cfg=config):
|
|
41
39
|
# Windows, not handlers for elab or sim:
|
|
42
40
|
pass
|
|
43
41
|
else:
|
|
@@ -129,7 +127,7 @@ def test_sim_elab_tools_pass_or_fail(command, tool, target, sim_expect_pass, add
|
|
|
129
127
|
added_args = added_sim_args_str.split()
|
|
130
128
|
|
|
131
129
|
relative_dir = "deps_files/test_err_fatal"
|
|
132
|
-
os.chdir(os.path.join(
|
|
130
|
+
os.chdir(os.path.join(THISPATH, relative_dir))
|
|
133
131
|
rc = eda.main(command, '--tool', tool, *(added_args), target)
|
|
134
132
|
print(f'{rc=}')
|
|
135
133
|
if command != 'sim' or sim_expect_pass:
|
|
@@ -128,6 +128,7 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
128
128
|
command_list += self.tool_config.get('compile-args', '--single-unit').split()
|
|
129
129
|
command_list += self.args['slang-args'] # add user args.
|
|
130
130
|
command_list += self._get_slang_json_args(command_exe=command_list[0])
|
|
131
|
+
command_list += self._get_slang_tool_config_waivers()
|
|
131
132
|
|
|
132
133
|
# incdirs
|
|
133
134
|
for value in self.incdirs:
|
|
@@ -214,6 +215,11 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
214
215
|
|
|
215
216
|
return command_list
|
|
216
217
|
|
|
218
|
+
def _get_slang_tool_config_waivers(self) -> list:
|
|
219
|
+
# Add compile waivers from config and command-line args
|
|
220
|
+
return [f'-Wno-{waiver}' for waiver in
|
|
221
|
+
self.tool_config.get('compile-waivers', []) + self.args['compile-waivers']]
|
|
222
|
+
|
|
217
223
|
|
|
218
224
|
class CommandLintSlang(CommandElabSlang):
|
|
219
225
|
'''CommandLintSlang is a command handler for: eda lint --tool=slang.'''
|
|
@@ -5,10 +5,12 @@ Contains classes for ToolVerilator and VerilatorSim, VerilatorElab.
|
|
|
5
5
|
|
|
6
6
|
# pylint: disable=R0801 # (calling functions with same arguments)
|
|
7
7
|
|
|
8
|
+
import multiprocessing
|
|
8
9
|
import os
|
|
9
10
|
import shutil
|
|
10
11
|
import subprocess
|
|
11
12
|
|
|
13
|
+
|
|
12
14
|
from opencos import util
|
|
13
15
|
from opencos.eda_base import Tool
|
|
14
16
|
from opencos.commands import CommandSim
|
|
@@ -210,15 +212,9 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
210
212
|
|
|
211
213
|
verilate_command_list = self._get_start_verilator_command_list(lint_only=lint_only)
|
|
212
214
|
|
|
213
|
-
# Add compile args from our self.config (tools.verilator.compile-args str)
|
|
214
|
-
config_compile_args = self.tool_config.get(
|
|
215
|
-
'compile-args',
|
|
216
|
-
'--timing --assert --autoflush -sv').split()
|
|
217
|
-
verilate_command_list += config_compile_args
|
|
218
|
-
|
|
219
215
|
verilate_command_list += self._get_verilator_tool_config_waivers()
|
|
220
216
|
|
|
221
|
-
verilate_command_list += self.
|
|
217
|
+
verilate_command_list += self._verilator_args_defaults_cflags_nproc()
|
|
222
218
|
|
|
223
219
|
verilate_command_list += self._get_verilator_waves_args(lint_only=lint_only)
|
|
224
220
|
|
|
@@ -425,45 +421,51 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
425
421
|
return ret
|
|
426
422
|
|
|
427
423
|
|
|
428
|
-
def
|
|
424
|
+
def _verilator_args_defaults_cflags_nproc(self) -> list:
|
|
429
425
|
'''Returns list of args to be added to verilator (compile) step
|
|
430
426
|
|
|
431
|
-
Uses self.args['verilate-args']
|
|
427
|
+
Uses self.args['verilate-args'], self.args['compile-args'], and self.tool_config
|
|
428
|
+
|
|
429
|
+
Sets -j <value> and -CFLAGS -O<value> if not present in --config-yml, --compile-args,
|
|
430
|
+
or --verilate-args. If present, chooses the first instance (does not present duplicates
|
|
431
|
+
to verilator call).
|
|
432
432
|
'''
|
|
433
433
|
|
|
434
|
-
# We can only support one -CFLAGS followed by one -O[0-9] arg in
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
434
|
+
# We can only support one -CFLAGS followed by one -O[0-9] arg in
|
|
435
|
+
# --verilate-args or --compile-args.
|
|
436
|
+
|
|
437
|
+
# Add compile args from our self.config (tools.verilator.compile-args str)
|
|
438
|
+
verilate_args = self.args['verilate-args'] + \
|
|
439
|
+
self.args['compile-args'] + \
|
|
440
|
+
self.tool_config.get(
|
|
441
|
+
'compile-args',
|
|
442
|
+
'--timing --assert --autoflush -sv').split()
|
|
443
|
+
|
|
438
444
|
util.debug(f"{self.args['verilate-args']=}")
|
|
439
445
|
util.debug(f"{self.args['compile-args']=}")
|
|
440
|
-
for arg in self.args['verilate-args'] + self.args['compile-args']:
|
|
441
|
-
# pick the first ones we see of these:
|
|
442
|
-
if arg == '-CFLAGS':
|
|
443
|
-
prev_arg_is_cflags = True
|
|
444
|
-
if arg not in verilate_cflags_args_dict:
|
|
445
|
-
# We can only have 1
|
|
446
|
-
verilate_cflags_args_dict[arg] = True
|
|
447
|
-
verilate_args.append(arg)
|
|
448
|
-
else:
|
|
449
|
-
util.debug(f'Previous saw -CFLAGS args {verilate_cflags_args_dict=},',
|
|
450
|
-
f'skipping new {arg=}')
|
|
451
|
-
|
|
452
|
-
elif arg.startswith('-O') and len(arg) == 3:
|
|
453
|
-
if '-O' not in verilate_cflags_args_dict and prev_arg_is_cflags:
|
|
454
|
-
# We can only have 1
|
|
455
|
-
verilate_cflags_args_dict['-O'] = arg[-1]
|
|
456
|
-
verilate_args.append(arg)
|
|
457
|
-
else:
|
|
458
|
-
util.debug(f'Previous saw -CFLAGS args {verilate_cflags_args_dict=},',
|
|
459
|
-
f'skipping new {arg=}')
|
|
460
|
-
prev_arg_is_cflags = False
|
|
461
|
-
|
|
462
|
-
else:
|
|
463
|
-
prev_arg_is_cflags = False
|
|
464
|
-
verilate_args.append(arg)
|
|
465
446
|
|
|
466
|
-
|
|
447
|
+
dash_j_arg_indices = []
|
|
448
|
+
cflags_dasho_args_indices = []
|
|
449
|
+
for i, arg in enumerate(list(verilate_args)):
|
|
450
|
+
# There can only be one of these: -j <value>, similarly can only be one of
|
|
451
|
+
# -CFLAGS -O<value>
|
|
452
|
+
if (i + 1) < len(verilate_args):
|
|
453
|
+
if arg == '-j':
|
|
454
|
+
dash_j_arg_indices.extend([i, i + 1])
|
|
455
|
+
if arg == '-CFLAGS':
|
|
456
|
+
next_arg = verilate_args[i + 1]
|
|
457
|
+
if next_arg.startswith('-O') and len(next_arg) == 3:
|
|
458
|
+
cflags_dasho_args_indices.extend([i, i + 1])
|
|
459
|
+
|
|
460
|
+
# For -j <value> we'll pick the first one, remove the rest.
|
|
461
|
+
# Same goes for -CFLAGS -O<value>
|
|
462
|
+
for index in dash_j_arg_indices[2:] + cflags_dasho_args_indices[2:]:
|
|
463
|
+
verilate_args[index] = ''
|
|
464
|
+
|
|
465
|
+
verilate_args = [x for x in verilate_args if x != ''] # strip empty str.
|
|
466
|
+
|
|
467
|
+
# Support for --optimize which will use -CFLAGS -O3, if -CFLAGS is not present at all.
|
|
468
|
+
if cflags_dasho_args_indices:
|
|
467
469
|
# add whatever args were passed via 'compile-args' or 'verilate_args'. Note these will
|
|
468
470
|
# take precedence over the --optimize arg.
|
|
469
471
|
pass
|
|
@@ -472,8 +474,15 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
472
474
|
# (slower compile, better runtime)
|
|
473
475
|
verilate_args += '-CFLAGS', '-O3'
|
|
474
476
|
else:
|
|
477
|
+
# Default to -O1:
|
|
475
478
|
verilate_args += '-CFLAGS', '-O1'
|
|
476
479
|
|
|
480
|
+
# If there was no -j setting, then use max(2, $(nproc) - 1)
|
|
481
|
+
if not dash_j_arg_indices:
|
|
482
|
+
nproc = max(2, multiprocessing.cpu_count() - 1)
|
|
483
|
+
verilate_args += '-j', f'{nproc}'
|
|
484
|
+
|
|
485
|
+
|
|
477
486
|
return verilate_args
|
|
478
487
|
|
|
479
488
|
|
|
@@ -18,6 +18,7 @@ from enum import Enum
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from importlib import import_module
|
|
20
20
|
from dotenv import load_dotenv
|
|
21
|
+
from supports_color import supportsColor
|
|
21
22
|
|
|
22
23
|
from opencos.utils import status_constants
|
|
23
24
|
|
|
@@ -29,7 +30,7 @@ dot_f_files_expanded = set() # pylint: disable=invalid-name
|
|
|
29
30
|
env_files_loaded = set() # pylint: disable=invalid-name
|
|
30
31
|
|
|
31
32
|
args = { # pylint: disable=invalid-name
|
|
32
|
-
'color' :
|
|
33
|
+
'color' : bool(supportsColor.stdout),
|
|
33
34
|
'quiet' : False,
|
|
34
35
|
'verbose' : False,
|
|
35
36
|
'debug' : False,
|
|
@@ -351,13 +352,14 @@ def get_argparser() -> argparse.ArgumentParser:
|
|
|
351
352
|
bool_action_kwargs = get_argparse_bool_action_kwargs()
|
|
352
353
|
|
|
353
354
|
parser.add_argument('--version', default=False, action='store_true')
|
|
354
|
-
parser.add_argument('--color', **bool_action_kwargs, default=
|
|
355
|
+
parser.add_argument('--color', **bool_action_kwargs, default=bool(supportsColor.stdout),
|
|
355
356
|
help='Use shell colors for info/warning/error messaging')
|
|
356
|
-
parser.add_argument('--quiet', **bool_action_kwargs,
|
|
357
|
-
|
|
357
|
+
parser.add_argument('--quiet', **bool_action_kwargs, default=args['quiet'],
|
|
358
|
+
help='Do not display info messaging')
|
|
359
|
+
parser.add_argument('--verbose', **bool_action_kwargs, default=args['verbose'],
|
|
358
360
|
help='Display additional messaging level 2 or higher')
|
|
359
|
-
parser.add_argument('--fancy', **bool_action_kwargs)
|
|
360
|
-
parser.add_argument('--debug', **bool_action_kwargs,
|
|
361
|
+
parser.add_argument('--fancy', **bool_action_kwargs, default=args['fancy'])
|
|
362
|
+
parser.add_argument('--debug', **bool_action_kwargs, default=args['debug'],
|
|
361
363
|
help='Display additional debug messaging level 1 or higher')
|
|
362
364
|
parser.add_argument('--debug-level', type=int, default=0,
|
|
363
365
|
help='Set debug level messaging (default: 0)')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
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
|
|
@@ -17,4 +17,5 @@ Requires-Dist: toml>=0.10.2
|
|
|
17
17
|
Requires-Dist: yamllint>=1.35.1
|
|
18
18
|
Requires-Dist: PySerial>=3.5
|
|
19
19
|
Requires-Dist: cocotb>=2.0
|
|
20
|
+
Requires-Dist: supports_color>=0.2.0
|
|
20
21
|
Dynamic: license-file
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[project]
|
|
4
4
|
name = "opencos-eda"
|
|
5
|
-
version = "0.3.
|
|
5
|
+
version = "0.3.3"
|
|
6
6
|
dependencies = [
|
|
7
7
|
# opencos/eda.py dependencies
|
|
8
8
|
"mergedeep >= 1.3.4",
|
|
@@ -16,6 +16,7 @@ dependencies = [
|
|
|
16
16
|
# opencos/oc_cli.py dependencies
|
|
17
17
|
"PySerial >= 3.5",
|
|
18
18
|
"cocotb >= 2.0",
|
|
19
|
+
"supports_color >= 0.2.0",
|
|
19
20
|
]
|
|
20
21
|
requires-python = ">= 3.8"
|
|
21
22
|
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
|
|
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
|