opencos-eda 0.2.48__py3-none-any.whl → 0.2.50__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/__init__.py +4 -2
- opencos/_version.py +10 -7
- opencos/commands/flist.py +8 -7
- opencos/commands/multi.py +14 -15
- opencos/commands/sim.py +5 -0
- opencos/commands/sweep.py +3 -2
- opencos/deps/__init__.py +0 -0
- opencos/deps/defaults.py +69 -0
- opencos/deps/deps_commands.py +419 -0
- opencos/deps/deps_file.py +326 -0
- opencos/deps/deps_processor.py +670 -0
- opencos/deps_schema.py +7 -8
- opencos/eda.py +84 -64
- opencos/eda_base.py +585 -316
- opencos/eda_config.py +85 -14
- opencos/eda_config_defaults.yml +36 -4
- opencos/eda_extract_targets.py +22 -14
- opencos/eda_tool_helper.py +33 -7
- opencos/export_helper.py +166 -86
- opencos/export_json_convert.py +31 -23
- opencos/files.py +2 -1
- opencos/hw/__init__.py +0 -0
- opencos/{oc_cli.py → hw/oc_cli.py} +9 -4
- opencos/names.py +0 -4
- opencos/peakrdl_cleanup.py +13 -7
- opencos/seed.py +19 -11
- opencos/tests/helpers.py +3 -2
- opencos/tests/test_deps_helpers.py +35 -32
- opencos/tests/test_eda.py +36 -29
- opencos/tests/test_eda_elab.py +7 -4
- opencos/tests/test_eda_synth.py +1 -1
- opencos/tests/test_oc_cli.py +1 -1
- opencos/tests/test_tools.py +4 -2
- opencos/tools/iverilog.py +2 -2
- opencos/tools/modelsim_ase.py +24 -2
- opencos/tools/questa.py +5 -3
- opencos/tools/questa_fse.py +57 -0
- opencos/tools/riviera.py +1 -1
- opencos/tools/slang.py +9 -3
- opencos/tools/surelog.py +1 -1
- opencos/tools/verilator.py +26 -1
- opencos/tools/vivado.py +34 -27
- opencos/tools/yosys.py +4 -3
- opencos/util.py +532 -474
- opencos/utils/__init__.py +0 -0
- opencos/utils/markup_helpers.py +98 -0
- opencos/utils/str_helpers.py +111 -0
- opencos/utils/subprocess_helpers.py +108 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/METADATA +1 -1
- opencos_eda-0.2.50.dist-info/RECORD +89 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/entry_points.txt +1 -1
- opencos/deps_helpers.py +0 -1346
- opencos_eda-0.2.48.dist-info/RECORD +0 -79
- /opencos/{pcie.py → hw/pcie.py} +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/WHEEL +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.2.48.dist-info → opencos_eda-0.2.50.dist-info}/top_level.txt +0 -0
opencos/eda_config.py
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
''' opencos.eda_config - handles --config-yml arg, and providing a
|
|
2
|
+
'config' dict for use by opencos.eda, opencos.commands, and opencos.tools
|
|
3
|
+
|
|
4
|
+
Order of precedence for default value of eda arg: --config-yaml:
|
|
5
|
+
1) os.environ.get('EDA_CONFIG_YML', '') -- filepath to an eda_config.yml file
|
|
6
|
+
2) ~/.opencos-eda/EDA_CONFIG.yml
|
|
7
|
+
3) (package pip installed dir for opencos)/eda_config_defaults.yml
|
|
8
|
+
'''
|
|
9
|
+
|
|
10
|
+
import copy
|
|
1
11
|
import os
|
|
2
|
-
import sys
|
|
3
12
|
import argparse
|
|
4
|
-
import mergedeep
|
|
5
13
|
import shutil
|
|
6
14
|
|
|
15
|
+
import mergedeep
|
|
16
|
+
|
|
7
17
|
from opencos import util
|
|
18
|
+
from opencos.utils.markup_helpers import yaml_safe_load, yaml_safe_writer
|
|
8
19
|
|
|
9
20
|
class Defaults:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# 2) ~/.opencos-eda/EDA_CONFIG.yml
|
|
13
|
-
# 3) (package pip installed dir for opencos)/eda_config_defaults.yml
|
|
21
|
+
'''Defaults is a global placeholder for constants and supported features.'''
|
|
22
|
+
|
|
14
23
|
environ_override_config_yml = os.environ.get('EDA_CONFIG_YML', '')
|
|
15
24
|
home_override_config_yml = os.path.join(
|
|
16
25
|
os.environ.get('HOME', ''), '.opencos-eda', 'EDA_CONFIG.yml'
|
|
@@ -56,6 +65,7 @@ class Defaults:
|
|
|
56
65
|
'coverage-args',
|
|
57
66
|
])
|
|
58
67
|
|
|
68
|
+
EDA_OUTPUT_CONFIG_FNAME = 'eda_output_config.yml'
|
|
59
69
|
|
|
60
70
|
if os.path.exists(Defaults.environ_override_config_yml):
|
|
61
71
|
Defaults.config_yml = Defaults.environ_override_config_yml
|
|
@@ -65,9 +75,11 @@ else:
|
|
|
65
75
|
Defaults.config_yml = Defaults.opencos_config_yml
|
|
66
76
|
|
|
67
77
|
|
|
68
|
-
def find_eda_config_yml_fpath(
|
|
78
|
+
def find_eda_config_yml_fpath(
|
|
79
|
+
filename:str, package_search_only=False, package_search_enabled=True
|
|
80
|
+
) -> str:
|
|
69
81
|
'''Locates the filename (.yml) either from fullpath provided or from the sys.path
|
|
70
|
-
opencos package paths.'''
|
|
82
|
+
(pip-installed) opencos-eda package paths.'''
|
|
71
83
|
|
|
72
84
|
# Check fullpath, unless we're only checking the installed pacakge dir.
|
|
73
85
|
if package_search_only:
|
|
@@ -103,6 +115,11 @@ def find_eda_config_yml_fpath(filename:str, package_search_only=False, package_s
|
|
|
103
115
|
|
|
104
116
|
|
|
105
117
|
def check_config(config:dict, filename='') -> None:
|
|
118
|
+
'''Returns None, will util.error(..) if there are issues in 'config'
|
|
119
|
+
|
|
120
|
+
checks for known dict keys and data types, is NOT exhaustive checking.
|
|
121
|
+
'''
|
|
122
|
+
|
|
106
123
|
# sanity checks:
|
|
107
124
|
for key in config:
|
|
108
125
|
if key not in Defaults.supported_config_keys:
|
|
@@ -146,7 +163,7 @@ def update_config_auto_tool_order_for_tool(tool: str, config: dict) -> str:
|
|
|
146
163
|
return tool
|
|
147
164
|
|
|
148
165
|
old_exe = config['auto_tools_order'][0][tool].get('exe', str())
|
|
149
|
-
if
|
|
166
|
+
if isinstance(old_exe, list):
|
|
150
167
|
config['auto_tools_order'][0][tool]['exe'][0] = user_exe
|
|
151
168
|
else:
|
|
152
169
|
config['auto_tools_order'][0][tool]['exe'] = user_exe
|
|
@@ -154,23 +171,33 @@ def update_config_auto_tool_order_for_tool(tool: str, config: dict) -> str:
|
|
|
154
171
|
|
|
155
172
|
|
|
156
173
|
def update_config_auto_tool_order_for_tools(tools: list, config: dict) -> list:
|
|
157
|
-
|
|
174
|
+
'''Given a list of tools and eda_config style 'config' dict, update
|
|
175
|
+
|
|
176
|
+
the auto_tool_order (consumed by opencos.eda when --tool is not specified).
|
|
177
|
+
'''
|
|
178
|
+
ret = []
|
|
158
179
|
for tool in tools:
|
|
159
180
|
ret.append(update_config_auto_tool_order_for_tool(tool, config))
|
|
160
181
|
return ret
|
|
161
182
|
|
|
162
183
|
|
|
163
184
|
def update_config_for_eda_safe(config) -> None:
|
|
185
|
+
'''Set method to update config dict values to run in a "safe" mode'''
|
|
164
186
|
config['dep_command_enables']['shell'] = False
|
|
165
187
|
|
|
166
188
|
|
|
167
189
|
def deps_shell_commands_enabled(config) -> bool:
|
|
190
|
+
'''Get method on config to determine if DEPS.yml shell-style commands are allowed'''
|
|
168
191
|
return config['dep_command_enables']['shell']
|
|
169
192
|
|
|
170
193
|
|
|
171
194
|
def get_config(filename) -> dict:
|
|
195
|
+
'''Given an eda_config_default.yml (or --config-yml=<filename>) return a config
|
|
196
|
+
|
|
197
|
+
dict from the filename.'''
|
|
198
|
+
|
|
172
199
|
fpath = find_eda_config_yml_fpath(filename)
|
|
173
|
-
user_config =
|
|
200
|
+
user_config = yaml_safe_load(fpath)
|
|
174
201
|
check_config(user_config, filename=filename)
|
|
175
202
|
|
|
176
203
|
# The final thing we do is update key 'config-yml' with the full path used.
|
|
@@ -181,6 +208,10 @@ def get_config(filename) -> dict:
|
|
|
181
208
|
|
|
182
209
|
|
|
183
210
|
def get_config_handle_defaults(filename) -> dict:
|
|
211
|
+
'''Given a user provided --config-yml=<filename>, return a merged config with
|
|
212
|
+
|
|
213
|
+
the existing default config.'''
|
|
214
|
+
|
|
184
215
|
user_config = get_config(filename)
|
|
185
216
|
user_config = get_config_merged_with_defaults(user_config)
|
|
186
217
|
return user_config
|
|
@@ -197,19 +228,31 @@ def merge_config(dst_config:dict, overrides_config:dict, additive_strategy=False
|
|
|
197
228
|
|
|
198
229
|
|
|
199
230
|
def get_config_merged_with_defaults(config:dict) -> dict:
|
|
231
|
+
'''Returns a new config that has been merged with the default config.
|
|
232
|
+
|
|
233
|
+
The default config location is based on Defaults.config_yml (env, local, or pip
|
|
234
|
+
installed location)'''
|
|
235
|
+
|
|
200
236
|
default_fpath = find_eda_config_yml_fpath(Defaults.config_yml, package_search_only=True)
|
|
201
|
-
default_config =
|
|
237
|
+
default_config = yaml_safe_load(default_fpath)
|
|
202
238
|
merge_config(default_config, overrides_config=config)
|
|
203
239
|
# This technically mutated updated into default_config, so return that one:
|
|
204
240
|
return default_config
|
|
205
241
|
|
|
242
|
+
|
|
206
243
|
def get_argparser() -> argparse.ArgumentParser:
|
|
207
|
-
|
|
244
|
+
'''Returns an ArgumentParser, handles --config-yml=<filename> arg'''
|
|
245
|
+
parser = argparse.ArgumentParser(
|
|
246
|
+
prog='opencos eda config options', add_help=False, allow_abbrev=False
|
|
247
|
+
)
|
|
208
248
|
parser.add_argument('--config-yml', type=str, default=Defaults.config_yml,
|
|
209
|
-
help=
|
|
249
|
+
help=('YAML filename to use for configuration (default'
|
|
250
|
+
f' {Defaults.config_yml})'))
|
|
210
251
|
return parser
|
|
211
252
|
|
|
253
|
+
|
|
212
254
|
def get_argparser_short_help() -> str:
|
|
255
|
+
'''Returns a shortened help string given for arg --config-yml.'''
|
|
213
256
|
return util.get_argparser_short_help(parser=get_argparser())
|
|
214
257
|
|
|
215
258
|
|
|
@@ -249,3 +292,31 @@ def get_eda_config(args:list, quiet=False) -> (dict, list):
|
|
|
249
292
|
config = get_config_merged_with_defaults(config)
|
|
250
293
|
|
|
251
294
|
return config, unparsed
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def write_eda_config_and_args(
|
|
298
|
+
dirpath : str, filename: str = EDA_OUTPUT_CONFIG_FNAME,
|
|
299
|
+
command_obj_ref: object = None
|
|
300
|
+
) -> None:
|
|
301
|
+
'''Writes and eda_config style dict to dirpath/filename'''
|
|
302
|
+
if command_obj_ref is None:
|
|
303
|
+
return
|
|
304
|
+
fullpath = os.path.join(dirpath, filename)
|
|
305
|
+
data = {}
|
|
306
|
+
for x in ['command_name', 'config', 'target', 'args', 'modified_args', 'defines',
|
|
307
|
+
'incdirs', 'files_v', 'files_sv', 'files_vhd']:
|
|
308
|
+
# Use deep copy b/c otherwise these are references to opencos.eda.
|
|
309
|
+
data[x] = copy.deepcopy(getattr(command_obj_ref, x, ''))
|
|
310
|
+
|
|
311
|
+
# copy util.args
|
|
312
|
+
data['util'] = {
|
|
313
|
+
'args': util.args
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
# fix some burried class references in command_obj_ref.config,
|
|
317
|
+
# otherwise we won't be able to safe load this yaml, so cast as str repr.
|
|
318
|
+
for k, v in getattr(command_obj_ref, 'config', {}).items():
|
|
319
|
+
if k == 'command_handler':
|
|
320
|
+
data['config'][k] = str(v)
|
|
321
|
+
|
|
322
|
+
yaml_safe_writer(data=data, filepath=fullpath)
|
opencos/eda_config_defaults.yml
CHANGED
|
@@ -230,17 +230,39 @@ tools:
|
|
|
230
230
|
compile-args: |
|
|
231
231
|
-sv -svinputport=net -lint
|
|
232
232
|
compile-waivers:
|
|
233
|
-
- 2275 # 2275 - Existing package '
|
|
234
|
-
- 2555 # 2555 - assignment to input port
|
|
233
|
+
- 2275 # 2275 - Existing package 'myname_pkg' will be overwritten.
|
|
234
|
+
- 2555 # 2555 - assignment to input port myname
|
|
235
235
|
- 2583 # 2583 - [SVCHK] - Extra checking for conflicts with always_comb and
|
|
236
236
|
# always_latch variables is done at vopt time.
|
|
237
237
|
simulate-waivers:
|
|
238
|
-
- 3009 # 3009: [TSCALE] - Module '
|
|
238
|
+
- 3009 # 3009: [TSCALE] - Module 'myname' does not have a timeunit/timeprecision
|
|
239
239
|
# specification in effect, but other modules do.
|
|
240
240
|
simulate-waves-args: |
|
|
241
241
|
+acc
|
|
242
242
|
|
|
243
243
|
|
|
244
|
+
questa_fse:
|
|
245
|
+
defines:
|
|
246
|
+
OC_TOOL_QUESTA_FSE: 1
|
|
247
|
+
log-bad-strings:
|
|
248
|
+
- "Error:"
|
|
249
|
+
log-must-strings:
|
|
250
|
+
- " vsim "
|
|
251
|
+
- "Errors: 0"
|
|
252
|
+
compile-args: |
|
|
253
|
+
-sv -svinputport=net -lint
|
|
254
|
+
compile-waivers:
|
|
255
|
+
- 2275 # 2275 - Existing package 'myname_pkg' will be overwritten.
|
|
256
|
+
- 2555 # 2555 - assignment to input port myname
|
|
257
|
+
- 2583 # 2583 - [SVCHK] - Extra checking for conflicts with always_comb and
|
|
258
|
+
# always_latch variables is done at vopt time.
|
|
259
|
+
simulate-waivers:
|
|
260
|
+
- 3009 # 3009: [TSCALE] - Module 'myname' does not have a timeunit/timeprecision
|
|
261
|
+
# specification in effect, but other modules do.
|
|
262
|
+
simulate-waves-args: |
|
|
263
|
+
-voptargs=+acc=bcgnprst
|
|
264
|
+
|
|
265
|
+
|
|
244
266
|
iverilog:
|
|
245
267
|
log-bad-strings:
|
|
246
268
|
- "Error:"
|
|
@@ -303,7 +325,7 @@ auto_tools_order:
|
|
|
303
325
|
# TODO(drew): surelog is disabled from `eda tools-multi`. It is still
|
|
304
326
|
# enabled for `eda [multi] elab --tool surelog`. It does not support
|
|
305
327
|
# type comparisons:
|
|
306
|
-
# if type(
|
|
328
|
+
# if type(myname) == type(othername)
|
|
307
329
|
# [ERR:UH0700] ... Unsupported expression
|
|
308
330
|
# modelsim_ase also doesn't, but it won't fail elab, whereas surelog does.
|
|
309
331
|
surelog:
|
|
@@ -404,6 +426,16 @@ auto_tools_order:
|
|
|
404
426
|
elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
|
|
405
427
|
sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
|
|
406
428
|
|
|
429
|
+
questa_fse: # free student edition, works similar to modelsim_ase
|
|
430
|
+
exe: vsim
|
|
431
|
+
requires_cmd:
|
|
432
|
+
- vsim -version
|
|
433
|
+
requires_in_exe_path:
|
|
434
|
+
- questa_fse
|
|
435
|
+
handlers:
|
|
436
|
+
elab: opencos.tools.questa_fse.CommandElabQuestaFse
|
|
437
|
+
sim: opencos.tools.questa_fse.CommandSimQuestaFse
|
|
438
|
+
|
|
407
439
|
iverilog:
|
|
408
440
|
exe: iverilog
|
|
409
441
|
handlers:
|
opencos/eda_extract_targets.py
CHANGED
|
@@ -8,12 +8,8 @@ targets from DEPS files
|
|
|
8
8
|
import sys
|
|
9
9
|
import os
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
import json
|
|
12
11
|
|
|
13
|
-
import
|
|
14
|
-
import toml
|
|
15
|
-
|
|
16
|
-
from opencos.deps_helpers import get_all_targets
|
|
12
|
+
from opencos.deps.deps_file import get_all_targets
|
|
17
13
|
|
|
18
14
|
PATH_LPREFIX = str(Path('.')) + os.path.sep
|
|
19
15
|
|
|
@@ -32,12 +28,13 @@ def get_terminal_columns():
|
|
|
32
28
|
except OSError:
|
|
33
29
|
# Handle cases where the terminal size cannot be determined (e.g., not in a TTY)
|
|
34
30
|
return 80 # Default to 80 columns
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
|
|
32
|
+
return 80 # else default to 80.
|
|
37
33
|
|
|
38
34
|
|
|
39
35
|
def print_columns_manual(data: list, num_columns: int = 4, auto_columns: bool = True) -> None:
|
|
40
36
|
"""Prints a list of strings in columns, manually aligning them."""
|
|
37
|
+
|
|
41
38
|
if not data:
|
|
42
39
|
print()
|
|
43
40
|
return
|
|
@@ -59,10 +56,12 @@ def print_columns_manual(data: list, num_columns: int = 4, auto_columns: bool =
|
|
|
59
56
|
max_line_len += x + _spacing
|
|
60
57
|
if max_line_len > window_cols:
|
|
61
58
|
# subtract a column (already >= 2):
|
|
62
|
-
|
|
59
|
+
print_columns_manual(data=data, num_columns=num_columns-1, auto_columns=True)
|
|
60
|
+
return
|
|
63
61
|
if max_line_len + max_item_len + _spacing < window_cols:
|
|
64
62
|
# add 1 more column if we're guaranteed to have room.
|
|
65
|
-
|
|
63
|
+
print_columns_manual(data=data, num_columns=num_columns+1, auto_columns=True)
|
|
64
|
+
return
|
|
66
65
|
# else continue
|
|
67
66
|
|
|
68
67
|
# Print data in columns
|
|
@@ -72,21 +71,30 @@ def print_columns_manual(data: list, num_columns: int = 4, auto_columns: bool =
|
|
|
72
71
|
if col_index == num_columns - 1 or i == len(data) - 1:
|
|
73
72
|
print() # New line at the end of a row or end of data
|
|
74
73
|
|
|
74
|
+
|
|
75
75
|
def get_path_and_pattern(partial_path: str = '', base_path=str(Path('.'))) -> (str, str):
|
|
76
76
|
'''Returns tuple of (partial_path, partial_target or filter)'''
|
|
77
|
+
|
|
77
78
|
partial_target = ''
|
|
78
79
|
if not partial_path or partial_path == str(Path('.')):
|
|
79
80
|
partial_path = PATH_LPREFIX
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
|
|
82
|
+
# if the partial path is not an existing file or dir, then treat it as
|
|
83
|
+
# a partial and split it so partial_path/partial_target can be used later.
|
|
84
|
+
if not base_path or base_path == str(Path('.')):
|
|
85
|
+
if not os.path.exists(partial_path):
|
|
86
|
+
partial_path, partial_target = os.path.split(partial_path)
|
|
87
|
+
else:
|
|
88
|
+
if not os.path.exists(os.path.join(base_path, partial_path)):
|
|
89
|
+
partial_path, partial_target = os.path.split(partial_path)
|
|
90
|
+
|
|
91
|
+
# if we have no partial path, use compatible ./
|
|
82
92
|
if not partial_path:
|
|
83
93
|
partial_path = PATH_LPREFIX
|
|
84
94
|
|
|
85
95
|
return partial_path, partial_target
|
|
86
96
|
|
|
87
97
|
|
|
88
|
-
|
|
89
|
-
|
|
90
98
|
def get_targets(partial_paths: list, base_path=str(Path('.'))) -> list:
|
|
91
99
|
'''Returns a list of DEPS keys into pretty columns, using arg
|
|
92
100
|
|
|
@@ -109,7 +117,7 @@ def get_targets(partial_paths: list, base_path=str(Path('.'))) -> list:
|
|
|
109
117
|
error_on_empty_return=False,
|
|
110
118
|
lstrip_path=True
|
|
111
119
|
)
|
|
112
|
-
except:
|
|
120
|
+
except Exception:
|
|
113
121
|
keys = []
|
|
114
122
|
for key in keys:
|
|
115
123
|
targets_set.add(key)
|
opencos/eda_tool_helper.py
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
|
+
''' opencos.eda_tool_helper -- used by pytests and other checks to see if tools are loaded
|
|
2
|
+
|
|
3
|
+
which helps determine if a pytest is runnable for a given tool, or should be skipped.
|
|
4
|
+
Does this without calling `eda` or eda.main(..)
|
|
5
|
+
|
|
6
|
+
Example uses:
|
|
7
|
+
from opencos import eda_tool_helper
|
|
8
|
+
cfg, tools_loaded = eda_tool_helper.get_config_and_tools_loaded()
|
|
9
|
+
assert 'verilator' in tools_loaded
|
|
10
|
+
|
|
11
|
+
'''
|
|
1
12
|
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
13
|
|
|
5
14
|
from opencos import eda, eda_config, util
|
|
6
15
|
|
|
7
16
|
# Used by pytest, so we can skip tests if tools aren't present.
|
|
8
17
|
|
|
9
|
-
def get_config_and_tools_loaded(
|
|
18
|
+
def get_config_and_tools_loaded( # pylint: disable=dangerous-default-value
|
|
19
|
+
quiet: bool = False, args: list = []
|
|
20
|
+
) -> (dict, set):
|
|
21
|
+
'''Returns config dict and set tools_loaded, given the found config.
|
|
22
|
+
|
|
23
|
+
Can BYO args such as --config-yml=MY_OWN_EDA_CONFIG.yml
|
|
24
|
+
'''
|
|
25
|
+
|
|
10
26
|
# We have to figure out what tools are avaiable w/out calling eda.main,
|
|
11
27
|
# so we can get some of these using eda_config.get_eda_config()
|
|
12
28
|
config, _ = eda_config.get_eda_config(args=args, quiet=quiet)
|
|
@@ -14,14 +30,24 @@ def get_config_and_tools_loaded(quiet=False, args=[]):
|
|
|
14
30
|
tools_loaded = config.get('tools_loaded', set()).copy()
|
|
15
31
|
return config, tools_loaded
|
|
16
32
|
|
|
33
|
+
|
|
17
34
|
def get_all_handler_commands(config=None, tools_loaded=None) -> dict:
|
|
18
|
-
|
|
35
|
+
'''Given a config and tools_loaded (or if not supplied uses defaults) returns a dict
|
|
36
|
+
|
|
37
|
+
of { <command>: [list of tools that run that command, in auto-tool-order] }.
|
|
38
|
+
|
|
39
|
+
For example:
|
|
40
|
+
{ "sim": ["verilator", "vivado"],
|
|
41
|
+
"elab": ["slang", "verilator", ...], ...
|
|
42
|
+
}
|
|
43
|
+
'''
|
|
44
|
+
all_handler_commands = {}
|
|
19
45
|
|
|
20
46
|
if config is None or tools_loaded is None:
|
|
21
47
|
config, tools_loaded = get_config_and_tools_loaded()
|
|
22
48
|
|
|
23
|
-
assert
|
|
24
|
-
assert
|
|
49
|
+
assert isinstance(config, dict)
|
|
50
|
+
assert isinstance(tools_loaded, set)
|
|
25
51
|
|
|
26
52
|
# Let's re-walk auto_tools_order to get this ordered per eda command:
|
|
27
53
|
for tool, table in config.get('auto_tools_order', [{}])[0].items():
|
|
@@ -34,7 +60,7 @@ def get_all_handler_commands(config=None, tools_loaded=None) -> dict:
|
|
|
34
60
|
'disable-tools-multi in config')
|
|
35
61
|
continue
|
|
36
62
|
|
|
37
|
-
for command
|
|
63
|
+
for command in table.get('handlers', {}).keys():
|
|
38
64
|
if command not in all_handler_commands:
|
|
39
65
|
# create ordered list from config.
|
|
40
66
|
all_handler_commands[command] = list([tool])
|