opencos-eda 0.3.12__py3-none-any.whl → 0.3.13__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/flist.py +222 -39
- opencos/commands/multi.py +4 -2
- opencos/commands/sim.py +121 -7
- opencos/deps/deps_file.py +4 -1
- opencos/deps_schema.py +2 -2
- opencos/eda.py +12 -9
- opencos/eda_base.py +39 -8
- opencos/eda_config.py +37 -6
- opencos/eda_config_defaults.yml +28 -4
- opencos/eda_tool_helper.py +4 -4
- opencos/tools/cocotb.py +0 -11
- opencos/tools/invio.py +0 -6
- opencos/tools/iverilog.py +16 -16
- opencos/tools/modelsim_ase.py +0 -12
- opencos/tools/quartus.py +21 -1
- opencos/tools/questa.py +0 -14
- opencos/tools/questa_common.py +49 -25
- opencos/tools/questa_fe.py +0 -14
- opencos/tools/questa_fse.py +0 -14
- opencos/tools/riviera.py +54 -24
- opencos/tools/slang.py +12 -9
- opencos/tools/slang_yosys.py +0 -6
- opencos/tools/surelog.py +11 -8
- opencos/tools/tabbycad_yosys.py +1 -7
- opencos/tools/verilator.py +13 -11
- opencos/tools/vivado.py +49 -18
- opencos/tools/yosys.py +1 -3
- opencos/util.py +14 -5
- opencos/utils/str_helpers.py +4 -1
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/METADATA +1 -2
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/RECORD +36 -36
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/WHEEL +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/entry_points.txt +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/top_level.txt +0 -0
opencos/eda_base.py
CHANGED
|
@@ -26,7 +26,8 @@ from opencos import eda_config
|
|
|
26
26
|
|
|
27
27
|
from opencos.util import Colors, safe_emoji
|
|
28
28
|
from opencos.utils.str_helpers import sprint_time, strip_outer_quotes, string_or_space, \
|
|
29
|
-
indent_wrap_long_text, pretty_list_columns_manual, get_terminal_columns
|
|
29
|
+
indent_wrap_long_text, pretty_list_columns_manual, get_terminal_columns, \
|
|
30
|
+
PARAMETER_NAME_RSTR
|
|
30
31
|
from opencos.utils.subprocess_helpers import subprocess_run_background
|
|
31
32
|
from opencos.utils import status_constants
|
|
32
33
|
|
|
@@ -192,6 +193,8 @@ class Tool:
|
|
|
192
193
|
self.args_help = {}
|
|
193
194
|
if getattr(self, 'defines', None) is None:
|
|
194
195
|
self.defines = {}
|
|
196
|
+
if getattr(self, 'config', None) is None:
|
|
197
|
+
self.config = config
|
|
195
198
|
self.args.update({
|
|
196
199
|
'tool': self._TOOL, # Set for all derived classes.
|
|
197
200
|
})
|
|
@@ -261,8 +264,20 @@ class Tool:
|
|
|
261
264
|
)
|
|
262
265
|
|
|
263
266
|
def set_tool_defines(self) -> None:
|
|
264
|
-
'''Derived classes may override, sets any additional defines based on tool.
|
|
265
|
-
|
|
267
|
+
'''Derived classes may override, sets any additional defines based on tool.
|
|
268
|
+
|
|
269
|
+
If overriding, you likely want to call:
|
|
270
|
+
super().set_tool_defines()
|
|
271
|
+
to pick up anything from self.config['tools'] (from the eda_config YAML)
|
|
272
|
+
'''
|
|
273
|
+
if not self._TOOL:
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
_tool_config = self.config.get('tools', {}).get(self._TOOL, {})
|
|
277
|
+
self.defines.update(
|
|
278
|
+
_tool_config.get('defines', {})
|
|
279
|
+
)
|
|
280
|
+
|
|
266
281
|
|
|
267
282
|
|
|
268
283
|
class Command: # pylint: disable=too-many-public-methods,too-many-instance-attributes
|
|
@@ -1501,7 +1516,14 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1501
1516
|
def process_parameter_arg(
|
|
1502
1517
|
self, text: str, pwd: str = os.getcwd()
|
|
1503
1518
|
) -> None:
|
|
1504
|
-
'''Retuns None, parses -G<Name>=<Value> adds to internal self.parameters.
|
|
1519
|
+
'''Retuns None, parses -G<Name>=<Value> adds to internal self.parameters.
|
|
1520
|
+
|
|
1521
|
+
Note that not all tools will allow hierarchy path information when setting
|
|
1522
|
+
parameters. The Queta/Modelsim family can handle -G/Path/To/Name=Value,
|
|
1523
|
+
but other tools may crash.
|
|
1524
|
+
|
|
1525
|
+
Also note - we do not currently accept [0] in the /Path/To/generate[1]/Name=Value
|
|
1526
|
+
'''
|
|
1505
1527
|
|
|
1506
1528
|
# Deal with raw CLI/bash/powershell argparser, strip all outer quotes.
|
|
1507
1529
|
text = strip_outer_quotes(text)
|
|
@@ -1514,14 +1536,14 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1514
1536
|
return
|
|
1515
1537
|
|
|
1516
1538
|
text = text[2:] # strip leading -G
|
|
1517
|
-
m = re.match(
|
|
1539
|
+
m = re.match(rf'^({PARAMETER_NAME_RSTR})$', text)
|
|
1518
1540
|
if m:
|
|
1519
1541
|
k = m.group(1)
|
|
1520
1542
|
util.warning(f"Parameter {k} has no value and will not be applied")
|
|
1521
1543
|
return
|
|
1522
|
-
m = re.match(
|
|
1544
|
+
m = re.match(rf'^({PARAMETER_NAME_RSTR})\=(\S+)$', text)
|
|
1523
1545
|
if not m:
|
|
1524
|
-
m = re.match(
|
|
1546
|
+
m = re.match(rf'^({PARAMETER_NAME_RSTR})\=(\"[^\"]*\")$', text)
|
|
1525
1547
|
if m:
|
|
1526
1548
|
k = m.group(1)
|
|
1527
1549
|
v = m.group(2)
|
|
@@ -1536,7 +1558,11 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1536
1558
|
v = int(v)
|
|
1537
1559
|
except ValueError:
|
|
1538
1560
|
pass
|
|
1561
|
+
util.debug('set parameter Name={k} Value={v}')
|
|
1539
1562
|
self.set_parameter(k, v)
|
|
1563
|
+
else:
|
|
1564
|
+
util.warning(f'Unable to set parameter from token (-G removed): {text}')
|
|
1565
|
+
|
|
1540
1566
|
|
|
1541
1567
|
|
|
1542
1568
|
def process_plusarg( # pylint: disable=too-many-branches
|
|
@@ -1924,19 +1950,24 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
|
|
|
1924
1950
|
m = re.match(r"^\'?\+\w+", token)
|
|
1925
1951
|
if m:
|
|
1926
1952
|
# Copy and strip all outer ' or " on the plusarg:
|
|
1953
|
+
util.debug(f'plusarg found at {token=}')
|
|
1927
1954
|
plusarg = strip_outer_quotes(token)
|
|
1928
1955
|
self.process_plusarg(plusarg, pwd=pwd)
|
|
1929
1956
|
remove_list.append(token)
|
|
1930
1957
|
continue
|
|
1931
1958
|
|
|
1932
1959
|
# Parameters in -G<word>=<something>
|
|
1933
|
-
|
|
1960
|
+
# Parameters in -Gpath.to.<word>=<something>
|
|
1961
|
+
# Parameters in -G/path/to/<word>=<something>
|
|
1962
|
+
m = re.match(rf"^\'?\-G{PARAMETER_NAME_RSTR}\=.+", token)
|
|
1934
1963
|
if m:
|
|
1935
1964
|
# Copy and strip all outer ' or " on the text:
|
|
1965
|
+
util.debug(f'found parameter at {token=}')
|
|
1936
1966
|
param = strip_outer_quotes(token)
|
|
1937
1967
|
self.process_parameter_arg(param, pwd=pwd)
|
|
1938
1968
|
remove_list.append(token)
|
|
1939
1969
|
|
|
1970
|
+
|
|
1940
1971
|
for x in remove_list:
|
|
1941
1972
|
unparsed.remove(x)
|
|
1942
1973
|
|
opencos/eda_config.py
CHANGED
|
@@ -33,6 +33,7 @@ class Defaults:
|
|
|
33
33
|
opencos_config_yml = 'eda_config_defaults.yml'
|
|
34
34
|
config_yml = ''
|
|
35
35
|
config_yml_set_from = ''
|
|
36
|
+
non_default_config_yml_arg_used = ''
|
|
36
37
|
|
|
37
38
|
supported_config_keys = set([
|
|
38
39
|
'DEFAULT_HANDLERS', 'DEFAULT_HANDLERS_HELP',
|
|
@@ -314,11 +315,35 @@ def get_eda_config(args:list, quiet=False) -> (dict, list):
|
|
|
314
315
|
config = None
|
|
315
316
|
|
|
316
317
|
if parsed.config_yml != Defaults.config_yml:
|
|
318
|
+
Defaults.non_default_config_yml_arg_used = parsed.config_yml
|
|
317
319
|
config = get_config_merged_with_defaults(config)
|
|
318
320
|
|
|
319
321
|
return config, unparsed
|
|
320
322
|
|
|
321
323
|
|
|
324
|
+
def get_config_yml_args_for_flist() -> list:
|
|
325
|
+
'''Returns list of args, or empty list. Used by CommandFList when we want to get the args
|
|
326
|
+
|
|
327
|
+
to reproduce a target to be run again in `eda`'''
|
|
328
|
+
ret = []
|
|
329
|
+
|
|
330
|
+
if Defaults.non_default_config_yml_arg_used:
|
|
331
|
+
ret.append(f'--config-yml={Defaults.non_default_config_yml_arg_used}')
|
|
332
|
+
|
|
333
|
+
if Defaults.config_yml_set_from:
|
|
334
|
+
# a default config-yml was used, but it wasn't from eda, was from
|
|
335
|
+
# ENV or HOME dir. This is not included in the flist, so warn about it.
|
|
336
|
+
# Since we don't support > 1 config-yml args, need to warn about this.
|
|
337
|
+
util.warning('Note: for command "flist", picked up',
|
|
338
|
+
f'--config-yml={Defaults.config_yml},',
|
|
339
|
+
f'from: {Defaults.config_yml_set_from}')
|
|
340
|
+
|
|
341
|
+
elif Defaults.config_yml_set_from:
|
|
342
|
+
ret.append(f'--config-yml={Defaults.config_yml}')
|
|
343
|
+
|
|
344
|
+
return ret
|
|
345
|
+
|
|
346
|
+
|
|
322
347
|
def write_eda_config_and_args(
|
|
323
348
|
dirpath : str, filename: str = EDA_OUTPUT_CONFIG_FNAME,
|
|
324
349
|
command_obj_ref: object = None
|
|
@@ -334,16 +359,22 @@ def write_eda_config_and_args(
|
|
|
334
359
|
# Use deep copy b/c otherwise these are references to opencos.eda.
|
|
335
360
|
data[x] = copy.deepcopy(getattr(command_obj_ref, x, ''))
|
|
336
361
|
|
|
337
|
-
# copy util.args
|
|
338
|
-
data['util'] = {
|
|
339
|
-
|
|
340
|
-
|
|
362
|
+
# copy util.args, and other util globals:
|
|
363
|
+
data['util'] = {}
|
|
364
|
+
for x in ['INITIAL_CWD', 'args', 'dot_f_files_expanded', 'env_files_loaded', 'max_error_code']:
|
|
365
|
+
data['util'][x] = getattr(util, x, '')
|
|
366
|
+
|
|
367
|
+
# copy some information about which eda_config YAML was used:
|
|
368
|
+
for member in ['config_yml', 'config_yml_set_from', 'non_default_config_yml_arg_used']:
|
|
369
|
+
data[member] = getattr(Defaults, member, '')
|
|
341
370
|
|
|
342
371
|
# fix some burried class references in command_obj_ref.config,
|
|
343
372
|
# otherwise we won't be able to safe load this yaml, so cast as str repr.
|
|
344
|
-
|
|
373
|
+
config = getattr(command_obj_ref, 'config', {})
|
|
374
|
+
for k, v in config.items():
|
|
345
375
|
if k == 'command_handler':
|
|
346
|
-
data['config'][
|
|
376
|
+
data['config']['command_handler'] = str(v)
|
|
377
|
+
|
|
347
378
|
|
|
348
379
|
yaml_safe_writer(data=data, filepath=fullpath)
|
|
349
380
|
|
opencos/eda_config_defaults.yml
CHANGED
|
@@ -116,6 +116,7 @@ command_determines_tool:
|
|
|
116
116
|
|
|
117
117
|
command_tool_is_optional:
|
|
118
118
|
# eda commands that may not need to use a tool at all, will skip auto_tools_order if --tool=None (default)
|
|
119
|
+
- shell
|
|
119
120
|
- flist
|
|
120
121
|
- export
|
|
121
122
|
- targets
|
|
@@ -254,6 +255,7 @@ tools:
|
|
|
254
255
|
|
|
255
256
|
defines:
|
|
256
257
|
OC_TOOL_SLANG: null
|
|
258
|
+
SLANG: 1
|
|
257
259
|
log-bad-strings:
|
|
258
260
|
- 'Build failed: '
|
|
259
261
|
log-must-strings:
|
|
@@ -273,7 +275,8 @@ tools:
|
|
|
273
275
|
elab: opencos.tools.verilator.VerilatorElab
|
|
274
276
|
sim: opencos.tools.verilator.VerilatorSim
|
|
275
277
|
|
|
276
|
-
defines:
|
|
278
|
+
defines:
|
|
279
|
+
SIMULATION: 1
|
|
277
280
|
log-warning-strings:
|
|
278
281
|
- "%Warning"
|
|
279
282
|
log-bad-strings:
|
|
@@ -382,11 +385,14 @@ tools:
|
|
|
382
385
|
lint: opencos.tools.riviera.CommandLintRiviera
|
|
383
386
|
elab: opencos.tools.riviera.CommandElabRiviera
|
|
384
387
|
sim: opencos.tools.riviera.CommandSimRiviera
|
|
388
|
+
flist: opencos.tools.riviera.CommandFListRiviera
|
|
385
389
|
waves: opencos.commands.waves.CommandWaves
|
|
386
390
|
|
|
387
391
|
defines:
|
|
388
392
|
OC_TOOL_RIVIERA: 1
|
|
389
393
|
RIVIERA: 1
|
|
394
|
+
# see oclib_defines.vh, this is to prevent type comparisons
|
|
395
|
+
OC_TOOL_BROKEN_TYPE_COMPARISON: 1
|
|
390
396
|
log-warning-strings:
|
|
391
397
|
- "Warning: "
|
|
392
398
|
log-bad-strings:
|
|
@@ -396,7 +402,7 @@ tools:
|
|
|
396
402
|
log-must-strings:
|
|
397
403
|
- "VSIM: Simulation has finished"
|
|
398
404
|
compile-args: |
|
|
399
|
-
-echo -sv -input_ports net -
|
|
405
|
+
-echo -sv -input_ports net -dbg +accb +accr +accs +dacc
|
|
400
406
|
compile-coverage-args: |
|
|
401
407
|
-coverage sbecam -coverage_options count
|
|
402
408
|
# -uvm -ovm
|
|
@@ -416,11 +422,14 @@ tools:
|
|
|
416
422
|
lint: opencos.tools.modelsim_ase.CommandLintModelsimAse
|
|
417
423
|
elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
|
|
418
424
|
sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
|
|
425
|
+
flist: opencos.tools.modelsim_ase.CommandFListModelsimAse
|
|
419
426
|
waves: opencos.commands.waves.CommandWaves
|
|
420
427
|
|
|
421
428
|
defines:
|
|
422
429
|
OC_ASSERT_PROPERTY_NOT_SUPPORTED: 1
|
|
423
430
|
OC_TOOL_MODELSIM_ASE: 1
|
|
431
|
+
# see oclib_defines.vh, this is to prevent type comparisons
|
|
432
|
+
OC_TOOL_BROKEN_TYPE_COMPARISON: 1
|
|
424
433
|
log-warning-strings:
|
|
425
434
|
- "Warning: "
|
|
426
435
|
log-bad-strings:
|
|
@@ -457,7 +466,7 @@ tools:
|
|
|
457
466
|
waves: opencos.commands.waves.CommandWaves
|
|
458
467
|
|
|
459
468
|
defines:
|
|
460
|
-
|
|
469
|
+
OC_TOOL_QUESTA_FE: 1
|
|
461
470
|
log-warning-strings:
|
|
462
471
|
- "Warning: "
|
|
463
472
|
log-bad-strings:
|
|
@@ -531,7 +540,7 @@ tools:
|
|
|
531
540
|
waves: opencos.commands.waves.CommandWaves
|
|
532
541
|
|
|
533
542
|
defines:
|
|
534
|
-
|
|
543
|
+
OC_TOOL_QUESTA: 1
|
|
535
544
|
log-warning-strings:
|
|
536
545
|
- "Warning: "
|
|
537
546
|
log-bad-strings:
|
|
@@ -563,6 +572,10 @@ tools:
|
|
|
563
572
|
lint: opencos.tools.iverilog.CommandLintIverilog
|
|
564
573
|
elab: opencos.tools.iverilog.CommandElabIverilog
|
|
565
574
|
sim: opencos.tools.iverilog.CommandSimIverilog
|
|
575
|
+
defines:
|
|
576
|
+
SIMULATION: 1
|
|
577
|
+
IVERILOG: 1
|
|
578
|
+
OC_ASSERT_PROPERTY_NOT_SUPPORTED: 1
|
|
566
579
|
|
|
567
580
|
log-warning-strings:
|
|
568
581
|
- "Warning:"
|
|
@@ -595,6 +608,8 @@ tools:
|
|
|
595
608
|
|
|
596
609
|
defines:
|
|
597
610
|
OC_TOOL_COCOTB: null
|
|
611
|
+
COCOTB: 1
|
|
612
|
+
SIMULATION: 1
|
|
598
613
|
log-warning-strings:
|
|
599
614
|
- "Warning:"
|
|
600
615
|
- "WARNING:"
|
|
@@ -669,6 +684,10 @@ tools:
|
|
|
669
684
|
elab: opencos.tools.slang_yosys.CommandElabSlangYosys
|
|
670
685
|
synth: opencos.tools.slang_yosys.CommandSynthSlangYosys
|
|
671
686
|
lec: opencos.tools.slang_yosys.CommandLecSlangYosys
|
|
687
|
+
defines:
|
|
688
|
+
OC_TOOL_YOSYS: null
|
|
689
|
+
OC_TOOL_SLANG: null
|
|
690
|
+
SLANG: 1
|
|
672
691
|
|
|
673
692
|
tabbycad_yosys:
|
|
674
693
|
exe: yosys
|
|
@@ -676,6 +695,9 @@ tools:
|
|
|
676
695
|
- YOSYSHQ_LICENSE
|
|
677
696
|
handlers:
|
|
678
697
|
synth: opencos.tools.tabbycad_yosys.CommandSynthTabbyCadYosys
|
|
698
|
+
defines:
|
|
699
|
+
OC_TOOL_YOSYS: null
|
|
700
|
+
OC_TOOL_TABBYCAD: null
|
|
679
701
|
|
|
680
702
|
invio_yosys:
|
|
681
703
|
exe: yosys
|
|
@@ -686,6 +708,8 @@ tools:
|
|
|
686
708
|
handlers:
|
|
687
709
|
elab: opencos.tools.invio_yosys.CommandElabInvioYosys
|
|
688
710
|
synth: opencos.tools.invio_yosys.CommandSynthInvioYosys
|
|
711
|
+
OC_TOOL_YOSYS: null
|
|
712
|
+
OC_TOOL_INVIO: null
|
|
689
713
|
|
|
690
714
|
yosys:
|
|
691
715
|
exe: yosys
|
opencos/eda_tool_helper.py
CHANGED
|
@@ -21,7 +21,7 @@ from opencos.utils import str_helpers
|
|
|
21
21
|
def get_config_and_tools_loaded( # pylint: disable=dangerous-default-value
|
|
22
22
|
quiet: bool = False, args: list = []
|
|
23
23
|
) -> (dict, set):
|
|
24
|
-
'''Returns config dict and
|
|
24
|
+
'''Returns config dict and list tools_loaded, given the found config.
|
|
25
25
|
|
|
26
26
|
Can BYO args such as --config-yml=MY_OWN_EDA_CONFIG.yml
|
|
27
27
|
'''
|
|
@@ -34,7 +34,7 @@ def get_config_and_tools_loaded( # pylint: disable=dangerous-default-value
|
|
|
34
34
|
# within eda, etc, if you already have a valid config or tools_loaded.
|
|
35
35
|
eda = import_module("opencos.eda")
|
|
36
36
|
config = eda.init_config(config=config, quiet=quiet)
|
|
37
|
-
tools_loaded = config.get('tools_loaded',
|
|
37
|
+
tools_loaded = config.get('tools_loaded', []).copy()
|
|
38
38
|
|
|
39
39
|
return config, tools_loaded
|
|
40
40
|
|
|
@@ -55,7 +55,7 @@ def get_all_handler_commands(config=None, tools_loaded=None) -> dict:
|
|
|
55
55
|
config, tools_loaded = get_config_and_tools_loaded()
|
|
56
56
|
|
|
57
57
|
assert isinstance(config, dict)
|
|
58
|
-
assert isinstance(tools_loaded,
|
|
58
|
+
assert isinstance(tools_loaded, list)
|
|
59
59
|
|
|
60
60
|
# Let's re-walk auto_tools_order to get this ordered per eda command:
|
|
61
61
|
for command, tools_list in config.get('auto_tools_order', {}).items():
|
|
@@ -130,7 +130,7 @@ def get_handler_info_with_versions( # pylint: disable=too-many-branches
|
|
|
130
130
|
if not config:
|
|
131
131
|
config, tools_loaded = get_config_and_tools_loaded()
|
|
132
132
|
else:
|
|
133
|
-
tools_loaded = list(config.get('tools_loaded',
|
|
133
|
+
tools_loaded = list(config.get('tools_loaded', []))
|
|
134
134
|
|
|
135
135
|
eda_commands = list(config.get('DEFAULT_HANDLERS', {}).keys())
|
|
136
136
|
show_versions = config.get('show_tool_versions', False)
|
opencos/tools/cocotb.py
CHANGED
|
@@ -51,14 +51,6 @@ class ToolCocotb(Tool):
|
|
|
51
51
|
|
|
52
52
|
return ''
|
|
53
53
|
|
|
54
|
-
def set_tool_defines(self):
|
|
55
|
-
super().set_tool_defines()
|
|
56
|
-
self.defines.update({
|
|
57
|
-
'SIMULATION': 1,
|
|
58
|
-
'COCOTB': 1,
|
|
59
|
-
'OC_TOOL_COCOTB': None,
|
|
60
|
-
})
|
|
61
|
-
|
|
62
54
|
|
|
63
55
|
class CommandSimCocotb(CommandSim, ToolCocotb):
|
|
64
56
|
'''CommandSimCocotb is a command handler for: eda sim --tool=cocotb'''
|
|
@@ -103,9 +95,6 @@ class CommandSimCocotb(CommandSim, ToolCocotb):
|
|
|
103
95
|
self.cocotb_test_files = []
|
|
104
96
|
|
|
105
97
|
|
|
106
|
-
def set_tool_defines(self):
|
|
107
|
-
ToolCocotb.set_tool_defines(self)
|
|
108
|
-
|
|
109
98
|
def help( # pylint: disable=dangerous-default-value
|
|
110
99
|
self, tokens: list = [], no_targets: bool = False
|
|
111
100
|
) -> None:
|
opencos/tools/invio.py
CHANGED
|
@@ -26,14 +26,8 @@ class ToolInvio(Tool):
|
|
|
26
26
|
if not spec:
|
|
27
27
|
self.error('"invio" package not in python env')
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
return super().get_versions()
|
|
31
30
|
|
|
32
|
-
def set_tool_defines(self):
|
|
33
|
-
super().set_tool_defines()
|
|
34
|
-
self.defines.update({
|
|
35
|
-
'OC_TOOL_INVIO': None,
|
|
36
|
-
})
|
|
37
31
|
|
|
38
32
|
class CommandElabInvio(CommandElab, ToolInvio):
|
|
39
33
|
'''Command handler for: eda elab --tool=invio'''
|
opencos/tools/iverilog.py
CHANGED
|
@@ -44,14 +44,6 @@ class ToolIverilog(Tool):
|
|
|
44
44
|
self._VERSION = version
|
|
45
45
|
return self._VERSION
|
|
46
46
|
|
|
47
|
-
def set_tool_defines(self):
|
|
48
|
-
# TODO(drew): come back to this, Tool doesn't have self.defines. Command does.
|
|
49
|
-
self.defines.update({
|
|
50
|
-
'SIMULATION': 1,
|
|
51
|
-
'IVERILOG': 1,
|
|
52
|
-
'OC_ASSERT_PROPERTY_NOT_SUPPORTED': 1,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
47
|
|
|
56
48
|
class CommandSimIverilog(CommandSim, ToolIverilog):
|
|
57
49
|
'''CommandSimIverilog is a command handler for: eda sim --tool=iverilog'''
|
|
@@ -128,17 +120,25 @@ class CommandSimIverilog(CommandSim, ToolIverilog):
|
|
|
128
120
|
for value in self.incdirs:
|
|
129
121
|
command_list += [ '-I', value ]
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
123
|
+
if self.args['ext-defines-sv-fname']:
|
|
124
|
+
self.create_ext_defines_sv()
|
|
125
|
+
else:
|
|
126
|
+
for k,v in self.defines.items():
|
|
127
|
+
if v is None:
|
|
128
|
+
command_list += [ '-D', k ]
|
|
129
|
+
else:
|
|
130
|
+
# Generally we should only support int and str python types passed as
|
|
131
|
+
# +define+{k}={v}, but also for SystemVerilog plusargs
|
|
132
|
+
command_list += [ '-D', f'{k}={sanitize_defines_for_sh(v)}' ]
|
|
138
133
|
|
|
139
134
|
# parameters
|
|
135
|
+
# If you do -PName=Value, all parameters in the hierachy with Name will be set,
|
|
136
|
+
# so to only do top level parameters, if hierarchy isn't mentioned in the Name,
|
|
137
|
+
# would need to do -P{self.args['top'].Name=Value
|
|
140
138
|
command_list.extend(
|
|
141
|
-
self.process_parameters_get_list(
|
|
139
|
+
self.process_parameters_get_list(
|
|
140
|
+
arg_prefix='-P', hier_delimiter='.', top_hier_str=f'{self.args["top"]}.'
|
|
141
|
+
)
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
if not self.files_sv and not self.files_v:
|
opencos/tools/modelsim_ase.py
CHANGED
|
@@ -40,18 +40,6 @@ class CommandSimModelsimAse(CommonSimQuesta):
|
|
|
40
40
|
)
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
def set_tool_defines(self):
|
|
44
|
-
# Update any defines from config.tools.modelsim_ase:
|
|
45
|
-
self.defines.update(
|
|
46
|
-
self.tool_config.get(
|
|
47
|
-
'defines',
|
|
48
|
-
# defaults, if not set:
|
|
49
|
-
{'OC_ASSERT_PROPERTY_NOT_SUPPORTED': 1,
|
|
50
|
-
'OC_TOOL_MODELSIM_ASE': 1}
|
|
51
|
-
)
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
43
|
|
|
56
44
|
class CommandElabModelsimAse(CommandSimModelsimAse):
|
|
57
45
|
'''CommandElabModelsimAse is a command handler for: eda elab --tool=modelsim_ase'''
|
opencos/tools/quartus.py
CHANGED
|
@@ -550,9 +550,29 @@ class CommandFListQuartus(CommandFList, ToolQuartus):
|
|
|
550
550
|
CommandFList.__init__(self, config=config)
|
|
551
551
|
ToolQuartus.__init__(self, config=self.config)
|
|
552
552
|
self.args.update({
|
|
553
|
-
'emit
|
|
553
|
+
# synth/project style Flist, can't emit these:
|
|
554
|
+
'emit-parameter': False,
|
|
555
|
+
'emit-plusargs': False,
|
|
554
556
|
})
|
|
555
557
|
|
|
558
|
+
def get_flist_plusargs_list(self) -> list:
|
|
559
|
+
'''Overriden from CommandFList.'''
|
|
560
|
+
if self.args['unprocessed-plusargs']:
|
|
561
|
+
util.warning('Command "flist" for --tool=quartus is not intended for simulation',
|
|
562
|
+
'and plusargs were present. They will NOT be included in the flist:',
|
|
563
|
+
f'{self.args["unprocessed-plusargs"]}')
|
|
564
|
+
|
|
565
|
+
return []
|
|
566
|
+
|
|
567
|
+
def get_flist_parameter_list(self) -> list:
|
|
568
|
+
'''Overriden from CommandFList.'''
|
|
569
|
+
if self.parameters:
|
|
570
|
+
util.warning('Command "flist" for --tool=quartus is not intended for simulation',
|
|
571
|
+
'and parameters were present. They will NOT be included in the flist:',
|
|
572
|
+
f'{self.parameters}')
|
|
573
|
+
|
|
574
|
+
return []
|
|
575
|
+
|
|
556
576
|
|
|
557
577
|
class CommandProjQuartus(CommandProj, ToolQuartus):
|
|
558
578
|
'''CommandProjQuartus is a command handler for: eda proj --tool=quartus'''
|
opencos/tools/questa.py
CHANGED
|
@@ -39,20 +39,6 @@ class CommandSimQuesta(CommonSimQuesta):
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def set_tool_defines(self):
|
|
43
|
-
'''Override from questa.ToolQuesta'''
|
|
44
|
-
# Update any defines from config.tools.questa_fse:
|
|
45
|
-
self.defines.update(
|
|
46
|
-
self.tool_config.get(
|
|
47
|
-
'defines',
|
|
48
|
-
# defaults, if not set:
|
|
49
|
-
{
|
|
50
|
-
'OC_TOOL_QUESTA': 1
|
|
51
|
-
}
|
|
52
|
-
)
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
42
|
class CommandElabQuesta(CommandSimQuesta):
|
|
57
43
|
'''CommandElabQuesta is a command handler for: eda elab --tool=questa'''
|
|
58
44
|
|
opencos/tools/questa_common.py
CHANGED
|
@@ -53,8 +53,10 @@ class ToolQuesta(Tool):
|
|
|
53
53
|
if line.strip().startswith('Release Notes For'):
|
|
54
54
|
m = re.search(r'(\d+)\.(\d+)', line)
|
|
55
55
|
if m:
|
|
56
|
-
self.
|
|
57
|
-
|
|
56
|
+
if self._TOOL.startswith('questa'):
|
|
57
|
+
# don't set these for ModelsimASE:
|
|
58
|
+
self.questa_major = int(m.group(1))
|
|
59
|
+
self.questa_minor = int(m.group(2))
|
|
58
60
|
self._VERSION = str(self.questa_major) + '.' + str(self.questa_minor)
|
|
59
61
|
util.debug(f'version {self._VERSION} ({release_notes_txt_filepath})')
|
|
60
62
|
break
|
|
@@ -101,11 +103,14 @@ class ToolQuesta(Tool):
|
|
|
101
103
|
|
|
102
104
|
return self._VERSION
|
|
103
105
|
|
|
104
|
-
def set_tool_defines(self):
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
def set_tool_defines(self) -> None:
|
|
107
|
+
'''Override from class Tool, which handles picking up config['tools'][self._TOOL]
|
|
108
|
+
|
|
109
|
+
defines. We also set the OC_TOOL_QUESTA_[major]_[minor] if those exist
|
|
110
|
+
'''
|
|
111
|
+
super().set_tool_defines() # Tool, set from config.
|
|
112
|
+
if self.questa_major and self.questa_minor:
|
|
113
|
+
self.defines[f'OC_TOOL_QUESTA_{self.questa_major:d}_{self.questa_minor:d}'] = None
|
|
109
114
|
|
|
110
115
|
|
|
111
116
|
|
|
@@ -250,21 +255,24 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
250
255
|
for value in self.incdirs:
|
|
251
256
|
vlog_dot_f_lines += [ f"+incdir+{value}" ]
|
|
252
257
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
# entire +define+NAME="hi" needs to wrapped in double quotes with the
|
|
260
|
-
# value v double-quotes escaped: "+define+NAME=\"hi\""
|
|
261
|
-
if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
|
|
262
|
-
str_v = v.replace('"', '\\"')
|
|
263
|
-
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
258
|
+
if self.args['ext-defines-sv-fname']:
|
|
259
|
+
self.create_ext_defines_sv()
|
|
260
|
+
else:
|
|
261
|
+
for k,v in self.defines.items():
|
|
262
|
+
if v is None:
|
|
263
|
+
vlog_dot_f_lines += [ f'+define+{k}' ]
|
|
264
264
|
else:
|
|
265
|
-
|
|
266
|
-
#
|
|
267
|
-
|
|
265
|
+
|
|
266
|
+
# if the value v is a double-quoted string, such as v='"hi"', the
|
|
267
|
+
# entire +define+NAME="hi" needs to wrapped in double quotes with the
|
|
268
|
+
# value v double-quotes escaped: "+define+NAME=\"hi\""
|
|
269
|
+
if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
|
|
270
|
+
str_v = v.replace('"', '\\"')
|
|
271
|
+
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
272
|
+
else:
|
|
273
|
+
# Generally we should only support int and str python types passed as
|
|
274
|
+
# +define+{k}={v}, but also for SystemVerilog plusargs
|
|
275
|
+
vlog_dot_f_lines += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
|
|
268
276
|
|
|
269
277
|
|
|
270
278
|
vlog_dot_f_lines += self.args['compile-args']
|
|
@@ -297,10 +305,17 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
297
305
|
# work around this by setting tcl varaibles for each parameter.
|
|
298
306
|
if self.parameters:
|
|
299
307
|
if not self.use_vopt:
|
|
300
|
-
voptargs_str += ' ' + ' '.join(
|
|
308
|
+
voptargs_str += ' ' + ' '.join(
|
|
309
|
+
self.process_parameters_get_list(
|
|
310
|
+
arg_prefix='-G', hier_delimiter='/', top_hier_str=f'/{self.args["top"]}/'
|
|
311
|
+
)
|
|
312
|
+
)
|
|
301
313
|
else:
|
|
302
314
|
for k,v in self.parameters.items():
|
|
303
|
-
s = sim.parameters_dict_get_command_list(
|
|
315
|
+
s = sim.parameters_dict_get_command_list(
|
|
316
|
+
params={k: v}, arg_prefix='', hier_delimiter='/',
|
|
317
|
+
top_hier_str=f'/{self.args["top"]}/'
|
|
318
|
+
)[0]
|
|
304
319
|
# At this point, s should be a str in form {k}={v}
|
|
305
320
|
if not s or '=' not in s:
|
|
306
321
|
continue
|
|
@@ -310,9 +325,12 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
310
325
|
# we'll do:
|
|
311
326
|
# set PARAMETERS(MyParam) "hi bye"
|
|
312
327
|
# vopt -GMyParam=$PARAMETERS(MyParam)
|
|
313
|
-
|
|
328
|
+
parts = s.split('=')
|
|
329
|
+
_name = parts[0]
|
|
330
|
+
_value = '='.join(parts[1:])
|
|
331
|
+
s = f'set PARAMETERS({_name}) {_value}'
|
|
314
332
|
vopt_do_lines.append(s)
|
|
315
|
-
voptargs_str += f' -G{
|
|
333
|
+
voptargs_str += f' -G{_name}=$PARAMETERS({_name}) '
|
|
316
334
|
else:
|
|
317
335
|
voptargs_str += f' -G{s} '
|
|
318
336
|
|
|
@@ -519,3 +537,9 @@ class CommonFListQuesta(CommandFList, ToolQuesta):
|
|
|
519
537
|
def __init__(self, config: dict):
|
|
520
538
|
CommandFList.__init__(self, config=config)
|
|
521
539
|
ToolQuesta.__init__(self, config=self.config)
|
|
540
|
+
self.args.update({
|
|
541
|
+
# an Flist, like vlog.f, cannot support parameters or sim-plusargs, so warn
|
|
542
|
+
# if they are present b/c they will not be emitted.
|
|
543
|
+
'emit-parameter': False,
|
|
544
|
+
'emit-plusargs': False,
|
|
545
|
+
})
|
opencos/tools/questa_fe.py
CHANGED
|
@@ -41,20 +41,6 @@ class CommandSimQuestaFe(CommonSimQuesta):
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def set_tool_defines(self):
|
|
45
|
-
'''Override from questa.ToolQuesta'''
|
|
46
|
-
# Update any defines from config.tools.questa_fse:
|
|
47
|
-
self.defines.update(
|
|
48
|
-
self.tool_config.get(
|
|
49
|
-
'defines',
|
|
50
|
-
# defaults, if not set:
|
|
51
|
-
{
|
|
52
|
-
'OC_TOOL_QUESTA_FE': 1
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
44
|
class CommandElabQuestaFe(CommandSimQuestaFe):
|
|
59
45
|
'''CommandElabQuesta is a command handler for: eda elab --tool=questa_fe'''
|
|
60
46
|
|
opencos/tools/questa_fse.py
CHANGED
|
@@ -38,20 +38,6 @@ class CommandSimQuestaFse(CommonSimQuesta):
|
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def set_tool_defines(self):
|
|
42
|
-
'''Override from questa.ToolQuesta'''
|
|
43
|
-
# Update any defines from config.tools.questa_fse:
|
|
44
|
-
self.defines.update(
|
|
45
|
-
self.tool_config.get(
|
|
46
|
-
'defines',
|
|
47
|
-
# defaults, if not set:
|
|
48
|
-
{
|
|
49
|
-
'OC_TOOL_QUESTA_FSE': 1
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
41
|
class CommandElabQuestaFse(CommandSimQuestaFse):
|
|
56
42
|
'''CommandElabQuestaFse is a command handler for: eda elab --tool=questa_fse'''
|
|
57
43
|
|