opencos-eda 0.2.47__py3-none-any.whl → 0.2.49__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. opencos/__init__.py +4 -2
  2. opencos/_version.py +10 -7
  3. opencos/commands/flist.py +8 -7
  4. opencos/commands/multi.py +35 -18
  5. opencos/commands/sweep.py +9 -4
  6. opencos/commands/waves.py +1 -1
  7. opencos/deps/__init__.py +0 -0
  8. opencos/deps/defaults.py +69 -0
  9. opencos/deps/deps_commands.py +419 -0
  10. opencos/deps/deps_file.py +326 -0
  11. opencos/deps/deps_processor.py +670 -0
  12. opencos/deps_schema.py +7 -8
  13. opencos/eda.py +92 -67
  14. opencos/eda_base.py +625 -332
  15. opencos/eda_config.py +80 -14
  16. opencos/eda_extract_targets.py +22 -14
  17. opencos/eda_tool_helper.py +33 -7
  18. opencos/export_helper.py +166 -86
  19. opencos/export_json_convert.py +31 -23
  20. opencos/files.py +2 -1
  21. opencos/hw/__init__.py +0 -0
  22. opencos/{oc_cli.py → hw/oc_cli.py} +9 -4
  23. opencos/names.py +0 -4
  24. opencos/peakrdl_cleanup.py +13 -7
  25. opencos/seed.py +19 -11
  26. opencos/tests/helpers.py +27 -14
  27. opencos/tests/test_deps_helpers.py +35 -32
  28. opencos/tests/test_eda.py +47 -41
  29. opencos/tests/test_eda_elab.py +5 -3
  30. opencos/tests/test_eda_synth.py +1 -1
  31. opencos/tests/test_oc_cli.py +1 -1
  32. opencos/tests/test_tools.py +3 -2
  33. opencos/tools/iverilog.py +2 -2
  34. opencos/tools/modelsim_ase.py +2 -2
  35. opencos/tools/riviera.py +1 -1
  36. opencos/tools/slang.py +1 -1
  37. opencos/tools/surelog.py +1 -1
  38. opencos/tools/verilator.py +1 -1
  39. opencos/tools/vivado.py +1 -1
  40. opencos/tools/yosys.py +4 -3
  41. opencos/util.py +440 -483
  42. opencos/utils/__init__.py +0 -0
  43. opencos/utils/markup_helpers.py +98 -0
  44. opencos/utils/str_helpers.py +111 -0
  45. opencos/utils/subprocess_helpers.py +108 -0
  46. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/METADATA +1 -1
  47. opencos_eda-0.2.49.dist-info/RECORD +88 -0
  48. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/entry_points.txt +1 -1
  49. opencos/deps_helpers.py +0 -1346
  50. opencos_eda-0.2.47.dist-info/RECORD +0 -79
  51. /opencos/{pcie.py → hw/pcie.py} +0 -0
  52. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/WHEEL +0 -0
  53. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/licenses/LICENSE +0 -0
  54. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/licenses/LICENSE.spdx +0 -0
  55. {opencos_eda-0.2.47.dist-info → opencos_eda-0.2.49.dist-info}/top_level.txt +0 -0
File without changes
@@ -0,0 +1,98 @@
1
+ ''' opencos.utils.markup_helpers - function helpers for YAML, TOML reading and writing'''
2
+
3
+ import re
4
+ import shutil
5
+ import subprocess
6
+
7
+ import yaml
8
+
9
+ from opencos.util import debug, error, info, warning
10
+
11
+
12
+ def yaml_load_only_root_line_numbers(filepath: str) -> dict:
13
+ '''Returns a dict of {key: int line number}, very crude'''
14
+ # Other solutions aren't as attractive, require a lot of mappers to get
15
+ # line numbers on returned values that aren't dict
16
+ data = None
17
+ with open(filepath, encoding='utf-8') as f:
18
+ try:
19
+ # Try to do a very lazy parse of root level keys only, returns dict{key:lineno}
20
+ data = {}
21
+ for lineno,line in enumerate(f.readlines()):
22
+ m = re.match(r'^(\w+):', line)
23
+ if m:
24
+ key = m.group(1)
25
+ data[key] = lineno + 1
26
+ except Exception as e:
27
+ error(f"Error loading YAML {filepath=}:", e)
28
+ return data
29
+
30
+
31
+ def toml_load_only_root_line_numbers(filepath: str) -> dict:
32
+ '''Returns a dict of {key: int line number}, very crude'''
33
+ data = None
34
+ with open(filepath, encoding='utf-8') as f:
35
+ try:
36
+ data = {}
37
+ for lineno, line in enumerate(f.readlines()):
38
+ m = re.match(r'^\[(\w+)\]', line)
39
+ if m:
40
+ key = m.group(1)
41
+ data[key] = lineno + 1
42
+ except Exception as e:
43
+ error(f'Error loading TOML {filepath=}', e)
44
+ return data
45
+
46
+
47
+ def yaml_safe_load(filepath: str, only_root_line_numbers:bool = False) -> dict:
48
+ '''Returns dict or None from filepath (str), errors if return type not in assert_return_types.
49
+
50
+ only_root_line_numbers -- if True, will return a dict of {key: line number (int)} for
51
+ all the root level keys. Used for debugging DEPS.yml in
52
+ eda.CommandDesign.resolve_target_core
53
+ '''
54
+
55
+ data = None
56
+
57
+ if only_root_line_numbers:
58
+ return yaml_load_only_root_line_numbers(filepath)
59
+
60
+ with open(filepath, encoding='utf-8') as f:
61
+ debug(f'Opening {filepath=}')
62
+ try:
63
+ data = yaml.safe_load(f)
64
+ except yaml.YAMLError as e:
65
+
66
+ # if yamllint is installed, then use it to get all errors in the .yml|.yaml
67
+ # file, instead of the single exception.
68
+ if shutil.which('yamllint'):
69
+ try:
70
+ sp_out = subprocess.run(
71
+ f'yamllint -d relaxed --no-warnings {filepath}'.split(),
72
+ capture_output=True, text=True, check=False )
73
+ for x in sp_out.stdout.split('\n'):
74
+ if x:
75
+ info('yamllint: ' + x)
76
+ except Exception as e2:
77
+ debug(f'yamllimt exception: {e2}')
78
+
79
+ if hasattr(e, 'problem_mark'):
80
+ mark = e.problem_mark
81
+ error(f"Error parsing {filepath=}: line {mark.line + 1},",
82
+ f"column {mark.column +1}: {e.problem}")
83
+ else:
84
+ error(f"Error loading YAML {filepath=}:", e)
85
+ except Exception as e:
86
+ error(f"Error loading YAML {filepath=}:", e)
87
+
88
+ return data
89
+
90
+
91
+ def yaml_safe_writer(data: dict, filepath: str) -> None:
92
+ '''Warpper for yaml.dump, enforces file extension otherwise warning'''
93
+ if filepath.endswith('.yml') or filepath.endswith('.yaml'):
94
+ with open(filepath, 'w', encoding='utf-8') as f:
95
+ yaml.dump(data, f, allow_unicode=True,
96
+ default_flow_style=False, sort_keys=False, encoding='utf-8')
97
+ else:
98
+ warning(f'{filepath=} to be written for this extension not implemented.')
@@ -0,0 +1,111 @@
1
+ '''opencos.utils.str_helpers -- Various str helpers for printing, indenting'''
2
+
3
+ import fnmatch
4
+ import re
5
+ import shlex
6
+ import textwrap
7
+
8
+ def strip_all_quotes(s: str) -> str:
9
+ '''Returns str with all ' and " removed'''
10
+ return s.replace("'", '').replace('"', '')
11
+
12
+
13
+ def strip_outer_quotes(s: str) -> str:
14
+ '''Returns str with outer pairs of (' or ") removed
15
+
16
+ Note this is done safely removing only outmost pairs of single quotes, or double
17
+ quotes. This is used on bare CLI args that may have outer quotes from shlex.quote(arg).
18
+ '''
19
+ ret = str(s)
20
+ while (ret.startswith("'") and ret.endswith("'")) or \
21
+ (ret.startswith('"') and ret.endswith('"')):
22
+ ret = ret[1:-1]
23
+ return ret
24
+
25
+
26
+ def string_or_space(text: str, whitespace: bool = False) -> str:
27
+ '''Returns str of either spaces (len(text)) or returns text.'''
28
+ if whitespace:
29
+ return " " * len(text)
30
+ return text
31
+
32
+
33
+ def sanitize_defines_for_sh(value: object, shlex_quote: bool = False) -> str:
34
+ '''Attempts to make a str for +define+key[=value] safer for using as a shell arg
35
+
36
+ Need to sanitize this for shell in case someone sends a +define+foo+1'b0,
37
+ which needs to be escaped as +define+foo+1\'b0, otherwise bash or sh will
38
+ think this is an unterminated string.
39
+
40
+ Optionally can use shlex.quote('+define+key=value') via shlex_quote=True
41
+ '''
42
+ if isinstance(value, str):
43
+ value = value.replace("'", "\\" + "'")
44
+ if shlex_quote:
45
+ value = shlex.quote(value)
46
+ return value
47
+
48
+
49
+ def sprint_time(time_value: int) -> str:
50
+ '''Return pretty str for time'''
51
+ s = int(time_value)
52
+ txt = ""
53
+ do_all = False
54
+ # days
55
+ if s >= (24 * 60 * 60): # greater than 24h, we show days
56
+ d = int(s / (24 *60 *60))
57
+ txt += f"{d}d:"
58
+ s -= d * 24 * 60 * 60
59
+ do_all = True
60
+ # hours
61
+ if do_all or s >= (60 *60):
62
+ d = int(s / (60 * 60))
63
+ txt += f"{d:2}:"
64
+ s -= d * 60 * 60
65
+ do_all = True
66
+ # minutes
67
+ d = int(s / 60)
68
+ txt += f"{d:02}:"
69
+ s -= d * 60
70
+ # seconds
71
+ txt += f"{s:02}"
72
+ return txt
73
+
74
+
75
+ def indent_wrap_long_text(
76
+ text: str, width: int = 80, initial_indent: int = 0, indent: int = 4
77
+ ) -> str:
78
+ """Returns str, wraps text to a specified width and indents subsequent lines."""
79
+ wrapped_lines = textwrap.wrap(
80
+ text, width=width,
81
+ initial_indent=' ' * initial_indent,
82
+ subsequent_indent=' ' * indent
83
+ )
84
+ return '\n'.join(wrapped_lines)
85
+
86
+
87
+ def dep_str2list(value: object) -> list:
88
+ '''Helper for a markup \n or space separated string to be returned as a list'''
89
+ if value is None:
90
+ return []
91
+ if isinstance(value, str):
92
+ return re.split('\n+| +', value) # convert \n separated to list, also split on spaces
93
+ return value
94
+
95
+
96
+ def fnmatch_or_re(pattern: str, string: str) -> bool:
97
+ '''Returns True if pattern/string matches in re.match or fnmatch'''
98
+ matches = []
99
+ # fnmatch check, aka: ./*test
100
+ matches.append(
101
+ bool(fnmatch.fnmatch(name=string, pat=pattern))
102
+ )
103
+ # regex check, aka: ./.*test
104
+ try:
105
+ matches.append(
106
+ bool(re.match(pattern=pattern, string=string))
107
+ )
108
+ except: # pylint: disable=bare-except
109
+ # could have been an illegal/unsupported regex, so don't match.
110
+ pass
111
+ return any(matches)
@@ -0,0 +1,108 @@
1
+ ''' opencos.utils.subprocess_helpers -- wrappers for subprocess to support background/tee'''
2
+
3
+ import os
4
+ import shutil
5
+ import subprocess
6
+ import sys
7
+
8
+ from opencos.util import debug, error, info, progname, global_log
9
+
10
+ IS_WINDOWS = sys.platform.startswith('win')
11
+
12
+ def subprocess_run(
13
+ work_dir: str, command_list: list, fake: bool = False, shell: bool = False
14
+ ) -> int:
15
+ ''' Run command_list in the foreground, with preference to use bash if shell=True'''
16
+
17
+ proc_kwargs = {
18
+ 'shell': shell
19
+ }
20
+ if work_dir:
21
+ proc_kwargs['cwd'] = work_dir
22
+
23
+ bash_exec = shutil.which('bash')
24
+ if shell and bash_exec and not IS_WINDOWS:
25
+ proc_kwargs.update({'executable': bash_exec})
26
+
27
+ if not IS_WINDOWS and shell:
28
+ c = ' '.join(command_list)
29
+ else:
30
+ c = command_list
31
+
32
+ if fake:
33
+ info(f"subprocess_run FAKE: would have called subprocess.run({c}, **{proc_kwargs}")
34
+ return 0
35
+
36
+ debug(f"subprocess_run: About to call subprocess.run({c}, **{proc_kwargs}")
37
+ proc = subprocess.run(c, check=True, **proc_kwargs)
38
+ return proc.returncode
39
+
40
+
41
+ def subprocess_run_background(
42
+ work_dir: str, command_list: list, background: bool = True, fake : bool = False,
43
+ shell: bool = False, tee_fpath: str = ''
44
+ ) -> (str, str, int):
45
+ ''' Run command_list in the background, with preference to use bash if shell=True
46
+
47
+ tee_fpath is relative to work_dir.
48
+
49
+ Note that stderr is converted to stdout, and stderr is retuned as '':
50
+ Returns tuple of (stdout str, '', int return code)
51
+ '''
52
+
53
+ debug(f'subprocess_run_background: {background=} {tee_fpath=} {shell=}')
54
+
55
+ if fake:
56
+ # let subprocess_run handle it (won't run anything)
57
+ rc = subprocess_run(work_dir, command_list, fake=fake, shell=shell)
58
+ return '', '', rc
59
+
60
+ proc_kwargs = {'shell': shell,
61
+ 'stdout': subprocess.PIPE,
62
+ 'stderr': subprocess.STDOUT,
63
+ }
64
+ if work_dir:
65
+ proc_kwargs['cwd'] = work_dir
66
+
67
+ bash_exec = shutil.which('bash')
68
+ if shell and bash_exec and not IS_WINDOWS:
69
+ # Note - windows powershell will end up calling: /bin/bash /c, which won't work
70
+ proc_kwargs.update({'executable': bash_exec})
71
+
72
+ if not IS_WINDOWS and shell:
73
+ c = ' '.join(command_list)
74
+ else:
75
+ c = command_list # leave as list.
76
+
77
+ debug(f"subprocess_run_background: about to call subprocess.Popen({c}, **{proc_kwargs})")
78
+ proc = subprocess.Popen(c, **proc_kwargs) # pylint: disable=consider-using-with
79
+
80
+ stdout = ''
81
+ tee_fpath_f = None
82
+ if tee_fpath:
83
+ tee_fpath = os.path.join(work_dir, tee_fpath)
84
+ try:
85
+ tee_fpath_f = open( # pylint: disable=consider-using-with
86
+ tee_fpath, 'w', encoding='utf-8'
87
+ )
88
+ except Exception as e:
89
+ error(f'Unable to open file "{tee_fpath}" for writing, {e}')
90
+
91
+ for line in iter(proc.stdout.readline, b''):
92
+ line = line.rstrip().decode("utf-8", errors="replace")
93
+ if not background:
94
+ print(line)
95
+ if tee_fpath_f:
96
+ tee_fpath_f.write(line + '\n')
97
+ if global_log.file:
98
+ global_log.write(line, '\n')
99
+ stdout += line + '\n'
100
+
101
+ proc.communicate()
102
+ rc = proc.returncode
103
+ if tee_fpath_f:
104
+ tee_fpath_f.write(f'INFO: [{progname}] subprocess_run_background: returncode={rc}\n')
105
+ tee_fpath_f.close()
106
+ info('subprocess_run_background: wrote: ' + os.path.abspath(tee_fpath))
107
+
108
+ return stdout, '', rc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.47
3
+ Version: 0.2.49
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
@@ -0,0 +1,88 @@
1
+ opencos/__init__.py,sha256=RwJA9oc1uUlvNX7v5zoqwjnSRNq2NZwRlHqtS-ICJkI,122
2
+ opencos/_version.py,sha256=XiHFZjCofkkZvI9befTFKsRt5zLouUo1CIwhW4srWU0,582
3
+ opencos/_waves_pkg.sv,sha256=1lbhQOVGc3t_R8czYjP40hssP0I3FlZOpHTkI7yKFbI,1251
4
+ opencos/deps_schema.py,sha256=pdJpKmfXxCYZsfXTxsnACw-s6Mzk55QH06ZSA5uqPV0,15454
5
+ opencos/eda.py,sha256=y53bScMokPfpbZfqzpSg9Q08U6GVF_BjW2P0bPiEBE0,20424
6
+ opencos/eda_base.py,sha256=GOgJN68SlW4R8f6tTpG6eiI5lyZpd1jLE0gbs0yeZeo,93660
7
+ opencos/eda_config.py,sha256=3xdaTdOx59myfqxAJV5Ji_jodRU_MhIqyQdiQXuX2Ls,11246
8
+ opencos/eda_config_defaults.yml,sha256=AteZbwRJ6wviinks47-e5TX0DoU0culJfBw6L3xYOOA,11535
9
+ opencos/eda_config_max_verilator_waivers.yml,sha256=lTAU4IOEbUWVlPzuer1YYhIyxpPINeA4EJqcRIT-Ymk,840
10
+ opencos/eda_config_reduced.yml,sha256=cQ9jY4J7EvAbeHTiP6bvpDSVJAYiitjLZPSxxLKIEbk,1440
11
+ opencos/eda_deps_bash_completion.bash,sha256=jMkQKY82HBgOnQeMdA1hMrXguRFtB52SMBxUemKovL4,1958
12
+ opencos/eda_extract_targets.py,sha256=dvBjc2qFBJkwlW6Fm-66Y_vlr0VZL1QwfIosMR_bgbY,4814
13
+ opencos/eda_tool_helper.py,sha256=_YgobDLEWW6Fzdr976LxaCDZ4DKRyuMs5CrYQHaTPrU,2558
14
+ opencos/export_helper.py,sha256=ArsM8qxBc08gj9S-UholGU417POfBYb_cHkBQZEfqfI,22046
15
+ opencos/export_json_convert.py,sha256=tSIMbLFtc_Fo66EhFovMii1v_qJYyFZJrPNnoPdW7L0,4182
16
+ opencos/files.py,sha256=aoq0O2KfISzZb-Vi_q_0TTGBER9xJc--FkVZf0ga7pA,1549
17
+ opencos/names.py,sha256=iC37PV7Pz0PicTDg09vbQ9NXAj-5m6RKrWHkkcHB8As,1145
18
+ opencos/peakrdl_cleanup.py,sha256=vHNGtalTrIVP335PhRjPt9RhoccgpK1HJAi-E4M8Kc8,736
19
+ opencos/seed.py,sha256=IL9Yg-r9SLSRseMVWaEHmuw2_DNi_eyut11EafoNTsU,942
20
+ opencos/util.py,sha256=w7nZIzvb25aezemAlMWaUgaYg6IshikpfLEGEOrmM3g,27874
21
+ opencos/commands/__init__.py,sha256=DtOA56oWJu68l-_1_7Gdv0N-gtXVB3-p9IhGzAYex8U,1014
22
+ opencos/commands/build.py,sha256=jI5ul53qfwn6X-yfSdSQIcLBhGtzZUk7r_wKBBmKJI0,1425
23
+ opencos/commands/elab.py,sha256=m6Gk03wSzX8UkcmReooK7turF7LpqO0IcdOZwJ8XiyI,1596
24
+ opencos/commands/export.py,sha256=juzxJL5-RpEnU5DmwF0fiG5pUrB2BbUbvCp2OasEd88,3494
25
+ opencos/commands/flist.py,sha256=OUu_ewTDLkZqdW4547iRrwOhT4ghm8oMYHsA63yChvo,8551
26
+ opencos/commands/lec.py,sha256=gN6nQ4GURhPC8nu8Zuj08s1fmNzuiuaS9vJgtNZyX28,3647
27
+ opencos/commands/multi.py,sha256=mBpsx6GaYyT_1KrOgiLu7303uYO5wyLVl56nrw1eiLw,27231
28
+ opencos/commands/open.py,sha256=unrpGckzg0FE5W3oARq8x0jX7hhV_uM9Oh5FgISHFAg,724
29
+ opencos/commands/proj.py,sha256=MdHTOtQYG93_gT97dWuSyAgUxX2vi9FRhL0dtc-rM98,1096
30
+ opencos/commands/shell.py,sha256=senuqSGOc5nVGU5voZNJO4_hzVAK0ELtu0wmRZgwv3k,7463
31
+ opencos/commands/sim.py,sha256=oZyc4thCWZAk4668bbehRBzbOOVQDhyoDyemlDwYPFg,14059
32
+ opencos/commands/sweep.py,sha256=ni4XFgnFF8HLXtwPhETyLWfvc2kgtm4bcxFcKzUhkf0,9343
33
+ opencos/commands/synth.py,sha256=quB-HWS4LKYTiFBHiYarQi4pMnRmt12wQTZpi14VvlE,4355
34
+ opencos/commands/targets.py,sha256=_jRNhm2Fqj0fmMvTw6Ba39DCsRHf_r_uZCy_R064kpA,1472
35
+ opencos/commands/upload.py,sha256=nlb4nlxrDCQPcabEmH3nP19g4PFILDqFDab4LwJ95Z4,796
36
+ opencos/commands/waves.py,sha256=dsWwtjpDgH-YsiIjJgqTvteY3OZ48UnEAWc3blV2Fog,7055
37
+ opencos/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ opencos/deps/defaults.py,sha256=4VgTRXf0hSJrj4tMk0t-mmvgEaaQQFDIYrxWrcKfYWk,1241
39
+ opencos/deps/deps_commands.py,sha256=OlqueYFK8U83loasok3xJGzUDpNcj2DPk37332DfmRo,17039
40
+ opencos/deps/deps_file.py,sha256=QvJ1fMyoQOXNbvHjWevkYF2kx0zvbRgFZ3GAPWw8jqk,12997
41
+ opencos/deps/deps_processor.py,sha256=NYGBrBAmk7ltrvxsEhv76Kpp76GBRJqeNNY_ckWf5mE,33028
42
+ opencos/hw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ opencos/hw/oc_cli.py,sha256=QBmf05VooB9kQFzgliak7PEvqVLTSEI3v6deV1OZQEs,132252
44
+ opencos/hw/pcie.py,sha256=VUJljaZJYgScAAx5yn7F6GoA8K9eTcw24otYZbkMpYs,3035
45
+ opencos/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ opencos/tests/custom_config.yml,sha256=TRoVM9ZFKPOA_8JmlpzaMhnGO1txmaD14N_8P1oqzew,257
47
+ opencos/tests/helpers.py,sha256=T621N2TPuqSg_kPeU2WbuP9oES_1RQ1poCHlOtVXyGo,8921
48
+ opencos/tests/test_build.py,sha256=FQAxOpLVQShAHD_L5rqJctPeSAoqoOCNFI0RXflLuY0,387
49
+ opencos/tests/test_deps_helpers.py,sha256=f9GJXvzcdE3SGkKJ7q-YBTgRagZcIzeRa6nMVCCiEvI,7848
50
+ opencos/tests/test_deps_schema.py,sha256=T3P9KjaMyKsk8b7snNVvNSsom2hIJcg6Z9apYiXoH9Y,941
51
+ opencos/tests/test_eda.py,sha256=bg7SjSVCJSJ2lk51ddfjuVckMOps6_HU-3tCwAIRO7c,39198
52
+ opencos/tests/test_eda_elab.py,sha256=ftW6eQG2KcqndpHK586gXZZs8mEKQedQw12tJ7tYGwQ,2640
53
+ opencos/tests/test_eda_synth.py,sha256=LOM8CKpNyjka_sKS2c00YObOAQeVgpRmuM12Bn-PHqU,5234
54
+ opencos/tests/test_oc_cli.py,sha256=w-F-LjSSWVql3D2WG8tcV4_C52i-hL_2WT3oDpKQn9s,734
55
+ opencos/tests/test_tools.py,sha256=-Wfvt6ARt2WLJ-9Yr88NlwmGWZhnw06Mfrv0100IGS8,5267
56
+ opencos/tests/deps_files/command_order/DEPS.yml,sha256=vloOzWZ5qU3yGNFaDlrAJdEzYxK6qf8gfac3zqF-0FI,438
57
+ opencos/tests/deps_files/error_msgs/DEPS.yml,sha256=fYvHouIscOlr8V28bqx9SoxRBpDBLX4AG-AkVXh8qbo,717
58
+ opencos/tests/deps_files/iverilog_test/DEPS.yml,sha256=vDylEuLt642lhRSvOr3F5ziB5lhPSwkaUGN4_mWJw-c,40
59
+ opencos/tests/deps_files/no_deps_here/DEPS.yml,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ opencos/tests/deps_files/non_sv_reqs/DEPS.yml,sha256=VZkahO1AKhD9GUV5lK8VwUONEi5NesfNfMYOzKk7keU,1006
61
+ opencos/tests/deps_files/tags_with_tools/DEPS.yml,sha256=-5U1qfJElgpVhmkLEu3lYuvDYva8kDlt6JOdB9jidmc,1377
62
+ opencos/tests/deps_files/test_err_fatal/DEPS.yml,sha256=GnXIUJvshQWR9PlYxX67T53ejf5KhDbtD8sUJB4Rwd0,95
63
+ opencos/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ opencos/tools/invio.py,sha256=q9E9n6xsozDfar-1rLvJEZbCpPb_bQEy6WKEI3KS3dk,3163
65
+ opencos/tools/invio_helpers.py,sha256=1au4CYmV5aC7DHjaZBNemydH6Eq0i-Yt5L3HyKfQOfY,7638
66
+ opencos/tools/invio_yosys.py,sha256=asSjbdPjBXB76KxNZIhoDRn2DoXKsZEQ1YDX_WBzKiA,6019
67
+ opencos/tools/iverilog.py,sha256=KQV5tiRdM0ZuJOO0q3ZeUmhRyEc-oJggOc6RKIjoH84,6482
68
+ opencos/tools/modelsim_ase.py,sha256=KQtvqBN7HdtsMl2MoMjaS29-_P5RsiB-ooVu1bC37LQ,13289
69
+ opencos/tools/questa.py,sha256=AX_3USyf6eMcssH4b-8WLbCzz-cXYnQzlHvCyL9C7Og,7505
70
+ opencos/tools/riviera.py,sha256=0FKAUvgyUHvJ5z0LOjHV9p3dGF8LI5kj5WLOZXgCDas,10695
71
+ opencos/tools/slang.py,sha256=bK1_EBA-3ZiUtlRMrMTVH58bhMpeipI87TIdB5O1NII,7456
72
+ opencos/tools/slang_yosys.py,sha256=3fyLRRdTXhSppNtUhhUl00oG-cT9TyyPTH6JvasS9ZE,9804
73
+ opencos/tools/surelog.py,sha256=dtj3ApAKoQasnGdg42n9DPgeqoJ5nCuurIkIO3G5ZCY,5011
74
+ opencos/tools/tabbycad_yosys.py,sha256=2LePPgYXBVdsy7YcffPIWN-I0B7queLQ_f_pme2SCGw,7803
75
+ opencos/tools/verilator.py,sha256=k5FMDyohNcJepElMRAoPSdq7r-zmZ6xG_cZb2XmCFb8,18411
76
+ opencos/tools/vivado.py,sha256=a7bUINQDh74WGWUtfGEEH6M_7RgNyC8Yk4lBrkBXl2o,40168
77
+ opencos/tools/yosys.py,sha256=5zn9CeJc6UUuBI1Gk7HD8Y_l4GPa4KcLB7NNYxIQBjY,25648
78
+ opencos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ opencos/utils/markup_helpers.py,sha256=tDaDtV4INEg04Diks1ZXlfOwzyCOGnWqc5aeHnwLoOk,3727
80
+ opencos/utils/str_helpers.py,sha256=DOkwfKJR6aENM3U2BkJ41ELDU5Uj_zyhEfxuaQEcpEY,3352
81
+ opencos/utils/subprocess_helpers.py,sha256=xemAGPey6M0sWY_FElvr-Z0phCfdjaC-znP8FKihPaE,3535
82
+ opencos_eda-0.2.49.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
83
+ opencos_eda-0.2.49.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
84
+ opencos_eda-0.2.49.dist-info/METADATA,sha256=gZQ8X2NXImdrTE6GBmQsaRHvrb5q99bVu2O9VnIpbd8,604
85
+ opencos_eda-0.2.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
86
+ opencos_eda-0.2.49.dist-info/entry_points.txt,sha256=hi6SZHiGGgLrI3KnBCOXDpYOGXYpw-zWBWe5Di39OCw,167
87
+ opencos_eda-0.2.49.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
88
+ opencos_eda-0.2.49.dist-info/RECORD,,
@@ -2,4 +2,4 @@
2
2
  eda = opencos.eda:main_cli
3
3
  eda_deps_schema = opencos.deps_schema:main
4
4
  eda_targets = opencos.eda_extract_targets:main
5
- oc_cli = opencos.oc_cli:main
5
+ oc_cli = opencos.hw.oc_cli:main