opencos-eda 0.2.54__py3-none-any.whl → 0.2.55__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.
@@ -10,6 +10,7 @@ from .elab import CommandElab
10
10
  from .export import CommandExport
11
11
  from .flist import CommandFList
12
12
  from .multi import CommandMulti, CommandToolsMulti
13
+ from .lint import CommandLint
13
14
  from .open import CommandOpen
14
15
  from .proj import CommandProj
15
16
  from .sim import CommandSim
@@ -28,6 +29,7 @@ __all__ = [
28
29
  'CommandExport',
29
30
  'CommandFList',
30
31
  'CommandMulti',
32
+ 'CommandLint',
31
33
  'CommandOpen',
32
34
  'CommandProj',
33
35
  'CommandSim',
@@ -0,0 +1,51 @@
1
+ '''opencos.commands.lint - Base class command handler for: eda lint ...
2
+
3
+ Intended to be overriden by Tool based classes (such as CommandLintVivado, etc)
4
+
5
+ Note that many 'lint' command handlers that also can perform simulations, such
6
+ as VerilatorLint, will instead inherit from VerilatorSim and simply perform a
7
+ shortened sim as the lint, instead of inheriting CommandLint.
8
+
9
+ Tools that don't support a 'sim' command will generally use CommandLint, such
10
+ as CommandLintSlang.'''
11
+
12
+ from opencos.commands.sim import CommandSim
13
+
14
+ class CommandLint(CommandSim):
15
+ '''Base class command handler for: eda lint ...'''
16
+
17
+ command_name = 'lint'
18
+
19
+ def __init__(self, config: dict):
20
+ CommandSim.__init__(self, config=config)
21
+ # add args specific to this simulator
22
+ self.args['stop-after-compile'] = True
23
+ self.args['lint'] = True
24
+ self.args['verilate-args'] = []
25
+
26
+
27
+
28
+ def compile(self) -> None:
29
+ raise NotImplementedError
30
+
31
+ def elaborate(self) -> None:
32
+ raise NotImplementedError
33
+
34
+ def get_compile_command_lists(self, **kwargs) -> list:
35
+ ''' Returns a list of lists (list of command lists).'''
36
+ raise NotImplementedError
37
+
38
+ def get_elaborate_command_lists(self, **kwargs) -> list:
39
+ ''' Returns a list of lists (list of command lists).'''
40
+ raise NotImplementedError
41
+
42
+ # CommandSim methods that elab does not use:
43
+
44
+ def simulate(self):
45
+ pass
46
+
47
+ def get_simulate_command_lists(self, **kwargs) -> list:
48
+ return []
49
+
50
+ def get_post_simulate_command_lists(self, **kwargs) -> list:
51
+ return []
opencos/deps/deps_file.py CHANGED
@@ -306,7 +306,9 @@ class DepsFile:
306
306
  return False
307
307
 
308
308
  if not is_valid_target_name(target_node):
309
- util.warning(f"In file {self.rel_deps_file}, {target_node} {VALID_TARGET_INFO_STR}")
309
+ util.warning(
310
+ f"In file {self.rel_deps_file}, {target_node} {VALID_TARGET_INFO_STR}"
311
+ )
310
312
 
311
313
  if not caller_info:
312
314
  # If we don't have caller_info, likely came from command line (or DEPS JSON data):
opencos/eda.py CHANGED
@@ -23,7 +23,7 @@ from opencos import util, eda_config, eda_base
23
23
  from opencos.eda_base import Tool, which_tool, get_eda_exec
24
24
  from opencos.utils import vsim_helper, vscode_helper
25
25
  from opencos.utils.subprocess_helpers import subprocess_run_background
26
- from opencos.utils import status_constants
26
+ from opencos.utils import status_constants, str_helpers
27
27
 
28
28
  # Configure util:
29
29
  util.progname = "EDA"
@@ -78,7 +78,7 @@ def get_all_commands_help_str(config: dict) -> str:
78
78
  return '\n'.join(all_commands_help)
79
79
 
80
80
 
81
- def usage(tokens: list, config: dict, command="") -> int:
81
+ def usage(tokens: list, config: dict, command: str = "", tool: str = "") -> int:
82
82
  '''Returns an int shell return code, given remaining args (tokens list) and eda command.
83
83
 
84
84
  config is the config dict. Used to check valid commands in config['command_handler']
@@ -112,6 +112,9 @@ And <files|targets, ...> is one or more source file or DEPS markup file target,
112
112
 
113
113
  if command in config['command_handler'].keys():
114
114
  sco = config['command_handler'][command](config=config) # sub command object
115
+ sco_tool = getattr(sco, '_TOOL', '')
116
+ if tool and tool != sco_tool:
117
+ util.warning(f'{tool=} does not support {command=}')
115
118
  sco.help(tokens=tokens)
116
119
  return util.exit(0)
117
120
 
@@ -282,9 +285,15 @@ def tool_setup(tool: str, config: dict, quiet: bool = False, auto_setup: bool =
282
285
  if tool not in config['auto_tools_order'][0]:
283
286
  tools = list(config.get('auto_tools_order', [{}])[0].keys())
284
287
  cfg_yaml_fname = config.get('config-yml', None)
288
+ util.warning(f'Unknown tool: {tool}')
289
+ if tools:
290
+ util.info('Known tools:')
291
+ pretty_tools = str_helpers.pretty_list_columns_manual(data=tools)
292
+ for row in pretty_tools:
293
+ if row:
294
+ util.info(row)
285
295
  util.error(f"Don't know how to run tool_setup({tool=}), is not in",
286
- f"config['auto_tools_order'] for {tools=}",
287
- f"from {cfg_yaml_fname}")
296
+ f"config['auto_tools_order'] from {cfg_yaml_fname}")
288
297
  return
289
298
 
290
299
  if tool not in config['auto_tools_found']:
@@ -394,7 +403,9 @@ def process_tokens( # pylint: disable=too-many-branches,too-many-statements,too-
394
403
  for arg in unparsed:
395
404
  if not arg.startswith('-'):
396
405
  command = arg
397
- return usage(tokens=unparsed, config=config, command=command)
406
+ if parsed.tool:
407
+ tool_setup(parsed.tool, config=config)
408
+ return usage(tokens=unparsed, config=config, command=command, tool=parsed.tool)
398
409
 
399
410
  if parsed.tool:
400
411
  tool_setup(parsed.tool, config=config)
@@ -7,6 +7,7 @@ DEFAULT_HANDLERS:
7
7
  # These commands (sim, elab, etc) require a tool, but have a default handler
8
8
  # base class:
9
9
  sim : opencos.commands.CommandSim
10
+ lint : opencos.commands.CommandLint
10
11
  elab : opencos.commands.CommandElab
11
12
  synth : opencos.commands.CommandSynth
12
13
  proj : opencos.commands.CommandProj
@@ -29,7 +30,8 @@ DEFAULT_HANDLERS:
29
30
 
30
31
  DEFAULT_HANDLERS_HELP:
31
32
  sim: Simulates a DEPS target.
32
- elab: Elaborates a DEPS target (lint, tool specific).
33
+ lint: Syntax check, lint a DEPS target
34
+ elab: Elaborates a DEPS target (lint + elab, tool specific).
33
35
  synth: Synthesizes a DEPS target.
34
36
  flist: Create dependency from a DEPS target.
35
37
  proj: Create a project from a DEPS target for GUI sim/waves/debug.
@@ -362,11 +364,13 @@ auto_tools_order:
362
364
  requires_cmd:
363
365
  - slang --version
364
366
  handlers:
367
+ lint: opencos.tools.slang.CommandLintSlang
365
368
  elab: opencos.tools.slang.CommandElabSlang
366
369
 
367
370
  verilator:
368
371
  exe: verilator
369
372
  handlers:
373
+ lint: opencos.tools.verilator.VerilatorLint
370
374
  elab: opencos.tools.verilator.VerilatorElab
371
375
  sim: opencos.tools.verilator.VerilatorSim
372
376
 
@@ -382,6 +386,7 @@ auto_tools_order:
382
386
  requires_cmd:
383
387
  - surelog --version
384
388
  handlers:
389
+ lint: opencos.tools.surelog.CommandLintSurelog
385
390
  elab: opencos.tools.surelog.CommandElabSurelog
386
391
 
387
392
  invio:
@@ -391,6 +396,7 @@ auto_tools_order:
391
396
  requires_py:
392
397
  - invio
393
398
  handlers:
399
+ lint: opencos.tools.invio.CommandLintInvio
394
400
  elab: opencos.tools.invio.CommandElabInvio
395
401
 
396
402
  vaporview:
@@ -422,6 +428,7 @@ auto_tools_order:
422
428
  vivado:
423
429
  exe: vivado
424
430
  handlers:
431
+ lint: opencos.tools.vivado.CommandLintVivado
425
432
  elab: opencos.tools.vivado.CommandElabVivado
426
433
  sim: opencos.tools.vivado.CommandSimVivado
427
434
  synth: opencos.tools.vivado.CommandSynthVivado
@@ -469,6 +476,7 @@ auto_tools_order:
469
476
  exe: qrun
470
477
  requires_vsim_helper: True
471
478
  handlers:
479
+ lint: opencos.tools.questa.CommandLintQuesta
472
480
  elab: opencos.tools.questa.CommandElabQuesta
473
481
  sim: opencos.tools.questa.CommandSimQuesta
474
482
  flist: opencos.tools.questa.CommandFListQuesta
@@ -479,6 +487,7 @@ auto_tools_order:
479
487
  - which riviera # Do not run it, make sure it's in PATH
480
488
  requires_vsim_helper: True
481
489
  handlers:
490
+ lint: opencos.tools.riviera.CommandLintRiviera
482
491
  elab: opencos.tools.riviera.CommandElabRiviera
483
492
  sim: opencos.tools.riviera.CommandSimRiviera
484
493
 
@@ -486,6 +495,7 @@ auto_tools_order:
486
495
  exe: vsim
487
496
  requires_vsim_helper: True
488
497
  handlers:
498
+ lint: opencos.tools.modelsim_ase.CommandLintModelsimAse
489
499
  elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
490
500
  sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
491
501
 
@@ -493,6 +503,7 @@ auto_tools_order:
493
503
  exe: vsim
494
504
  requires_vsim_helper: True
495
505
  handlers:
506
+ lint: opencos.tools.questa_fse.CommandLintQuestaFse
496
507
  elab: opencos.tools.questa_fse.CommandElabQuestaFse
497
508
  sim: opencos.tools.questa_fse.CommandSimQuestaFse
498
509
  flist: opencos.tools.questa_fse.CommandFListQuestaFse
@@ -500,6 +511,7 @@ auto_tools_order:
500
511
  iverilog:
501
512
  exe: iverilog
502
513
  handlers:
514
+ lint: opencos.tools.iverilog.CommandLintIverilog
503
515
  elab: opencos.tools.iverilog.CommandElabIverilog
504
516
  sim: opencos.tools.iverilog.CommandSimIverilog
505
517
 
opencos/tests/helpers.py CHANGED
@@ -65,6 +65,11 @@ def eda_elab_wrap(*args):
65
65
  main_args = [x for x in list(args) if (x != 'elab' and '--seed' not in x)]
66
66
  return eda.main('elab', *main_args)
67
67
 
68
+ def eda_lint_wrap(*args):
69
+ '''Calls eda.main for 'elab'.'''
70
+ main_args = [x for x in list(args) if (x != 'lint' and '--seed' not in x)]
71
+ return eda.main('lint', *main_args)
72
+
68
73
  def assert_sim_log_passes(
69
74
  filepath: str, want_str: str = 'TEST PASS',
70
75
  err_strs: list = ['Error', 'ERROR', 'TEST FAIL']
@@ -5,7 +5,7 @@ import pytest
5
5
 
6
6
  from opencos import eda_tool_helper
7
7
  from opencos.tests import helpers
8
- from opencos.tests.helpers import eda_wrap, eda_elab_wrap
8
+ from opencos.tests.helpers import eda_wrap, eda_elab_wrap, eda_lint_wrap
9
9
 
10
10
 
11
11
  thispath = os.path.dirname(__file__)
@@ -29,6 +29,16 @@ list_of_elab_tools = [
29
29
  'invio_yosys',
30
30
  ]
31
31
 
32
+ list_of_lint_tools = [
33
+ 'slang',
34
+ 'verilator',
35
+ 'vivado',
36
+ 'modelsim_ase'
37
+ 'questa_fse',
38
+ 'invio',
39
+ 'surelog',
40
+ ]
41
+
32
42
  list_of_elab_tools_cant_sim = [
33
43
  'slang',
34
44
  'invio',
@@ -36,6 +46,11 @@ list_of_elab_tools_cant_sim = [
36
46
  'invio_yosys',
37
47
  ]
38
48
 
49
+ list_of_commands = [
50
+ 'elab',
51
+ 'lint',
52
+ ]
53
+
39
54
  def skip_it(tool) -> bool:
40
55
  '''Returns True if this test should be skipped
41
56
 
@@ -44,27 +59,33 @@ def skip_it(tool) -> bool:
44
59
  '''
45
60
  return bool( tool not in tools_loaded )
46
61
 
62
+ @pytest.mark.parametrize("command", list_of_commands)
47
63
  @pytest.mark.parametrize("tool", list_of_elab_tools)
48
64
  class Tests:
49
65
  '''Test tools from list_of_elab_tools for 'eda elab' and 'eda multi elab'.'''
50
66
 
51
- def test_args_elab(self, tool):
67
+ def test_args_elab(self, command, tool):
52
68
  '''tests: eda elab --tool oclib_priarb'''
69
+ if command == 'lint' and tool not in list_of_lint_tools:
70
+ pytest.skip(f"lint skipped for {tool=} b/c it can't run lint")
53
71
  if skip_it(tool):
54
72
  pytest.skip(f"{tool=} skipped, {tools_loaded=}")
55
73
  return # skip/pass
56
74
  chdir_remove_work_dir('../../lib')
57
- rc = eda_elab_wrap('--tool', tool, 'oclib_priarb')
75
+ if command == 'elab':
76
+ rc = eda_elab_wrap('--tool', tool, 'oclib_priarb')
77
+ else:
78
+ rc = eda_lint_wrap('--tool', tool, 'oclib_priarb')
58
79
  print(f'{rc=}')
59
80
  assert rc == 0
60
81
 
61
- def test_args_multi_elab(self, tool):
82
+ def test_args_multi_elab(self, command, tool):
62
83
  '''tests: eda multi elab --tool oclib_*arb'''
63
84
  if skip_it(tool):
64
85
  pytest.skip(f"{tool=} skipped, {tools_loaded=}")
65
86
  return # skip/pass
66
87
  chdir_remove_work_dir('../../lib')
67
- rc = eda_wrap('multi', 'elab', '--tool', tool, 'oclib_*arb')
88
+ rc = eda_wrap('multi', command, '--tool', tool, 'oclib_*arb')
68
89
  print(f'{rc=}')
69
90
  assert rc == 0
70
91
 
opencos/tools/invio.py CHANGED
@@ -38,6 +38,8 @@ class ToolInvio(Tool):
38
38
  class CommandElabInvio(CommandElab, ToolInvio):
39
39
  '''Command handler for: eda elab --tool=invio'''
40
40
 
41
+ command_name = 'elab'
42
+
41
43
  def __init__(self, config:dict):
42
44
  CommandElab.__init__(self, config)
43
45
  ToolInvio.__init__(self, config=self.config)
@@ -72,7 +74,7 @@ class CommandElabInvio(CommandElab, ToolInvio):
72
74
  '''Returns list of util.ShellCommandList, for slang we'll run this in elaborate()'''
73
75
  invio_blackbox_list = self.args.get('invio-blackbox', [])
74
76
  invio_dict = invio_helpers.get_invio_command_dict(
75
- self, blackbox_list=invio_blackbox_list, sim_elab=True
77
+ self, blackbox_list=invio_blackbox_list,
76
78
  )
77
79
  return invio_dict['command_lists']
78
80
 
@@ -84,3 +86,8 @@ class CommandElabInvio(CommandElab, ToolInvio):
84
86
  def get_elaborate_command_lists(self, **kwargs) -> list:
85
87
  '''We only use 'compile' commands for invio elab, do not use elaborate commands'''
86
88
  return []
89
+
90
+ class CommandLintInvio(CommandElabInvio):
91
+ '''Command handler for: eda lint --tool=invio'''
92
+
93
+ command_name = 'lint'
@@ -34,6 +34,7 @@ def write_py_file(
34
34
  py_filename: str = 'run_invio.py',
35
35
  v_filename: str = '',
36
36
  blackbox_list: list = [],
37
+ sim_lint: bool = False,
37
38
  sim_elab: bool = False,
38
39
  **kwargs
39
40
  ) -> dict:
@@ -137,7 +138,15 @@ def write_py_file(
137
138
  tee_fpath = 'invio.log')]
138
139
  })
139
140
 
140
- if sim_elab:
141
+ if sim_lint:
142
+ # lint (skip elaborate steps -- from eda.CommandLintInvio)
143
+ lines += [
144
+ 'assert analyze()',
145
+ '',
146
+ 'report_analyzed_files()',
147
+ 'print_instance_hierarchy()',
148
+ ]
149
+ elif sim_elab:
141
150
  # elab (non-synthesis), runs the following (from eda.CommandElabInvio)
142
151
  lines += [
143
152
  'assert analyze()',
@@ -206,14 +215,23 @@ def write_py_file(
206
215
 
207
216
 
208
217
 
209
- def get_invio_command_dict(command_design_obj:object, v_filename='', py_filename='run_invio.py',
210
- blackbox_list=[], sim_elab:bool=False, **kwargs) -> dict:
218
+ def get_invio_command_dict(
219
+ command_design_obj:object, v_filename='', py_filename='run_invio.py',
220
+ blackbox_list=[],
221
+ **kwargs
222
+ ) -> dict:
211
223
  '''Creates a .py file from an eda.CommandDesign. Returns a dict with
212
224
 
213
225
  information about what to run.'''
214
226
 
215
- invio_dict = write_py_file( command_design_obj, v_filename=v_filename,
216
- py_filename=py_filename, blackbox_list=blackbox_list,
217
- sim_elab=sim_elab, **kwargs )
227
+ cmd_name = getattr(command_design_obj, 'command_name', '')
228
+ sim_lint = cmd_name == 'lint'
229
+ sim_elab = cmd_name == 'elab'
230
+
231
+ invio_dict = write_py_file(
232
+ command_design_obj, v_filename=v_filename,
233
+ py_filename=py_filename, blackbox_list=blackbox_list,
234
+ sim_elab=sim_elab, sim_lint=sim_lint, **kwargs
235
+ )
218
236
 
219
237
  return invio_dict
@@ -59,7 +59,7 @@ class CommandSynthInvioYosys(CommonSynthYosys, ToolInvioYosys):
59
59
 
60
60
  # Generate run_invio.py:
61
61
  invio_dict = invio_helpers.get_invio_command_dict(
62
- self, blackbox_list=invio_blackbox_list, sim_elab=False
62
+ self, blackbox_list=invio_blackbox_list,
63
63
  )
64
64
  # run run_invio.py:
65
65
  if not self.args.get('stop-before-compile', False):
@@ -146,9 +146,10 @@ class CommandSynthInvioYosys(CommonSynthYosys, ToolInvioYosys):
146
146
  class CommandElabInvioYosys(CommandSynthInvioYosys):
147
147
  '''Run invio + yosys as elab only (does not run the synthesis portion)'''
148
148
 
149
+ command_name = 'elab'
150
+
149
151
  def __init__(self, config):
150
152
  super().__init__(config)
151
- self.command_name = 'elab'
152
153
  self.args.update({
153
154
  'stop-after-compile': True, # In the case of Invio/Yosys we run the Invio step
154
155
  'lint': True
opencos/tools/iverilog.py CHANGED
@@ -164,6 +164,19 @@ class CommandSimIverilog(CommandSim, ToolIverilog):
164
164
  class CommandElabIverilog(CommandSimIverilog):
165
165
  '''CommandElabIverilog is a command handler for: eda elab --tool=iverilog'''
166
166
 
167
+ command_name = 'elab'
168
+
169
+ def __init__(self, config:dict):
170
+ super().__init__(config)
171
+ self.args['stop-after-elaborate'] = True
172
+
173
+
174
+ class CommandLintIverilog(CommandSimIverilog):
175
+ '''CommandLintIverilog is a command handler for: eda lint --tool=iverilog'''
176
+
177
+ command_name = 'lint'
178
+
167
179
  def __init__(self, config:dict):
168
180
  super().__init__(config)
181
+ self.args['stop-after-compile'] = True
169
182
  self.args['stop-after-elaborate'] = True
@@ -369,6 +369,19 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
369
369
  class CommandElabModelsimAse(CommandSimModelsimAse):
370
370
  '''CommandElabModelsimAse is a command handler for: eda elab --tool=modelsim_ase'''
371
371
 
372
+ command_name = 'elab'
373
+
374
+ def __init__(self, config:dict):
375
+ super().__init__(config)
376
+ self.args['stop-after-elaborate'] = True
377
+
378
+
379
+ class CommandLintModelsimAse(CommandSimModelsimAse):
380
+ '''CommandLintModelsimAse is a command handler for: eda lint --tool=modelsim_ase'''
381
+
382
+ command_name = 'lint'
383
+
372
384
  def __init__(self, config:dict):
373
385
  super().__init__(config)
386
+ self.args['stop-after-compile'] = True
374
387
  self.args['stop-after-elaborate'] = True
opencos/tools/quartus.py CHANGED
@@ -150,6 +150,7 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
150
150
  self.write_tcl_file(tcl_file=tcl_file)
151
151
 
152
152
  # execute Quartus synthesis
153
+ command_list_gui = [self.quartus_gui_exe, '-t', tcl_file]
153
154
  command_list = [
154
155
  self.quartus_exe, '-t', tcl_file
155
156
  ]
@@ -170,9 +171,27 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
170
171
  typ='text', description='Quartus Synthesis Report'
171
172
  )
172
173
 
173
- self.exec(self.args['work-dir'], command_list)
174
+ if self.args['gui'] and self.quartus_gui_exe:
175
+ self.exec(self.args['work-dir'], command_list_gui)
176
+ else:
177
+ self.exec(self.args['work-dir'], command_list)
178
+
179
+
180
+ saved_qpf_filename = self.args["top"] + '.qpf'
181
+ if not os.path.isfile(os.path.join(self.args['work-dir'], saved_qpf_filename)):
182
+ self.error('Saved project file does not exist:',
183
+ os.path.join(self.args['work-dir'], saved_qpf_filename))
184
+
174
185
  util.info(f"Synthesis done, results are in: {self.args['work-dir']}")
175
186
 
187
+ # Note: in GUI mode, if you ran: quaruts -t build.tcl, it will exit on completion,
188
+ # so we'll re-open the project.
189
+ if self.args['gui'] and self.quartus_gui_exe:
190
+ self.exec(
191
+ work_dir=self.args['work-dir'],
192
+ command_list=[self.quartus_gui_exe, saved_qpf_filename]
193
+ )
194
+
176
195
  def write_tcl_file(self, tcl_file: str) -> None: # pylint: disable=too-many-locals,too-many-branches
177
196
  '''Writes synthesis capable Quartus tcl file to filepath 'tcl_file'.'''
178
197
 
@@ -221,11 +240,27 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
221
240
  tcl_lines.append(f"set_global_assignment -name VERILOG_MACRO \"{key}={value}\"")
222
241
 
223
242
  # Add constraints
243
+ default_sdc = False
244
+ sdc_files = []
224
245
  if self.args['sdc']:
225
- tcl_lines.append(f"set_global_assignment -name SDC_FILE \"{self.args['sdc']}\"")
246
+ sdc_files = [os.path.abspath(self.args['sdc'])]
226
247
  elif self.files_sdc:
227
- for sdc_file in self.files_sdc:
228
- tcl_lines.append(f"set_global_assignment -name SDC_FILE \"{sdc_file}\"")
248
+ # Use files from DEPS target or command line.
249
+ sdc_files = self.files_sdc
250
+ else:
251
+ default_sdc = True
252
+ sdc_file = self.args['top'] + '.sdc'
253
+ sdc_files = [sdc_file]
254
+
255
+ for f in sdc_files:
256
+ for attr in ('SDC_FILE', 'SYN_SDC_FILE', 'RTL_SDC_FILE'):
257
+ tcl_lines.extend([
258
+ f"set_global_assignment -name {attr} \"{f}\""
259
+ ])
260
+ tcl_lines.append("set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON")
261
+
262
+ if default_sdc:
263
+ self.write_default_sdc(sdc_file=os.path.join(self.args['work-dir'], sdc_file))
229
264
 
230
265
  tcl_lines += [
231
266
  "# Run synthesis",
@@ -237,6 +272,25 @@ class CommandSynthQuartus(CommandSynth, ToolQuartus):
237
272
  ftcl.write('\n'.join(tcl_lines))
238
273
 
239
274
 
275
+ def write_default_sdc(self, sdc_file: str) -> None:
276
+ '''Writes a default SDC file to filepath 'sdc_file'.'''
277
+
278
+ sdc_lines = []
279
+ util.info("Creating default constraints: clock:",
280
+ f"{self.args['clock-name']}, {self.args['clock-ns']} (ns),")
281
+
282
+ clock_name = self.args['clock-name']
283
+ period = self.args['clock-ns']
284
+
285
+ sdc_lines += [
286
+ ("create_clock -name {" + clock_name + "} -period {" + str(period) + "} [get_ports "
287
+ "{" + clock_name + "}]")
288
+ ]
289
+
290
+ with open( sdc_file, 'w', encoding='utf-8' ) as fsdc:
291
+ fsdc.write('\n'.join(sdc_lines))
292
+
293
+
240
294
  class CommandBuildQuartus(CommandBuild, ToolQuartus):
241
295
  '''CommandBuildQuartus is a command handler for: eda build --tool=quartus'''
242
296
 
@@ -371,7 +425,8 @@ class CommandBuildQuartus(CommandBuild, ToolQuartus):
371
425
  util.write_shell_command_file(dirpath=self.args['work-dir'], filename='run_quartus_gui.sh',
372
426
  command_lists=[
373
427
  command_list_gui,
374
- ['quartus', saved_qpf_filename], # reopen when done.
428
+ # reopen when done.
429
+ [self.quartus_gui_exe, saved_qpf_filename],
375
430
  ], line_breaks=True)
376
431
 
377
432
  # Add artifact tracking for build
@@ -422,7 +477,7 @@ class CommandBuildQuartus(CommandBuild, ToolQuartus):
422
477
  if self.args['gui'] and self.quartus_gui_exe:
423
478
  self.exec(
424
479
  work_dir=self.args['work-dir'],
425
- command_list=['quartus', saved_qpf_filename]
480
+ command_list=[self.quartus_gui_exe, saved_qpf_filename]
426
481
  )
427
482
 
428
483
 
opencos/tools/questa.py CHANGED
@@ -267,7 +267,21 @@ class CommandFListQuesta(CommandFList, ToolQuesta):
267
267
  class CommandElabQuesta(CommandSimQuesta):
268
268
  '''Command handler for: eda elab --tool=questa'''
269
269
 
270
+ command_name = 'elab'
271
+
272
+ def __init__(self, config:dict):
273
+ CommandSimQuesta.__init__(self, config)
274
+ # add args specific to this simulator
275
+ self.args['stop-after-elaborate'] = True
276
+
277
+
278
+ class CommandLintQuesta(CommandSimQuesta):
279
+ '''Command handler for: eda lint --tool=questa'''
280
+
281
+ command_name = 'lint'
282
+
270
283
  def __init__(self, config:dict):
271
284
  CommandSimQuesta.__init__(self, config)
272
285
  # add args specific to this simulator
286
+ self.args['stop-after-compile'] = True
273
287
  self.args['stop-after-elaborate'] = True
@@ -56,8 +56,21 @@ class CommandSimQuestaFse(CommandSimModelsimAse):
56
56
  class CommandElabQuestaFse(CommandSimQuestaFse):
57
57
  '''CommandElabQuestaFse is a command handler for: eda elab --tool=questa_fse'''
58
58
 
59
+ command_name = 'elab'
60
+
61
+ def __init__(self, config:dict):
62
+ super().__init__(config)
63
+ self.args['stop-after-elaborate'] = True
64
+
65
+
66
+ class CommandLintQuestaFse(CommandSimQuestaFse):
67
+ '''CommandLintQuestaFse is a command handler for: eda lint --tool=questa_fse'''
68
+
69
+ command_name = 'lint'
70
+
59
71
  def __init__(self, config:dict):
60
72
  super().__init__(config)
73
+ self.args['stop-after-compile'] = True
61
74
  self.args['stop-after-elaborate'] = True
62
75
 
63
76
 
opencos/tools/riviera.py CHANGED
@@ -289,6 +289,19 @@ class CommandSimRiviera(CommandSimModelsimAse, ToolRiviera):
289
289
  class CommandElabRiviera(CommandSimRiviera):
290
290
  '''CommandElabRiviera is a command handler for: eda elab --tool=riviera'''
291
291
 
292
+ command_name = 'elab'
293
+
294
+ def __init__(self, config:dict):
295
+ super().__init__(config)
296
+ self.args['stop-after-elaborate'] = True
297
+
298
+
299
+ class CommandLintRiviera(CommandSimRiviera):
300
+ '''CommandLintRiviera is a command handler for: eda lint --tool=riviera'''
301
+
302
+ command_name = 'lint'
303
+
292
304
  def __init__(self, config:dict):
293
305
  super().__init__(config)
306
+ self.args['stop-after-compile'] = True
294
307
  self.args['stop-after-elaborate'] = True
opencos/tools/slang.py CHANGED
@@ -115,7 +115,7 @@ class CommandElabSlang(CommandElab, ToolSlang):
115
115
  pass
116
116
 
117
117
  def elaborate(self):
118
- ''' elaborate() - following parent Commandsim's run() flow, runs slang_command_lists'''
118
+ ''' elaborate() - following parent CommandSim's run() flow, runs slang_command_lists'''
119
119
  if self.args['stop-before-compile'] or \
120
120
  self.args['stop-after-compile']:
121
121
  return
@@ -208,3 +208,14 @@ class CommandElabSlang(CommandElab, ToolSlang):
208
208
  )
209
209
 
210
210
  return command_list
211
+
212
+
213
+ class CommandLintSlang(CommandElabSlang):
214
+ '''CommandLintSlang is a command handler for: eda lint --tool=slang.'''
215
+
216
+ command_name = 'lint'
217
+
218
+ def __init__(self, config: dict):
219
+ super().__init__(config)
220
+ # keep stop-after-compile=False, allow's CommandElabSlang.elaborate() to run.
221
+ self.args['slang-args'] = ['--lint-only', '--ignore-unknown-modules']
opencos/tools/surelog.py CHANGED
@@ -63,6 +63,7 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
63
63
  ToolSurelog.__init__(self, config=self.config)
64
64
  self.args.update({
65
65
  'surelog-top': '',
66
+ 'surelog-args': [],
66
67
  })
67
68
 
68
69
  self.surelog_command_lists = []
@@ -98,6 +99,7 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
98
99
  'compile-args',
99
100
  '-parse').split()
100
101
  command_list += config_compile_args
102
+ command_list += self.args['surelog-args']
101
103
 
102
104
  if util.args.get('debug', None) or \
103
105
  util.args.get('verbose', None):
@@ -139,3 +141,14 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
139
141
  dirpath=self.args['work-dir'], filename='run_surelog.sh',
140
142
  command_lists=self.surelog_command_lists, line_breaks=True
141
143
  )
144
+
145
+
146
+ class CommandLintSurelog(CommandElabSurelog):
147
+ '''CommandLintSurelog is a command handler for: eda lint --tool=surelog.'''
148
+ command_name = 'lint'
149
+
150
+ def __init__(self, config: dict):
151
+ super().__init__(config)
152
+ # keep stop-after-compile=False, allow's CommandElabSurelog.elaborate() to run.
153
+ # run the "compile" step only for surelog by setting -noelab:
154
+ self.args['surelog-args'] = ['-noelab']
@@ -499,8 +499,22 @@ class VerilatorSim(CommandSim, ToolVerilator):
499
499
 
500
500
  class VerilatorElab(VerilatorSim):
501
501
  '''VerilatorElab is a command handler for: eda elab --tool=verilator'''
502
+ command_name = 'elab'
502
503
 
503
504
  def __init__(self, config: dict):
504
505
  super().__init__(config)
505
506
  self.args['stop-after-elaborate'] = True
506
507
  self.args['lint-only'] = True
508
+
509
+
510
+ class VerilatorLint(VerilatorSim):
511
+ '''VerilatorLint is a command handler for: eda lint --tool=verilator.
512
+
513
+ For practical reasons, this is identical to VerilatorElab with --stop-after-compile.'''
514
+ command_name = 'lint'
515
+
516
+ def __init__(self, config: dict):
517
+ super().__init__(config)
518
+ self.args['stop-after-compile'] = True
519
+ self.args['stop-after-elaborate'] = True
520
+ self.args['lint-only'] = True
opencos/tools/vivado.py CHANGED
@@ -347,12 +347,23 @@ class CommandSimVivado(CommandSim, ToolVivado):
347
347
 
348
348
  class CommandElabVivado(CommandSimVivado):
349
349
  '''CommandElabVivado is a command handler for: eda elab --tool=vivado, uses xvlog, xelab'''
350
+ command_name = 'elab'
350
351
  def __init__(self, config: dict):
351
352
  CommandSimVivado.__init__(self, config)
352
353
  # add args specific to this tool
353
354
  self.args['stop-after-elaborate'] = True
354
355
 
355
356
 
357
+ class CommandLintVivado(CommandSimVivado):
358
+ '''CommandLintVivado is a command handler for: eda lint --tool=vivado, uses xvlog'''
359
+ command_name = 'lint'
360
+ def __init__(self, config: dict):
361
+ CommandSimVivado.__init__(self, config)
362
+ # add args specific to this tool
363
+ self.args['stop-after-compile'] = True
364
+ self.args['stop-after-elaborate'] = True
365
+
366
+
356
367
  class CommandSynthVivado(CommandSynth, ToolVivado):
357
368
  '''CommandSynthVivado is a command handler for: eda synth --tool=vivado'''
358
369
  def __init__(self, config: dict):
opencos/tools/yosys.py CHANGED
@@ -219,6 +219,9 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
219
219
  if not self.args['sta-scriptfile']:
220
220
  return []
221
221
 
222
+ # Add URL info for OpenSTA source code:
223
+ self._add_opensta_info()
224
+
222
225
  ret_list = []
223
226
  for i,fpath in enumerate(self.args['sta-scriptfile']):
224
227
  if not os.path.isfile(fpath):
@@ -377,6 +380,9 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
377
380
  if not self.sta_exe:
378
381
  self.error(f'--sta is set, but "sta" was not found in PATH, see: {self._URL}')
379
382
 
383
+ # Add URL info for OpenSTA source code:
384
+ self._add_opensta_info()
385
+
380
386
  sta_command_list = util.ShellCommandList(
381
387
  [ self.sta_exe, '-no_init', '-exit', 'sta.f' ],
382
388
  tee_fpath = 'sta.log'
@@ -439,6 +445,15 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
439
445
  ]
440
446
  f.write('\n'.join(lines))
441
447
 
448
+ def _add_opensta_info(self) -> None:
449
+ '''Adds OpenSTA URL information to artifacts and logs'''
450
+
451
+ opensta_repo_url = 'https://github.com/The-OpenROAD-Project/OpenSTA'
452
+
453
+ # Log GPL3.0 license information
454
+ util.info(f'Using OpenSTA (see URL for license and source): {opensta_repo_url}')
455
+ if hasattr(self, 'sta_version') and self.sta_version:
456
+ util.info(f'OpenSTA version: {self.sta_version}')
442
457
 
443
458
  def _get_read_verilog_one_liner(self) -> str:
444
459
  '''Returns a string, intended to be used w/out Slang, for Verilog or simple
opencos/util.py CHANGED
@@ -1,5 +1,7 @@
1
1
  '''opencos.util -- support global logging, argparser for printing (colors)'''
2
2
 
3
+ # pylint: disable=too-many-lines
4
+
3
5
  import argparse
4
6
  import atexit
5
7
  import datetime
@@ -89,6 +91,7 @@ class ArtifactTypes(Enum):
89
91
  TCL = 5
90
92
  SHELL = 6
91
93
  BITSTREAM = 7
94
+ LICENSE = 8
92
95
 
93
96
  class Artifacts:
94
97
  '''Class to hold file artifacts, for logs generated by EDA, or other artifcats created
@@ -198,7 +201,10 @@ class Artifacts:
198
201
  # Update all file sizes:
199
202
  remove_keys = set()
200
203
  for key, entry in self.data.items():
201
- if os.path.isfile(entry['name']):
204
+ if entry['type'] == 'license':
205
+ # License entries are metadata, not files - keep them as-is
206
+ entry['size'] = 0
207
+ elif os.path.isfile(entry['name']):
202
208
  entry['size'] = os.path.getsize(entry['name'])
203
209
  else:
204
210
  # file doesn't exist, remove it from artifacts.
@@ -7,14 +7,18 @@ import shlex
7
7
  import textwrap
8
8
 
9
9
  VALID_TARGET_INFO_STR = (
10
- "should start with an underscore/letter, rest should be alpha-numeric, dashes, or underscores."
10
+ "should start with a . or underscore/letter, rest should be"
11
+ " ., alpha-numeric, dashes, or underscores."
11
12
  )
12
13
 
13
14
  def is_valid_target_name(s: str) -> bool:
14
- '''Returns True if str starts with underscore/letter, rest alphanum, dash, or underscores'''
15
- if not s or not (s[0].isalpha() or s[0] == '_'):
15
+ '''Returns True if str starts with . or underscore/letter, rest alphanum, dash, dot,
16
+
17
+ or underscores. We allow '.' otherwise deps_file.py posts warnings about badly named
18
+ targets for files that are missing.'''
19
+ if not s or not (s[0].isalpha() or s[0] == '_' or s[0] == '.'):
16
20
  return False
17
- return s.replace('_', '').replace('-', '').isalnum()
21
+ return s.replace('_', '').replace('-', '').replace('.', '').isalnum()
18
22
 
19
23
  def strip_all_quotes(s: str) -> str:
20
24
  '''Returns str with all ' and " removed'''
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.54
3
+ Version: 0.2.55
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
@@ -15,5 +15,5 @@ Requires-Dist: schema>=0.7.7
15
15
  Requires-Dist: toml>=0.10.2
16
16
  Requires-Dist: yamllint>=1.35.1
17
17
  Requires-Dist: PySerial>=3.5
18
- Requires-Dist: cocotb>=2.0.0b1
18
+ Requires-Dist: cocotb>=2.0
19
19
  Dynamic: license-file
@@ -2,10 +2,10 @@ 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=5QLN2OQdhbfxHqbqt4Ty-Saskh-z_h9m9qfWqB8kZ9U,15691
5
- opencos/eda.py,sha256=kz4jSYBANXdbNGH3DmE9v_jU2p_NkI2tT6aBslcYtcQ,22248
5
+ opencos/eda.py,sha256=otdIufWO8C4YoEmwcaQGMwH06xe-IjyyExYWhw3Xz-8,22765
6
6
  opencos/eda_base.py,sha256=DX0RHiJq84T_4LpcC7zQD5cCuDHfLrWzk7lkXBWfeP8,101892
7
7
  opencos/eda_config.py,sha256=XgO2YKUWSL7TAFo-V4h4xqNO3Z1Ug4JI-W8LvzD-kGQ,11407
8
- opencos/eda_config_defaults.yml,sha256=-2ISGkktUo-O5hzju_KxNGr9oyRL9iYQ4OKRzImgCsQ,15284
8
+ opencos/eda_config_defaults.yml,sha256=_YwY2OufgfV8GXhQd6Gs7sE-I1z2GkGsCowxipNJZaw,15938
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
@@ -18,14 +18,15 @@ opencos/files.py,sha256=aoq0O2KfISzZb-Vi_q_0TTGBER9xJc--FkVZf0ga7pA,1549
18
18
  opencos/names.py,sha256=iC37PV7Pz0PicTDg09vbQ9NXAj-5m6RKrWHkkcHB8As,1145
19
19
  opencos/peakrdl_cleanup.py,sha256=vHNGtalTrIVP335PhRjPt9RhoccgpK1HJAi-E4M8Kc8,736
20
20
  opencos/seed.py,sha256=IL9Yg-r9SLSRseMVWaEHmuw2_DNi_eyut11EafoNTsU,942
21
- opencos/util.py,sha256=03b2JP80NDXksNTwShMRamnTVb1C2gUfrPYBDL40pHA,37565
22
- opencos/commands/__init__.py,sha256=TtfbQgmdSTGDZzTrl1ASx7pxY3jaXyK6aTtOng0x-O8,1076
21
+ opencos/util.py,sha256=9VGc54Rm-snEwbKEbToQRGoeGg8wqBeWpTJBagEbjw0,37770
22
+ opencos/commands/__init__.py,sha256=oOOQmn5_jHAMSOfA3swJJ7mdoyHsJA0lJwKPTudlTns,1125
23
23
  opencos/commands/build.py,sha256=hvjrvg7AbEotuQze6-yz3DOYRMtagkvJ-6TFNJQTwrs,1441
24
24
  opencos/commands/deps_help.py,sha256=WDrU7H9sypzDAxe_CHqhW5B_scbQMzBEdf-v-Jcfd5Q,10682
25
25
  opencos/commands/elab.py,sha256=m6Gk03wSzX8UkcmReooK7turF7LpqO0IcdOZwJ8XiyI,1596
26
26
  opencos/commands/export.py,sha256=dpTcrtPjIt6TOw-i8LUWhb4ismFAE1QK-dNAHC1jxME,3510
27
27
  opencos/commands/flist.py,sha256=x3VVarCVlz2kFJI5rQ8UsZzzas32j4zQKgzXGIozKwE,8638
28
28
  opencos/commands/lec.py,sha256=bshOs_GkuB1nCGd_SntT43_XpSYQYJqNCjVZp6Q1Chc,3879
29
+ opencos/commands/lint.py,sha256=piPb0l0zE3sAtNJkFQ-oNpuHxnaV_RNXkXtEj_9mwGs,1594
29
30
  opencos/commands/multi.py,sha256=dCo4rMIkGT3BtlBhUIAd7r31w8qxeJvybpl4H7DR77o,27225
30
31
  opencos/commands/open.py,sha256=XckvKUNwvc5KHbYGV-eQ2i0WG4X-yckroDaMC610MB4,804
31
32
  opencos/commands/proj.py,sha256=vCsZle3oUJ8xmIFuepgAD6G-YGl35xtTIcTeiVDshNo,1112
@@ -39,19 +40,19 @@ opencos/commands/waves.py,sha256=nrp3ALwfJujZns44tgCgia_dEedQyKe0T3fuws8h39U,769
39
40
  opencos/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
41
  opencos/deps/defaults.py,sha256=jG971rCDveja8NkY3uKcBYY-cnXsW_thqGRy19TWe1Q,1262
41
42
  opencos/deps/deps_commands.py,sha256=OlqueYFK8U83loasok3xJGzUDpNcj2DPk37332DfmRo,17039
42
- opencos/deps/deps_file.py,sha256=blqrN7wgOa5x_ldFC3tn2kCR4VStTEmMdXlePwyMwE4,16268
43
+ opencos/deps/deps_file.py,sha256=nVZWrq6PVhWig1yMNpy8w_7LQJ1rgb7Js0N1ngoqLio,16306
43
44
  opencos/deps/deps_processor.py,sha256=uO2NqQvi1iCRCO1pTS-ns-rET15FK3lsR6AjFrhPjUM,36209
44
45
  opencos/hw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
46
  opencos/hw/oc_cli.py,sha256=QBmf05VooB9kQFzgliak7PEvqVLTSEI3v6deV1OZQEs,132252
46
47
  opencos/hw/pcie.py,sha256=VUJljaZJYgScAAx5yn7F6GoA8K9eTcw24otYZbkMpYs,3035
47
48
  opencos/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
49
  opencos/tests/custom_config.yml,sha256=TRoVM9ZFKPOA_8JmlpzaMhnGO1txmaD14N_8P1oqzew,257
49
- opencos/tests/helpers.py,sha256=HdsARZK0KsGou2SRV30fBALV674bsST37ldpT-gI6q8,9512
50
+ opencos/tests/helpers.py,sha256=QjebK-tjGoKZq-RSgQ7EqMjJ4ArXQogLLtJBuK56OMw,9695
50
51
  opencos/tests/test_build.py,sha256=FQAxOpLVQShAHD_L5rqJctPeSAoqoOCNFI0RXflLuY0,387
51
52
  opencos/tests/test_deps_helpers.py,sha256=f9GJXvzcdE3SGkKJ7q-YBTgRagZcIzeRa6nMVCCiEvI,7848
52
53
  opencos/tests/test_deps_schema.py,sha256=T3P9KjaMyKsk8b7snNVvNSsom2hIJcg6Z9apYiXoH9Y,941
53
54
  opencos/tests/test_eda.py,sha256=cdxfLCUZq0nNelCQiplZXkeF4eyzmyJlZJFDSo77qeI,39464
54
- opencos/tests/test_eda_elab.py,sha256=VyYiaLLyfJi26FkoN9p_Kb9cMHfY-0u_0Mx1iVpsg-I,2657
55
+ opencos/tests/test_eda_elab.py,sha256=AjU4WMYtFoHpNe1Z4yWWpxDKy4V_hAjL5rl3jqphZrk,3179
55
56
  opencos/tests/test_eda_synth.py,sha256=LOM8CKpNyjka_sKS2c00YObOAQeVgpRmuM12Bn-PHqU,5234
56
57
  opencos/tests/test_oc_cli.py,sha256=w-F-LjSSWVql3D2WG8tcV4_C52i-hL_2WT3oDpKQn9s,734
57
58
  opencos/tests/test_tools.py,sha256=-WMpDZexAgko0FAcfiuASqSKNNL0Mr1ztag05808Upc,13735
@@ -64,33 +65,33 @@ opencos/tests/deps_files/tags_with_tools/DEPS.yml,sha256=-5U1qfJElgpVhmkLEu3lYuv
64
65
  opencos/tests/deps_files/test_err_fatal/DEPS.yml,sha256=GnXIUJvshQWR9PlYxX67T53ejf5KhDbtD8sUJB4Rwd0,95
65
66
  opencos/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
67
  opencos/tools/cocotb.py,sha256=vcp9wLlmgr6dLBnxEuJJyMjJIorIo96J0Z63tJwP-eE,16759
67
- opencos/tools/invio.py,sha256=q9E9n6xsozDfar-1rLvJEZbCpPb_bQEy6WKEI3KS3dk,3163
68
- opencos/tools/invio_helpers.py,sha256=1au4CYmV5aC7DHjaZBNemydH6Eq0i-Yt5L3HyKfQOfY,7638
69
- opencos/tools/invio_yosys.py,sha256=asSjbdPjBXB76KxNZIhoDRn2DoXKsZEQ1YDX_WBzKiA,6019
70
- opencos/tools/iverilog.py,sha256=tnwhOT_WjnUKf4ioei-xmclM2xDTRnN0DrkxIKwsfnc,5926
71
- opencos/tools/modelsim_ase.py,sha256=auBTdgBhbU2n92L0ezLUpppyE5z86Ci2-0hgDL_oNoc,14885
72
- opencos/tools/quartus.py,sha256=Iu4zw34OCKlERMyJ9GRwaAuRDeBHG_ApvJATvyII-68,27516
73
- opencos/tools/questa.py,sha256=5dr1LF7m5P1NmOPXU0hzMO0o0_RrXLDvc1gmhlwyEyU,9446
74
- opencos/tools/questa_fse.py,sha256=lqhW49YpbzhkOGWG-0EjITj-RMyy8IgWYoaW9UtjxK8,2194
75
- opencos/tools/riviera.py,sha256=D78anIJ_GnQ4aRwbWfR2QUslTgF38qiZod7v-EHLHg0,10716
76
- opencos/tools/slang.py,sha256=mFw58vhnCTRR9yaQ2zHPlNB5HKSf3Y078XcaVnpLaAc,7798
68
+ opencos/tools/invio.py,sha256=S2ChWr8xMZHSOOhX2hGKQhMmtQY2potVQjc-lsMg73o,3299
69
+ opencos/tools/invio_helpers.py,sha256=qj12OS-hn9cC-vlFX5EPXwHxOvwT98NoxgXGyAIRdrQ,8007
70
+ opencos/tools/invio_yosys.py,sha256=CszGeTdE1ilnMmWPLW77BrtobbsGb1CKXqot0hGimFU,5996
71
+ opencos/tools/iverilog.py,sha256=MxpCVFgR0lJt8gPE2A3cWO2kgM5ZJr9ZpDeJoOzH0rU,6277
72
+ opencos/tools/modelsim_ase.py,sha256=_CSxU1ylkuiW9LPowXJp-OTEuiHeNI9JsAZVQDHmv14,15249
73
+ opencos/tools/quartus.py,sha256=DVshppbpDKknQtgf-pnJvXQhVT8oHYGlAqbjHobrQBA,29591
74
+ opencos/tools/questa.py,sha256=nHImM0Wydcf4YHGibHmQAwmqKHmMxKZUqY-E-vz1o8M,9827
75
+ opencos/tools/questa_fse.py,sha256=hytkeuGg4qImj7rStV1i2kxkz9B0KFheGtcadxmpYAo,2550
76
+ opencos/tools/riviera.py,sha256=T_sk5Krszy20dbmloQQh3l3KIxMsaoWKRoAHkzpcH7I,11063
77
+ opencos/tools/slang.py,sha256=ON32RcXOYqw7ryumwos-ES5LF2_49rsTIPUivomZyys,8181
77
78
  opencos/tools/slang_yosys.py,sha256=3fyLRRdTXhSppNtUhhUl00oG-cT9TyyPTH6JvasS9ZE,9804
78
- opencos/tools/surelog.py,sha256=dtj3ApAKoQasnGdg42n9DPgeqoJ5nCuurIkIO3G5ZCY,5011
79
+ opencos/tools/surelog.py,sha256=RLZIsm2vr8oMZhlcedRepBcySYI4v8-lY9IEsqn2gGk,5525
79
80
  opencos/tools/tabbycad_yosys.py,sha256=2LePPgYXBVdsy7YcffPIWN-I0B7queLQ_f_pme2SCGw,7803
80
- opencos/tools/verilator.py,sha256=ACmRXJyE8ZGlu7gGHdgEyk8A5gQeMFSR1pBd8zw9eQc,20767
81
- opencos/tools/vivado.py,sha256=TEMIYSVCdEASu2fixFuKIwDbb3r_25Ns-8YyUVEz-eg,40611
82
- opencos/tools/yosys.py,sha256=UKWzvc2rSi3J9U2TROqRbmePdBmjskap664giumeRBk,26323
81
+ opencos/tools/verilator.py,sha256=vv_Y5pDp_Ffb93fUxoz1Ep5g0YrTdnYQgDECNHpzS2k,21229
82
+ opencos/tools/vivado.py,sha256=reFkszeoA75niPodkGQmt7y52ZaRNt_smRnC1QeJO6M,41020
83
+ opencos/tools/yosys.py,sha256=7o7uUbqjwuYUC7joGk2GCE1YsmnQN_W-yCZP49yl0X4,26926
83
84
  opencos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
85
  opencos/utils/markup_helpers.py,sha256=A8Ev5UJ4EVKjdcF2g85SQbjdPZR4jGpNqCLaBy_4v7Q,4569
85
86
  opencos/utils/status_constants.py,sha256=na6YsqlsCwIYzTXWE14dPadUYRNTrOS6YTXHCer2NbA,635
86
- opencos/utils/str_helpers.py,sha256=1VUBL9Q09eBDpTvLarhaQoJOLoi3IKOaFy2FHvKevEU,6270
87
+ opencos/utils/str_helpers.py,sha256=726ScK5-v7QkBi-zqESKZLsOl2_ya4vVJ5ZhxJqmBFo,6440
87
88
  opencos/utils/subprocess_helpers.py,sha256=xemAGPey6M0sWY_FElvr-Z0phCfdjaC-znP8FKihPaE,3535
88
89
  opencos/utils/vscode_helper.py,sha256=2YPjcDH_vTlwJvcITyMfvx8dLzPSRKzAvFRJz7BaJk8,1332
89
90
  opencos/utils/vsim_helper.py,sha256=2voGRZI2iAQ2Pv2ZI5g2why6xpgig-To8im-LVXtuDU,1517
90
- opencos_eda-0.2.54.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
91
- opencos_eda-0.2.54.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
92
- opencos_eda-0.2.54.dist-info/METADATA,sha256=Gn37sKvN_THH6F5LkbyNTe0b1RSgTtQIYy9oCUyodyg,635
93
- opencos_eda-0.2.54.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
- opencos_eda-0.2.54.dist-info/entry_points.txt,sha256=6n1T5NwVYDhN5l1h5zmyT197G4pE0SySDreB0QJzJR0,218
95
- opencos_eda-0.2.54.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
96
- opencos_eda-0.2.54.dist-info/RECORD,,
91
+ opencos_eda-0.2.55.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
92
+ opencos_eda-0.2.55.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
93
+ opencos_eda-0.2.55.dist-info/METADATA,sha256=8-uOG5UpKk0OjYY0GLER0e_KZ4RSBnzQC3jrxpwxolo,631
94
+ opencos_eda-0.2.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
95
+ opencos_eda-0.2.55.dist-info/entry_points.txt,sha256=6n1T5NwVYDhN5l1h5zmyT197G4pE0SySDreB0QJzJR0,218
96
+ opencos_eda-0.2.55.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
97
+ opencos_eda-0.2.55.dist-info/RECORD,,