opencos-eda 0.2.49__py3-none-any.whl → 0.2.51__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencos/commands/lec.py +7 -4
- opencos/commands/multi.py +1 -1
- opencos/commands/shell.py +11 -8
- opencos/commands/sim.py +43 -22
- opencos/deps/deps_file.py +67 -14
- opencos/eda.py +15 -3
- opencos/eda_base.py +54 -20
- opencos/eda_config.py +6 -0
- opencos/eda_config_defaults.yml +36 -14
- opencos/eda_deps_sanitize.py +73 -0
- opencos/tests/test_eda_elab.py +2 -1
- opencos/tests/test_tools.py +1 -0
- opencos/tools/modelsim_ase.py +22 -0
- opencos/tools/questa.py +5 -3
- opencos/tools/questa_fse.py +59 -0
- opencos/tools/slang.py +8 -2
- opencos/tools/verilator.py +25 -0
- opencos/tools/vivado.py +33 -26
- opencos/tools/yosys.py +21 -5
- opencos/util.py +183 -8
- opencos/utils/markup_helpers.py +31 -2
- opencos/utils/status_constants.py +27 -0
- opencos/utils/vsim_helper.py +55 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/METADATA +1 -1
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/RECORD +30 -26
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/entry_points.txt +1 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/WHEEL +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.2.49.dist-info → opencos_eda-0.2.51.dist-info}/top_level.txt +0 -0
opencos/util.py
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
'''opencos.util -- support global logging, argparser for printing (colors)'''
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import argparse
|
|
4
|
+
import atexit
|
|
5
5
|
import datetime
|
|
6
|
+
import json
|
|
6
7
|
import os
|
|
7
|
-
import
|
|
8
|
-
import atexit
|
|
8
|
+
import re
|
|
9
9
|
import shutil
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import time
|
|
10
13
|
import traceback
|
|
11
|
-
import argparse
|
|
12
|
-
import re
|
|
13
14
|
|
|
15
|
+
from enum import Enum
|
|
16
|
+
from pathlib import Path
|
|
14
17
|
from importlib import import_module
|
|
15
18
|
|
|
19
|
+
from opencos.utils import status_constants
|
|
20
|
+
|
|
16
21
|
global_exit_allowed = False # pylint: disable=invalid-name
|
|
17
22
|
progname = "UNKNOWN" # pylint: disable=invalid-name
|
|
18
23
|
progname_in_message = True # pylint: disable=invalid-name
|
|
@@ -26,8 +31,11 @@ args = { # pylint: disable=invalid-name
|
|
|
26
31
|
'fancy' : sys.stdout.isatty(),
|
|
27
32
|
'warnings' : 0,
|
|
28
33
|
'errors' : 0,
|
|
34
|
+
'artifacts-json': True,
|
|
29
35
|
}
|
|
30
36
|
|
|
37
|
+
max_error_code = 0 # pylint: disable=invalid-name
|
|
38
|
+
|
|
31
39
|
class Colors:
|
|
32
40
|
'''Namespace class for color printing help'''
|
|
33
41
|
red = "\x1B[31m"
|
|
@@ -70,6 +78,141 @@ def yellow_text(text: str) -> str:
|
|
|
70
78
|
return Colors.yellow + text + Colors.normal
|
|
71
79
|
return text
|
|
72
80
|
|
|
81
|
+
class ArtifactTypes(Enum):
|
|
82
|
+
'''Types that are allow-listed for artifacts.add* methods. If you don't use one of
|
|
83
|
+
these, you'll get a warning'''
|
|
84
|
+
TEXT = 0
|
|
85
|
+
JSON = 1
|
|
86
|
+
YAML = 2
|
|
87
|
+
WAVEFORM = 3
|
|
88
|
+
DOTF = 4
|
|
89
|
+
TCL = 5
|
|
90
|
+
SHELL = 6
|
|
91
|
+
|
|
92
|
+
class Artifacts:
|
|
93
|
+
'''Class to hold file artifacts, for logs generated by EDA, or other artifcats created
|
|
94
|
+
by a specific tool.
|
|
95
|
+
|
|
96
|
+
If enabled, will write out an artifacts.json file upon util.exit()
|
|
97
|
+
'''
|
|
98
|
+
|
|
99
|
+
data = {}
|
|
100
|
+
unresolved_data = {}
|
|
101
|
+
enabled = True
|
|
102
|
+
artifacts_json_filepath = os.path.join('eda.work', 'artifacts.json')
|
|
103
|
+
|
|
104
|
+
def _get_type_str(self, typ: str) -> (bool, str):
|
|
105
|
+
'''Gets the name from ArtifactTypes, and returns tuple of (True, str)
|
|
106
|
+
|
|
107
|
+
if the ArtifactTypes exists, else (False, str.upper())'''
|
|
108
|
+
ret = getattr(ArtifactTypes, typ.upper(), '')
|
|
109
|
+
if ret:
|
|
110
|
+
return True, ret.name.lower()
|
|
111
|
+
return False, typ.lower()
|
|
112
|
+
|
|
113
|
+
def add(self, name: str, typ: str, description: str = '') -> None:
|
|
114
|
+
'''Adds file to artifacts'''
|
|
115
|
+
|
|
116
|
+
if not self.enabled:
|
|
117
|
+
return # artifacts dumping disabled.
|
|
118
|
+
|
|
119
|
+
_, shortname = os.path.split(name)
|
|
120
|
+
if shortname in self.data:
|
|
121
|
+
return # artifact already registered
|
|
122
|
+
|
|
123
|
+
type_exists, type_str = self._get_type_str(typ)
|
|
124
|
+
if not type_exists:
|
|
125
|
+
warning(f'Unknown artifacts {typ=} add for {name=} {description=}')
|
|
126
|
+
|
|
127
|
+
self.data[shortname] = {
|
|
128
|
+
'name': name,
|
|
129
|
+
'type': type_str,
|
|
130
|
+
'size': 0, # will be filled in when JSON written upon exit.
|
|
131
|
+
'description': description,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
def add_extension(
|
|
135
|
+
self, search_paths: list, file_extension: str, typ: str, description: str = ''
|
|
136
|
+
) -> None:
|
|
137
|
+
'''Adds a placeholder for file extensions to add to artifacts
|
|
138
|
+
|
|
139
|
+
For example, when saving a Simulation waves, we may know it's a .fst or .vcd file,
|
|
140
|
+
but we do not know what the testbench SV file has set in $dumpfile(filepath)
|
|
141
|
+
'''
|
|
142
|
+
type_exists, type_str = self._get_type_str(typ)
|
|
143
|
+
if not type_exists:
|
|
144
|
+
warning(f'Unknown artifacts {typ=} add_extension for {search_paths=}',
|
|
145
|
+
f'{file_extension=} {description=}')
|
|
146
|
+
|
|
147
|
+
if isinstance(search_paths, str):
|
|
148
|
+
sp = [search_paths]
|
|
149
|
+
else:
|
|
150
|
+
sp = search_paths
|
|
151
|
+
self.unresolved_data[file_extension] = {
|
|
152
|
+
'search_paths': sp,
|
|
153
|
+
'type': type_str,
|
|
154
|
+
'description': description
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
def set_artifacts_json_dir(self, dirpath: str) -> None:
|
|
158
|
+
'''Sets the artifacts_json_filepath'''
|
|
159
|
+
_, right = os.path.split(self.artifacts_json_filepath)
|
|
160
|
+
self.artifacts_json_filepath = os.path.join(dirpath, right)
|
|
161
|
+
|
|
162
|
+
def reset(self, enable: bool = True) -> None:
|
|
163
|
+
'''Clears internal data (dict). Called by util.process_tokens()'''
|
|
164
|
+
self.data = {}
|
|
165
|
+
self.unresolved_data = {}
|
|
166
|
+
self.enabled = enable or args['artifacts-json']
|
|
167
|
+
self.artifacts_json_filepath = os.path.join('eda.work', 'artifacts.json')
|
|
168
|
+
|
|
169
|
+
def _resolve_unresolved_data(self, ext: str) -> None:
|
|
170
|
+
'''Find files for this extension that were registered using add_extension(...)
|
|
171
|
+
|
|
172
|
+
adds to self.data'''
|
|
173
|
+
entry = self.unresolved_data[ext]
|
|
174
|
+
if not entry:
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
for search_path in entry['search_paths']:
|
|
178
|
+
p = Path(search_path)
|
|
179
|
+
for posix_filename in p.glob(f'*.{ext}'):
|
|
180
|
+
self.add(
|
|
181
|
+
name=str(posix_filename), typ=entry['type'], description=entry['description']
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
def write_json(self) -> None:
|
|
185
|
+
'''Write out the artifacts.json file, called by util.exit()'''
|
|
186
|
+
|
|
187
|
+
if not self.enabled:
|
|
188
|
+
return # artifacts dumping disabled.
|
|
189
|
+
|
|
190
|
+
if self.unresolved_data:
|
|
191
|
+
for ext in self.unresolved_data:
|
|
192
|
+
self._resolve_unresolved_data(ext)
|
|
193
|
+
|
|
194
|
+
if not self.data:
|
|
195
|
+
return # do nothing if we have no artifacts
|
|
196
|
+
|
|
197
|
+
# Update all file sizes:
|
|
198
|
+
remove_keys = set()
|
|
199
|
+
for key, entry in self.data.items():
|
|
200
|
+
if os.path.isfile(entry['name']):
|
|
201
|
+
entry['size'] = os.path.getsize(entry['name'])
|
|
202
|
+
else:
|
|
203
|
+
# file doesn't exist, remove it from artifacts.
|
|
204
|
+
warning(f'Removing {key} ({entry["name"]}) from artifacts (file does not exist)')
|
|
205
|
+
remove_keys.add(key)
|
|
206
|
+
for key in remove_keys:
|
|
207
|
+
del self.data[key]
|
|
208
|
+
|
|
209
|
+
with open(self.artifacts_json_filepath, 'w', encoding='utf-8') as f:
|
|
210
|
+
json.dump(self.data, f, indent=4)
|
|
211
|
+
info(f'Wrote artifacts JSON: {self.artifacts_json_filepath}')
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
artifacts = Artifacts()
|
|
215
|
+
|
|
73
216
|
|
|
74
217
|
class UtilLogger:
|
|
75
218
|
'''Class for the util.global_log'''
|
|
@@ -81,6 +224,7 @@ class UtilLogger:
|
|
|
81
224
|
# util's argparser: --no-default-log, --logfile=<name>, or --force-logfile=<name>
|
|
82
225
|
default_log_enabled = False
|
|
83
226
|
default_log_filepath = os.path.join('eda.work', 'eda.log')
|
|
227
|
+
enable = True
|
|
84
228
|
|
|
85
229
|
def clear(self) -> None:
|
|
86
230
|
'''Resets internals'''
|
|
@@ -98,6 +242,9 @@ class UtilLogger:
|
|
|
98
242
|
|
|
99
243
|
def start(self, filename: str, force: bool = False) -> None:
|
|
100
244
|
'''Starts (opens) log'''
|
|
245
|
+
if not self.enable:
|
|
246
|
+
self.file = None
|
|
247
|
+
return
|
|
101
248
|
if not filename:
|
|
102
249
|
error('Trying to start a logfile, but filename is missing')
|
|
103
250
|
return
|
|
@@ -115,6 +262,8 @@ class UtilLogger:
|
|
|
115
262
|
debug(f"Opened logfile '{filename}' for writing")
|
|
116
263
|
self.filepath = filename
|
|
117
264
|
self.write_timestamp(f'start - {self.filepath}')
|
|
265
|
+
# add to global artifacts:
|
|
266
|
+
artifacts.add(name=filename, typ='text', description='EDA stdout logfile')
|
|
118
267
|
except Exception as e:
|
|
119
268
|
error(f"Error opening '{filename}' for writing, {e}")
|
|
120
269
|
self.clear()
|
|
@@ -213,6 +362,8 @@ def get_argparser() -> argparse.ArgumentParser:
|
|
|
213
362
|
parser.add_argument('--no-respawn', action='store_true',
|
|
214
363
|
help=('Legacy mode (default respawn disabled) for respawning eda.py'
|
|
215
364
|
' using $OC_ROOT/bin'))
|
|
365
|
+
parser.add_argument('--artifacts-json', **bool_action_kwargs,
|
|
366
|
+
help='Store a work-dir/artifacts.json file of known tool output files')
|
|
216
367
|
return parser
|
|
217
368
|
|
|
218
369
|
|
|
@@ -265,18 +416,24 @@ def process_tokens(tokens:list) -> (argparse.Namespace, list):
|
|
|
265
416
|
|
|
266
417
|
debug(f'util.process_tokens: {parsed=} {unparsed=} from {tokens=}')
|
|
267
418
|
|
|
419
|
+
# clear existing artifacts dicts (mostly for pytests repeatedly calling eda.main),
|
|
420
|
+
# set artifacts.enabled based on args['artifacts-json']
|
|
421
|
+
artifacts.reset(enable=parsed.artifacts_json)
|
|
422
|
+
|
|
268
423
|
if parsed.force_logfile:
|
|
269
424
|
start_log(parsed.force_logfile, force=True)
|
|
270
425
|
elif parsed.logfile:
|
|
271
426
|
start_log(parsed.logfile, force=False)
|
|
272
427
|
elif parsed.default_log and \
|
|
428
|
+
not any(x in unparsed for x in ('help', '-h', '--help')) and \
|
|
273
429
|
(parsed.force_logfile is None and parsed.logfile is None):
|
|
274
430
|
# Use a forced logfile in the eda.work/eda.log:
|
|
431
|
+
# avoid this if someone has --help arg not yet parsed.
|
|
275
432
|
start_log(global_log.default_log_filepath, force=True)
|
|
276
433
|
|
|
277
|
-
|
|
278
434
|
parsed_as_dict = vars(parsed)
|
|
279
435
|
for key,value in parsed_as_dict.items():
|
|
436
|
+
key = key.replace('_', '-')
|
|
280
437
|
if value is not None:
|
|
281
438
|
args[key] = value # only update with non-None values to our global 'args' dict
|
|
282
439
|
|
|
@@ -468,7 +625,9 @@ def warning(*text, start: object = None, end: str = '\n') -> None:
|
|
|
468
625
|
|
|
469
626
|
|
|
470
627
|
def error(
|
|
471
|
-
*text,
|
|
628
|
+
*text,
|
|
629
|
+
error_code: int = status_constants.EDA_DEFAULT_ERROR,
|
|
630
|
+
do_exit: bool = True, start: object = None, end: str = '\n'
|
|
472
631
|
) -> int:
|
|
473
632
|
'''Print error messaging (in red if possible).
|
|
474
633
|
|
|
@@ -481,9 +640,12 @@ def error(
|
|
|
481
640
|
|
|
482
641
|
Note these messages append to global logging. Increments global args['errors'] int.
|
|
483
642
|
'''
|
|
643
|
+
global max_error_code # pylint: disable=global-statement
|
|
644
|
+
|
|
484
645
|
if start is None:
|
|
485
646
|
start = "ERROR: " + (f"[{progname}] " if progname_in_message else "")
|
|
486
647
|
args['errors'] += 1
|
|
648
|
+
max_error_code = max(max_error_code, error_code)
|
|
487
649
|
print_red(f"{start}{' '.join(list(text))}", end=end)
|
|
488
650
|
if do_exit:
|
|
489
651
|
if args['debug']:
|
|
@@ -496,10 +658,23 @@ def error(
|
|
|
496
658
|
return abs(int(error_code))
|
|
497
659
|
|
|
498
660
|
|
|
661
|
+
def get_return_code() -> int:
|
|
662
|
+
'''Checks global max_error_code and args['errors']'''
|
|
663
|
+
if args['errors']:
|
|
664
|
+
if max_error_code == 0:
|
|
665
|
+
return 255
|
|
666
|
+
return max_error_code
|
|
667
|
+
return 0
|
|
668
|
+
|
|
669
|
+
|
|
499
670
|
def exit( # pylint: disable=redefined-builtin
|
|
500
671
|
error_code: int = 0, quiet: bool = False
|
|
501
672
|
) -> int:
|
|
502
673
|
'''sys.exit(int) wrapper, returns the error_code if global_exit_allowed=False'''
|
|
674
|
+
|
|
675
|
+
# Save out artifacts file:
|
|
676
|
+
artifacts.write_json()
|
|
677
|
+
|
|
503
678
|
if global_exit_allowed:
|
|
504
679
|
if not quiet:
|
|
505
680
|
info(f"Exiting with {args['warnings']} warnings, {args['errors']} errors")
|
opencos/utils/markup_helpers.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
''' opencos.utils.markup_helpers - function helpers for YAML, TOML reading and writing'''
|
|
2
2
|
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
3
5
|
import re
|
|
4
6
|
import shutil
|
|
5
7
|
import subprocess
|
|
@@ -89,10 +91,37 @@ def yaml_safe_load(filepath: str, only_root_line_numbers:bool = False) -> dict:
|
|
|
89
91
|
|
|
90
92
|
|
|
91
93
|
def yaml_safe_writer(data: dict, filepath: str) -> None:
|
|
92
|
-
'''
|
|
93
|
-
|
|
94
|
+
'''Wrapper for yaml.dump, enforces file extension otherwise warning'''
|
|
95
|
+
_, ext = os.path.splitext(filepath)
|
|
96
|
+
if ext.lower() in ('.yml', '.yaml'):
|
|
94
97
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
95
98
|
yaml.dump(data, f, allow_unicode=True,
|
|
96
99
|
default_flow_style=False, sort_keys=False, encoding='utf-8')
|
|
97
100
|
else:
|
|
98
101
|
warning(f'{filepath=} to be written for this extension not implemented.')
|
|
102
|
+
|
|
103
|
+
def json_writer(data: dict, filepath: str) -> None:
|
|
104
|
+
'''Wrapper for json.dump'''
|
|
105
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
106
|
+
json.dump(data, f, indent=4)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def markup_writer(data: dict, filepath: str) -> None:
|
|
110
|
+
'''Wrapper for yaml_safe_writer or json_writer'''
|
|
111
|
+
_, ext = os.path.splitext(filepath)
|
|
112
|
+
if ext.lower in ('.yml', '.yaml'):
|
|
113
|
+
yaml_safe_writer(data, filepath)
|
|
114
|
+
else:
|
|
115
|
+
json_writer(data, filepath)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def markup_dumper(data: dict, as_yaml: bool = False) -> str:
|
|
119
|
+
'''Returns JSON str; if as_yaml=True returns YAML str, from data'''
|
|
120
|
+
if as_yaml:
|
|
121
|
+
return yaml.dump(
|
|
122
|
+
data=data, allow_unicode=True,
|
|
123
|
+
default_flow_style=False, sort_keys=False
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# else return JSON:
|
|
127
|
+
return str(json.dumps(data, indent=4))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'''opencos.utils.status_constants is a module containing known Error return codes
|
|
2
|
+
|
|
3
|
+
(0 pass, > 0 fail) from eda or other opencos executables.
|
|
4
|
+
'''
|
|
5
|
+
|
|
6
|
+
NO_ERROR = 0
|
|
7
|
+
|
|
8
|
+
PYTHON_EXCEPTION = 1
|
|
9
|
+
|
|
10
|
+
EDA_DEPS_FILE_NOT_FOUND = 10
|
|
11
|
+
EDA_DEPS_TARGET_NOT_FOUND = 11
|
|
12
|
+
|
|
13
|
+
EDA_COMMAND_OR_ARGS_ERROR = 20
|
|
14
|
+
EDA_CONFIG_ERROR = 21
|
|
15
|
+
EDA_COMMAND_MISSING_TOP = 22
|
|
16
|
+
|
|
17
|
+
EDA_SIM_LOG_HAS_BAD_STRING = 30
|
|
18
|
+
EDA_SIM_LOG_MISSING_MUST_STRING = 31
|
|
19
|
+
|
|
20
|
+
EDA_SHELL_LOG_HAS_BAD_STRING = 38
|
|
21
|
+
EDA_SHELL_LOG_MISSING_MUST_STRING = 39
|
|
22
|
+
|
|
23
|
+
EDA_EXEC_NONZERO_RETURN_CODE1 = 41
|
|
24
|
+
EDA_EXEC_NONZERO_RETURN_CODE2 = 42
|
|
25
|
+
EDA_EXEC_NONZERO_RETURN_CODE255 = 255
|
|
26
|
+
|
|
27
|
+
EDA_DEFAULT_ERROR = 255
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'''Because so many tools use the exe vsim, I don't want to run `vsim -version` N times for N
|
|
2
|
+
tools each to figure out if it's full-Questa, Modelsim, QuestaFSE, or Riviera.
|
|
3
|
+
|
|
4
|
+
Instead, eda.py can call this once, and then query if this tool exists when running
|
|
5
|
+
opencos.eda.auto_tool_setup(..)
|
|
6
|
+
'''
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
|
|
11
|
+
from opencos.util import debug
|
|
12
|
+
|
|
13
|
+
vsim_path = shutil.which('vsim')
|
|
14
|
+
|
|
15
|
+
INIT_HAS_RUN = False
|
|
16
|
+
TOOL_IS = {
|
|
17
|
+
'riviera': False,
|
|
18
|
+
'modelsim_ase': False,
|
|
19
|
+
'questa' : False,
|
|
20
|
+
'questa_fse': False
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def init() -> None:
|
|
25
|
+
'''Sets INIT_HAS_RUN=True (only runs once) and one of TOOL_IS[tool] = True'''
|
|
26
|
+
global INIT_HAS_RUN # pylint: disable=global-statement
|
|
27
|
+
|
|
28
|
+
if INIT_HAS_RUN:
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
INIT_HAS_RUN = True
|
|
32
|
+
|
|
33
|
+
if not vsim_path:
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
proc = None
|
|
37
|
+
try:
|
|
38
|
+
proc = subprocess.run([vsim_path, '-version'], capture_output=True, check=False)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
debug(f'vsim -version: exception {e}')
|
|
41
|
+
|
|
42
|
+
if proc is None or proc.returncode != 0:
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
stdout_str_lower = proc.stdout.decode('utf-8', errors='replace').lower()
|
|
47
|
+
|
|
48
|
+
if all(x in stdout_str_lower for x in ('starter', 'modelsim', 'fpga')):
|
|
49
|
+
TOOL_IS['modelsim_ase'] = True
|
|
50
|
+
elif all(x in stdout_str_lower for x in ('starter', 'questa', 'fpga')):
|
|
51
|
+
TOOL_IS['questa_fse'] = True
|
|
52
|
+
elif all(x in stdout_str_lower for x in ('riviera', 'aldec')):
|
|
53
|
+
TOOL_IS['riviera'] = True
|
|
54
|
+
elif 'questa' in stdout_str_lower:
|
|
55
|
+
TOOL_IS['questa'] = True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.51
|
|
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
|
|
@@ -2,13 +2,14 @@ opencos/__init__.py,sha256=RwJA9oc1uUlvNX7v5zoqwjnSRNq2NZwRlHqtS-ICJkI,122
|
|
|
2
2
|
opencos/_version.py,sha256=XiHFZjCofkkZvI9befTFKsRt5zLouUo1CIwhW4srWU0,582
|
|
3
3
|
opencos/_waves_pkg.sv,sha256=1lbhQOVGc3t_R8czYjP40hssP0I3FlZOpHTkI7yKFbI,1251
|
|
4
4
|
opencos/deps_schema.py,sha256=pdJpKmfXxCYZsfXTxsnACw-s6Mzk55QH06ZSA5uqPV0,15454
|
|
5
|
-
opencos/eda.py,sha256=
|
|
6
|
-
opencos/eda_base.py,sha256=
|
|
7
|
-
opencos/eda_config.py,sha256=
|
|
8
|
-
opencos/eda_config_defaults.yml,sha256=
|
|
5
|
+
opencos/eda.py,sha256=rYBt4Qu2y45zdwD4jDx_p3l2u5LMS1nsaGQCP2ZYdwY,20883
|
|
6
|
+
opencos/eda_base.py,sha256=q0uKEzAMzLmqb4jMBcGv7rTpdKnfrhnMZo7MyB8YN8Y,95706
|
|
7
|
+
opencos/eda_config.py,sha256=Xma8w7kBLCNPCSrCKpceieU7GUBv4i54XZlHjnZ95X4,11353
|
|
8
|
+
opencos/eda_config_defaults.yml,sha256=PdR3xHWQIdGeIyCTr2c3W9Vfq9RC1E9HbqiSydyDYZE,12417
|
|
9
9
|
opencos/eda_config_max_verilator_waivers.yml,sha256=lTAU4IOEbUWVlPzuer1YYhIyxpPINeA4EJqcRIT-Ymk,840
|
|
10
10
|
opencos/eda_config_reduced.yml,sha256=cQ9jY4J7EvAbeHTiP6bvpDSVJAYiitjLZPSxxLKIEbk,1440
|
|
11
11
|
opencos/eda_deps_bash_completion.bash,sha256=jMkQKY82HBgOnQeMdA1hMrXguRFtB52SMBxUemKovL4,1958
|
|
12
|
+
opencos/eda_deps_sanitize.py,sha256=SQjvrte9Hv9JesRY0wljvbdC6pAmLCikI-Wdzzy-D04,1939
|
|
12
13
|
opencos/eda_extract_targets.py,sha256=dvBjc2qFBJkwlW6Fm-66Y_vlr0VZL1QwfIosMR_bgbY,4814
|
|
13
14
|
opencos/eda_tool_helper.py,sha256=_YgobDLEWW6Fzdr976LxaCDZ4DKRyuMs5CrYQHaTPrU,2558
|
|
14
15
|
opencos/export_helper.py,sha256=ArsM8qxBc08gj9S-UholGU417POfBYb_cHkBQZEfqfI,22046
|
|
@@ -17,18 +18,18 @@ opencos/files.py,sha256=aoq0O2KfISzZb-Vi_q_0TTGBER9xJc--FkVZf0ga7pA,1549
|
|
|
17
18
|
opencos/names.py,sha256=iC37PV7Pz0PicTDg09vbQ9NXAj-5m6RKrWHkkcHB8As,1145
|
|
18
19
|
opencos/peakrdl_cleanup.py,sha256=vHNGtalTrIVP335PhRjPt9RhoccgpK1HJAi-E4M8Kc8,736
|
|
19
20
|
opencos/seed.py,sha256=IL9Yg-r9SLSRseMVWaEHmuw2_DNi_eyut11EafoNTsU,942
|
|
20
|
-
opencos/util.py,sha256=
|
|
21
|
+
opencos/util.py,sha256=hnE66Mu7Uu-OGdAE5gkJ8nsKc_zUNMptXcuBFkm30wU,33975
|
|
21
22
|
opencos/commands/__init__.py,sha256=DtOA56oWJu68l-_1_7Gdv0N-gtXVB3-p9IhGzAYex8U,1014
|
|
22
23
|
opencos/commands/build.py,sha256=jI5ul53qfwn6X-yfSdSQIcLBhGtzZUk7r_wKBBmKJI0,1425
|
|
23
24
|
opencos/commands/elab.py,sha256=m6Gk03wSzX8UkcmReooK7turF7LpqO0IcdOZwJ8XiyI,1596
|
|
24
25
|
opencos/commands/export.py,sha256=juzxJL5-RpEnU5DmwF0fiG5pUrB2BbUbvCp2OasEd88,3494
|
|
25
26
|
opencos/commands/flist.py,sha256=OUu_ewTDLkZqdW4547iRrwOhT4ghm8oMYHsA63yChvo,8551
|
|
26
|
-
opencos/commands/lec.py,sha256=
|
|
27
|
-
opencos/commands/multi.py,sha256=
|
|
27
|
+
opencos/commands/lec.py,sha256=mIrMKFEZrFYIzvBdffcIyVULx04Cu4-480FB4Y1EiTA,3863
|
|
28
|
+
opencos/commands/multi.py,sha256=dCo4rMIkGT3BtlBhUIAd7r31w8qxeJvybpl4H7DR77o,27225
|
|
28
29
|
opencos/commands/open.py,sha256=unrpGckzg0FE5W3oARq8x0jX7hhV_uM9Oh5FgISHFAg,724
|
|
29
30
|
opencos/commands/proj.py,sha256=MdHTOtQYG93_gT97dWuSyAgUxX2vi9FRhL0dtc-rM98,1096
|
|
30
|
-
opencos/commands/shell.py,sha256=
|
|
31
|
-
opencos/commands/sim.py,sha256=
|
|
31
|
+
opencos/commands/shell.py,sha256=0SNxiNRPD1BO6dK0yxU_iV-8S9UyF4GOWGLL1A_KeVs,7583
|
|
32
|
+
opencos/commands/sim.py,sha256=WPkn_lZqgMPSQTxxT4Qa0qHKMmdHAkt1GXCDw4iD6kI,14723
|
|
32
33
|
opencos/commands/sweep.py,sha256=ni4XFgnFF8HLXtwPhETyLWfvc2kgtm4bcxFcKzUhkf0,9343
|
|
33
34
|
opencos/commands/synth.py,sha256=quB-HWS4LKYTiFBHiYarQi4pMnRmt12wQTZpi14VvlE,4355
|
|
34
35
|
opencos/commands/targets.py,sha256=_jRNhm2Fqj0fmMvTw6Ba39DCsRHf_r_uZCy_R064kpA,1472
|
|
@@ -37,7 +38,7 @@ opencos/commands/waves.py,sha256=dsWwtjpDgH-YsiIjJgqTvteY3OZ48UnEAWc3blV2Fog,705
|
|
|
37
38
|
opencos/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
39
|
opencos/deps/defaults.py,sha256=4VgTRXf0hSJrj4tMk0t-mmvgEaaQQFDIYrxWrcKfYWk,1241
|
|
39
40
|
opencos/deps/deps_commands.py,sha256=OlqueYFK8U83loasok3xJGzUDpNcj2DPk37332DfmRo,17039
|
|
40
|
-
opencos/deps/deps_file.py,sha256=
|
|
41
|
+
opencos/deps/deps_file.py,sha256=29UkOT-UYw5XYYRK7DySmZkgdTj4wnxVQ5SgZVnrrds,15199
|
|
41
42
|
opencos/deps/deps_processor.py,sha256=NYGBrBAmk7ltrvxsEhv76Kpp76GBRJqeNNY_ckWf5mE,33028
|
|
42
43
|
opencos/hw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
44
|
opencos/hw/oc_cli.py,sha256=QBmf05VooB9kQFzgliak7PEvqVLTSEI3v6deV1OZQEs,132252
|
|
@@ -49,10 +50,10 @@ opencos/tests/test_build.py,sha256=FQAxOpLVQShAHD_L5rqJctPeSAoqoOCNFI0RXflLuY0,3
|
|
|
49
50
|
opencos/tests/test_deps_helpers.py,sha256=f9GJXvzcdE3SGkKJ7q-YBTgRagZcIzeRa6nMVCCiEvI,7848
|
|
50
51
|
opencos/tests/test_deps_schema.py,sha256=T3P9KjaMyKsk8b7snNVvNSsom2hIJcg6Z9apYiXoH9Y,941
|
|
51
52
|
opencos/tests/test_eda.py,sha256=bg7SjSVCJSJ2lk51ddfjuVckMOps6_HU-3tCwAIRO7c,39198
|
|
52
|
-
opencos/tests/test_eda_elab.py,sha256=
|
|
53
|
+
opencos/tests/test_eda_elab.py,sha256=VyYiaLLyfJi26FkoN9p_Kb9cMHfY-0u_0Mx1iVpsg-I,2657
|
|
53
54
|
opencos/tests/test_eda_synth.py,sha256=LOM8CKpNyjka_sKS2c00YObOAQeVgpRmuM12Bn-PHqU,5234
|
|
54
55
|
opencos/tests/test_oc_cli.py,sha256=w-F-LjSSWVql3D2WG8tcV4_C52i-hL_2WT3oDpKQn9s,734
|
|
55
|
-
opencos/tests/test_tools.py,sha256
|
|
56
|
+
opencos/tests/test_tools.py,sha256=HEjKm86OMcrZznJMiiDFsDBN8FlBf4LR9egGO1pOh5c,5285
|
|
56
57
|
opencos/tests/deps_files/command_order/DEPS.yml,sha256=vloOzWZ5qU3yGNFaDlrAJdEzYxK6qf8gfac3zqF-0FI,438
|
|
57
58
|
opencos/tests/deps_files/error_msgs/DEPS.yml,sha256=fYvHouIscOlr8V28bqx9SoxRBpDBLX4AG-AkVXh8qbo,717
|
|
58
59
|
opencos/tests/deps_files/iverilog_test/DEPS.yml,sha256=vDylEuLt642lhRSvOr3F5ziB5lhPSwkaUGN4_mWJw-c,40
|
|
@@ -65,24 +66,27 @@ opencos/tools/invio.py,sha256=q9E9n6xsozDfar-1rLvJEZbCpPb_bQEy6WKEI3KS3dk,3163
|
|
|
65
66
|
opencos/tools/invio_helpers.py,sha256=1au4CYmV5aC7DHjaZBNemydH6Eq0i-Yt5L3HyKfQOfY,7638
|
|
66
67
|
opencos/tools/invio_yosys.py,sha256=asSjbdPjBXB76KxNZIhoDRn2DoXKsZEQ1YDX_WBzKiA,6019
|
|
67
68
|
opencos/tools/iverilog.py,sha256=KQV5tiRdM0ZuJOO0q3ZeUmhRyEc-oJggOc6RKIjoH84,6482
|
|
68
|
-
opencos/tools/modelsim_ase.py,sha256=
|
|
69
|
-
opencos/tools/questa.py,sha256=
|
|
69
|
+
opencos/tools/modelsim_ase.py,sha256=rW5YrzLIhZKdbIT2UM60DGmDEHDK3XMlndpBz906cmA,14229
|
|
70
|
+
opencos/tools/questa.py,sha256=bXH_ajMUBBHNUeWTBNWDp2gGyza2vf8xIC6vz5EWiz8,7619
|
|
71
|
+
opencos/tools/questa_fse.py,sha256=WLNvkD57ggI7lQgxYr6h_xmXenh50J_m8o8amhECmpk,1855
|
|
70
72
|
opencos/tools/riviera.py,sha256=0FKAUvgyUHvJ5z0LOjHV9p3dGF8LI5kj5WLOZXgCDas,10695
|
|
71
|
-
opencos/tools/slang.py,sha256=
|
|
73
|
+
opencos/tools/slang.py,sha256=mFw58vhnCTRR9yaQ2zHPlNB5HKSf3Y078XcaVnpLaAc,7798
|
|
72
74
|
opencos/tools/slang_yosys.py,sha256=3fyLRRdTXhSppNtUhhUl00oG-cT9TyyPTH6JvasS9ZE,9804
|
|
73
75
|
opencos/tools/surelog.py,sha256=dtj3ApAKoQasnGdg42n9DPgeqoJ5nCuurIkIO3G5ZCY,5011
|
|
74
76
|
opencos/tools/tabbycad_yosys.py,sha256=2LePPgYXBVdsy7YcffPIWN-I0B7queLQ_f_pme2SCGw,7803
|
|
75
|
-
opencos/tools/verilator.py,sha256=
|
|
76
|
-
opencos/tools/vivado.py,sha256=
|
|
77
|
-
opencos/tools/yosys.py,sha256=
|
|
77
|
+
opencos/tools/verilator.py,sha256=h5VScZyJYxk2cXDRrTTD47C_yAVHuyXv9_p7UL1o5mk,19486
|
|
78
|
+
opencos/tools/vivado.py,sha256=roM0MxrHoNIT_DsUiql1vQFlez2ql4qhwAfB-rGH4Qg,40485
|
|
79
|
+
opencos/tools/yosys.py,sha256=UKWzvc2rSi3J9U2TROqRbmePdBmjskap664giumeRBk,26323
|
|
78
80
|
opencos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
-
opencos/utils/markup_helpers.py,sha256=
|
|
81
|
+
opencos/utils/markup_helpers.py,sha256=A8Ev5UJ4EVKjdcF2g85SQbjdPZR4jGpNqCLaBy_4v7Q,4569
|
|
82
|
+
opencos/utils/status_constants.py,sha256=aQui30ohPCEaWNDh2iujJQ_KQa3plry_rk7uDzS3vWk,603
|
|
80
83
|
opencos/utils/str_helpers.py,sha256=DOkwfKJR6aENM3U2BkJ41ELDU5Uj_zyhEfxuaQEcpEY,3352
|
|
81
84
|
opencos/utils/subprocess_helpers.py,sha256=xemAGPey6M0sWY_FElvr-Z0phCfdjaC-znP8FKihPaE,3535
|
|
82
|
-
|
|
83
|
-
opencos_eda-0.2.
|
|
84
|
-
opencos_eda-0.2.
|
|
85
|
-
opencos_eda-0.2.
|
|
86
|
-
opencos_eda-0.2.
|
|
87
|
-
opencos_eda-0.2.
|
|
88
|
-
opencos_eda-0.2.
|
|
85
|
+
opencos/utils/vsim_helper.py,sha256=2voGRZI2iAQ2Pv2ZI5g2why6xpgig-To8im-LVXtuDU,1517
|
|
86
|
+
opencos_eda-0.2.51.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
87
|
+
opencos_eda-0.2.51.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
|
|
88
|
+
opencos_eda-0.2.51.dist-info/METADATA,sha256=XAX9j35DEWh0nLU7Gt8unosqGzK9dGeqHtGcj8IgK-8,604
|
|
89
|
+
opencos_eda-0.2.51.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
90
|
+
opencos_eda-0.2.51.dist-info/entry_points.txt,sha256=6n1T5NwVYDhN5l1h5zmyT197G4pE0SySDreB0QJzJR0,218
|
|
91
|
+
opencos_eda-0.2.51.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
|
|
92
|
+
opencos_eda-0.2.51.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|