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.
Files changed (36) hide show
  1. opencos/commands/flist.py +222 -39
  2. opencos/commands/multi.py +4 -2
  3. opencos/commands/sim.py +121 -7
  4. opencos/deps/deps_file.py +4 -1
  5. opencos/deps_schema.py +2 -2
  6. opencos/eda.py +12 -9
  7. opencos/eda_base.py +39 -8
  8. opencos/eda_config.py +37 -6
  9. opencos/eda_config_defaults.yml +28 -4
  10. opencos/eda_tool_helper.py +4 -4
  11. opencos/tools/cocotb.py +0 -11
  12. opencos/tools/invio.py +0 -6
  13. opencos/tools/iverilog.py +16 -16
  14. opencos/tools/modelsim_ase.py +0 -12
  15. opencos/tools/quartus.py +21 -1
  16. opencos/tools/questa.py +0 -14
  17. opencos/tools/questa_common.py +49 -25
  18. opencos/tools/questa_fe.py +0 -14
  19. opencos/tools/questa_fse.py +0 -14
  20. opencos/tools/riviera.py +54 -24
  21. opencos/tools/slang.py +12 -9
  22. opencos/tools/slang_yosys.py +0 -6
  23. opencos/tools/surelog.py +11 -8
  24. opencos/tools/tabbycad_yosys.py +1 -7
  25. opencos/tools/verilator.py +13 -11
  26. opencos/tools/vivado.py +49 -18
  27. opencos/tools/yosys.py +1 -3
  28. opencos/util.py +14 -5
  29. opencos/utils/str_helpers.py +4 -1
  30. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/METADATA +1 -2
  31. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/RECORD +36 -36
  32. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/WHEEL +0 -0
  33. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/entry_points.txt +0 -0
  34. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/licenses/LICENSE +0 -0
  35. {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.13.dist-info}/licenses/LICENSE.spdx +0 -0
  36. {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
- return
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(r'^(\w+)$', text)
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(r'^(\w+)\=(\S+)$', text)
1544
+ m = re.match(rf'^({PARAMETER_NAME_RSTR})\=(\S+)$', text)
1523
1545
  if not m:
1524
- m = re.match(r'^(\w+)\=(\"[^\"]*\")$', text)
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
- m = re.match(r"^\'?\-G\w+\=.+", token)
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
- 'args': util.args
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
- for k, v in getattr(command_obj_ref, 'config', {}).items():
373
+ config = getattr(command_obj_ref, 'config', {})
374
+ for k, v in config.items():
345
375
  if k == 'command_handler':
346
- data['config'][k] = str(v)
376
+ data['config']['command_handler'] = str(v)
377
+
347
378
 
348
379
  yaml_safe_writer(data=data, filepath=fullpath)
349
380
 
@@ -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 -lcu -dbg +accb +accr +accs +dacc
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
- OC_TOOL_QUESTA_FSE: 1
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
- OC_TOOL_QUESTA_FSE: 1
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
@@ -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 set tools_loaded, given the found config.
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', set()).copy()
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, set)
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', set()))
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
- for k,v in self.defines.items():
132
- if v is None:
133
- command_list += [ '-D', k ]
134
- else:
135
- # Generally we should only support int and str python types passed as
136
- # +define+{k}={v}, but also for SystemVerilog plusargs
137
- command_list += [ '-D', f'{k}={sanitize_defines_for_sh(v)}' ]
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(arg_prefix=f'-P{self.args["top"]}.')
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:
@@ -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-parameter': False
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
 
@@ -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.questa_major = int(m.group(1))
57
- self.questa_minor = int(m.group(2))
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
- # Will only be called from an object which also inherits from CommandDesign,
106
- # i.e. has self.defines
107
- self.defines['OC_TOOL_QUESTA'] = None
108
- self.defines[f'OC_TOOL_QUESTA_{self.questa_major:d}_{self.questa_minor:d}'] = None
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
- for k,v in self.defines.items():
254
- if v is None:
255
- vlog_dot_f_lines += [ f'+define+{k}' ]
256
- else:
257
-
258
- # if the value v is a double-quoted string, such as v='"hi"', the
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
- # Generally we should only support int and str python types passed as
266
- # +define+{k}={v}, but also for SystemVerilog plusargs
267
- vlog_dot_f_lines += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
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(self.process_parameters_get_list(arg_prefix='-G'))
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(params={k: v}, arg_prefix='')[0]
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
- s = s.replace(f'{k}=', f'set PARAMETERS({k}) ')
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{k}=$PARAMETERS({k}) '
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
+ })
@@ -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
 
@@ -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