opencos-eda 0.3.0__py3-none-any.whl → 0.3.1__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/deps/deps_file.py CHANGED
@@ -287,7 +287,9 @@ class DepsFile:
287
287
  f'{targets_str}'))
288
288
 
289
289
 
290
- def lookup(self, target_node: str, caller_info: str) -> bool:
290
+ def lookup( # pylint: disable=too-many-branches
291
+ self, target_node: str, caller_info: str
292
+ ) -> bool:
291
293
  '''Returns True if the target_node is in the DEPS markup file. If not, error with
292
294
 
293
295
  some caller_info(str). This is more useful for YAML or TOML markup where we have
@@ -295,16 +297,20 @@ class DepsFile:
295
297
  '''
296
298
  if target_node not in self.data:
297
299
  found_target = False
298
- # For error printing, prefer relative paths:
299
- t_path = os.path.relpath(self.target_path) + os.path.sep
300
- t_node = target_node
301
- t_full = os.path.join(t_path, t_node)
302
300
 
303
301
  if target_node.startswith('-'):
304
302
  # likely an unparsed arg that made it this far.
305
303
  util.warning(f"Ignoring unparsed argument '{target_node}'")
306
304
  return False
307
305
 
306
+ # For error printing, prefer relative paths:
307
+ if self.target_path:
308
+ t_path = os.path.relpath(self.target_path) + os.path.sep
309
+ else:
310
+ t_path = ''
311
+ t_node = target_node
312
+ t_full = os.path.join(t_path, t_node)
313
+
308
314
  if not is_valid_target_name(target_node):
309
315
  util.warning(
310
316
  f"In file {self.rel_deps_file}, {target_node} {VALID_TARGET_INFO_STR}"
@@ -4,11 +4,13 @@ a DEPS markup files targets (applying deps, reqs, commands, tags, incdirs, defin
4
4
  CommandDesign ref object
5
5
  '''
6
6
 
7
+ import argparse
7
8
  import os
8
9
 
9
10
  from opencos import files
10
11
  from opencos import eda_config
11
- from opencos.util import debug, info, warning, error
12
+ from opencos.util import debug, info, warning, error, read_tokens_from_dot_f, \
13
+ patch_args_for_dir
12
14
  from opencos.utils.str_helpers import dep_str2list
13
15
  from opencos.deps.deps_file import deps_target_get_deps_list
14
16
  from opencos.deps.deps_commands import deps_commands_handler
@@ -48,6 +50,7 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
48
50
  self.target_path = target_path
49
51
  self.target_node = target_node # for debug
50
52
  self.deps_file = deps_file # for debug
53
+ self.deps_dir, _ = os.path.split(deps_file)
51
54
  self.caller_info = caller_info
52
55
 
53
56
  assert isinstance(deps_entry, dict), \
@@ -150,7 +153,9 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
150
153
  return tokens
151
154
 
152
155
 
153
- def apply_args(self, args_list:list) -> list:
156
+ def apply_args( # pylint: disable=too-many-locals,too-many-branches
157
+ self, args_list:list
158
+ ) -> list:
154
159
  '''Given args_list, applies them to our self.command_design_ref obj
155
160
 
156
161
  This will return unparsed args that weren't in the self.command_design_ref.args keys
@@ -162,10 +167,54 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
162
167
  f"in {self.caller_info}")
163
168
  tokens = dep_str2list(args_list)
164
169
 
170
+ # patch args relative to the DEPS (if self.deps_dir exists) so things like
171
+ # --build-tcl=<file> for relative <file> works when calling targets from any directory.
172
+ tokens = patch_args_for_dir(
173
+ tokens=tokens, patch_dir=self.deps_dir, caller_info=self.caller_info
174
+ )
175
+
165
176
  # We're going to run an ArgumentParser here, which is not the most efficient
166
177
  # thing to do b/c it runs on all of self.command_design_ref.args (dict) even
167
178
  # if we're applying a single token.
168
179
 
180
+ # Since some args (util.py, eda_config.py, eda.py) can only be handled from command
181
+ # line, it would be nice if -f or --input-file is handled from DEPS, so we'll special
182
+ # case that now. Recursively resolve -f / --input-file.
183
+ parser = argparse.ArgumentParser(
184
+ prog='deps_processor -f/--input-file', add_help=False, allow_abbrev=False
185
+ )
186
+ parser.add_argument('-f', '--input-file', default=[], action='append',
187
+ help=(
188
+ 'Input .f file to be expanded as eda args, defines, incdirs,'
189
+ ' files, or targets.'
190
+ ))
191
+ try:
192
+ parsed, unparsed = parser.parse_known_args(tokens + [''])
193
+ tokens2 = list(filter(None, unparsed))
194
+ except argparse.ArgumentError:
195
+ error('deps_processor -f/--input-file, problem attempting to parse_known_args for:',
196
+ f'{tokens}')
197
+ tokens2 = tokens
198
+
199
+ if parsed.input_file:
200
+ dotf_tokens = []
201
+ for filepath in parsed.input_file:
202
+ # Since this isn't command line, we have to assume the path is relative
203
+ # to this DEPS file.
204
+ if not os.path.isabs(filepath):
205
+ filepath = os.path.join(self.deps_dir, filepath)
206
+ dotf_tokens.extend(read_tokens_from_dot_f(
207
+ filepath=filepath, caller_info=self.caller_info, verbose=True
208
+ ))
209
+
210
+ # put the .f files before the unparsed args.
211
+ tokens2 = dotf_tokens + tokens2
212
+
213
+ # recurse until we've resolved nested .f files.
214
+ return self.apply_args(args_list=tokens2)
215
+
216
+ tokens = tokens2 # if no --input-file values, keep parsing the remaining tokens2
217
+
169
218
  # We have to special-case anything with --tool[=value] in tokens, otherwise
170
219
  # the user may think they were allowed to set --tool, but in our flow the Command handler
171
220
  # (self.command_design_ref) has already been chosen, so setting the tool can have
@@ -180,11 +229,38 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
180
229
  _, unparsed = self.command_design_ref.run_argparser_on_list(
181
230
  tokens=tokens
182
231
  )
232
+
183
233
  # Annoying, but check for plusargs in unparsed, and have referenced CommandDesign
184
234
  # or CommandSim class handle it with process_plusarg.
185
- for arg in unparsed:
235
+ for arg in list(unparsed):
186
236
  if arg.startswith('+'):
187
237
  self.command_design_ref.process_plusarg(plusarg=arg, pwd=self.target_path)
238
+ unparsed.remove(arg)
239
+
240
+ # For any leftover files, or targets, attempt to process those too:
241
+ for arg in list(unparsed):
242
+ # Since this isn't command line, we have to assume for files, the path is relative
243
+ # to this DEPS file.
244
+ if os.path.isabs(arg):
245
+ target = arg
246
+ else:
247
+ target = os.path.join(self.deps_dir, arg)
248
+
249
+ file_exists, fpath, forced_extension = files.get_source_file(target)
250
+ if file_exists:
251
+ _, file_ext = os.path.splitext(fpath)
252
+ if forced_extension or file_ext:
253
+ self.command_design_ref.add_file(fpath, caller_info=self.caller_info,
254
+ forced_extension=forced_extension)
255
+ unparsed.remove(arg)
256
+
257
+ else:
258
+ if not os.path.isdir(target) and \
259
+ self.command_design_ref.resolve_target_core(
260
+ target=target, no_recursion=False, caller_info=self.caller_info,
261
+ error_on_not_found=False
262
+ ):
263
+ unparsed.remove(arg)
188
264
 
189
265
  if unparsed:
190
266
  # This is only a warning - because things like CommandFlist may not have every
opencos/eda_base.py CHANGED
@@ -230,6 +230,7 @@ class Command: # pylint: disable=too-many-public-methods
230
230
  'enable-tags': [],
231
231
  'disable-tags': [],
232
232
  'test-mode': False,
233
+ 'error-unknown-args': True,
233
234
  })
234
235
  self.args_help.update({
235
236
  'stop-before-compile': ('stop this run before any compile (if possible for tool) and'
@@ -249,6 +250,7 @@ class Command: # pylint: disable=too-many-public-methods
249
250
  ' --disable-tags has higher precedence than --enable-tags.'),
250
251
  'test-mode': ('command and tool dependent, usually stops the command early without'
251
252
  ' executing.'),
253
+ 'error-unknown-args': 'Enable errors on unknown/unparsable args',
252
254
  })
253
255
  self.modified_args = {}
254
256
  self.config = copy.deepcopy(config) # avoid external modifications.
@@ -495,9 +497,10 @@ class Command: # pylint: disable=too-many-public-methods
495
497
 
496
498
  # Do some minimal type handling, preserving the type(self.args[key])
497
499
  if key not in self.args:
498
- self.error(f'set_arg, {key=} not in self.args {value=}',
499
- f'({self.command_name=}, {self.__class__.__name__=})',
500
- error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
500
+ self.error_unknown_arg(
501
+ f'set_arg, {key=} not in self.args {value=}',
502
+ f'({self.command_name=}, {self.__class__.__name__=})'
503
+ )
501
504
 
502
505
  cur_value = self.args[key]
503
506
 
@@ -692,9 +695,10 @@ class Command: # pylint: disable=too-many-public-methods
692
695
  _, unparsed = self.run_argparser_on_list(tokens)
693
696
  if process_all and unparsed:
694
697
  self.warning_show_known_args()
695
- self.error(f"Didn't understand argument: '{unparsed=}' in",
696
- f" {self.command_name=} context, {pwd=}",
697
- error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
698
+ self.error_unknown_arg(
699
+ f"Didn't understand argument: '{unparsed=}' in",
700
+ f"{self.command_name=} context, {pwd=}"
701
+ )
698
702
 
699
703
  return unparsed
700
704
 
@@ -910,6 +914,16 @@ class Command: # pylint: disable=too-many-public-methods
910
914
  lines.append(self.pretty_str_known_args(command=commands[-1])) # use last command if > 1
911
915
  util.warning("\n".join(lines))
912
916
 
917
+ def error_unknown_arg(self, *msg) -> None:
918
+ '''For errors involving an unknown --arg, they can be optionally disabled
919
+
920
+ using --no-error-unknown-args
921
+ '''
922
+ if self.args['error-unknown-args']:
923
+ self.error(*msg, error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
924
+ else:
925
+ util.warning(*msg)
926
+
913
927
 
914
928
  class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
915
929
  '''CommandDesign is the eda base class for command handlers that need to track files.
@@ -1392,7 +1406,8 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1392
1406
  return self.resolve_target_core(target, no_recursion, caller_info)
1393
1407
 
1394
1408
  def resolve_target_core( # pylint: disable=too-many-locals,too-many-branches
1395
- self, target: str, no_recursion: bool, caller_info: str = ''
1409
+ self, target: str, no_recursion: bool, caller_info: str = '',
1410
+ error_on_not_found: bool = True
1396
1411
  ) -> bool:
1397
1412
  '''Returns True if target is found. recursive point for resolving path or DEPS markup
1398
1413
  target names.'''
@@ -1481,14 +1496,14 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1481
1496
  self.add_file(try_file, caller_info=f'n/a::{target}::n/a')
1482
1497
  found_target = True
1483
1498
  break # move on to the next target
1484
- if not found_target: # if STILL not found_this_target...
1499
+ if not found_target and error_on_not_found: # if STILL not found_this_target...
1485
1500
  self.error(f"Unable to resolve {target=}",
1486
1501
  error_code=status_constants.EDA_DEPS_TARGET_NOT_FOUND)
1487
1502
 
1488
1503
  # if we've found any target since being called, it means we found the one we were called for
1489
1504
  return found_target
1490
1505
 
1491
- def add_file(
1506
+ def add_file( # pylint: disable=too-many-locals,too-many-branches
1492
1507
  self, filename: str, use_abspath: bool = True, add_to_non_sources: bool = False,
1493
1508
  caller_info: str = '', forced_extension: str = ''
1494
1509
  ) -> str:
@@ -1512,6 +1527,7 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1512
1527
  vhdl_file_ext_list = known_file_ext_dict.get('vhdl', [])
1513
1528
  cpp_file_ext_list = known_file_ext_dict.get('cpp', [])
1514
1529
  sdc_file_ext_list = known_file_ext_dict.get('synth_constraints', [])
1530
+ dotf_file_ext_list = known_file_ext_dict.get('dotf', [])
1515
1531
 
1516
1532
  if forced_extension:
1517
1533
  # If forced_extension='systemverilog', then use the first known extension for
@@ -1544,6 +1560,13 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1544
1560
  elif file_ext in sdc_file_ext_list:
1545
1561
  self.files_sdc.append(file_abspath)
1546
1562
  util.debug(f"Added SDC file {filename} as {file_abspath}")
1563
+ elif file_ext in dotf_file_ext_list:
1564
+ # a stray .f file as a source file, sure why not support it:
1565
+ dp = DepsProcessor(command_design_ref=self, deps_entry={}, target='',
1566
+ target_path='', target_node='', deps_file='',
1567
+ caller_info=caller_info)
1568
+ dp.apply_args(args_list=[f'-f={file_abspath}'])
1569
+ del dp
1547
1570
  else:
1548
1571
  # unknown file extension. In these cases we link the file to the working directory
1549
1572
  # so it is available (for example, a .mem file that is expected to exist with relative
@@ -1637,9 +1660,10 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1637
1660
  if process_all and possible_unparsed_args:
1638
1661
  _tool = self.safe_which_tool()
1639
1662
  self.warning_show_known_args()
1640
- self.error(f"Didn't understand unparsed args: {possible_unparsed_args}, for command",
1641
- f"'{self.command_name}', tool '{_tool}'",
1642
- error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
1663
+ self.error_unknown_arg(
1664
+ f"Didn't understand unparsed args: {possible_unparsed_args}, for command",
1665
+ f"'{self.command_name}', tool '{_tool}'"
1666
+ )
1643
1667
 
1644
1668
  remove_list = []
1645
1669
  last_potential_top_file = ('', '') # (top, fpath)
@@ -1697,9 +1721,10 @@ class CommandDesign(Command): # pylint: disable=too-many-instance-attributes
1697
1721
  # we were unable to figure out what this command line token is for...
1698
1722
  if process_all and unparsed:
1699
1723
  self.warning_show_known_args()
1700
- self.error(f"Didn't understand remaining args or targets {unparsed=} for command",
1701
- f"'{self.command_name}'",
1702
- error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
1724
+ self.error_unknown_arg(
1725
+ f"Didn't understand remaining args or targets {unparsed=} for command",
1726
+ f"'{self.command_name}'"
1727
+ )
1703
1728
 
1704
1729
  # handle a missing self.args['top'] with last filepath or last target:
1705
1730
  if not self.args.get('top', ''):
@@ -2244,9 +2269,10 @@ class CommandParallel(Command):
2244
2269
  bad_remaining_args = [x for x in single_cmd_unparsed if x.startswith('-')]
2245
2270
  if bad_remaining_args:
2246
2271
  self.warning_show_known_args(command=f'{self.command_name} {command}')
2247
- self.error(f'for {self.command_name} {command=} the following args are unknown',
2248
- f'{bad_remaining_args}',
2249
- error_code=status_constants.EDA_COMMAND_OR_ARGS_ERROR)
2272
+ self.error_unknown_arg(
2273
+ f'for {self.command_name} {command=} the following args are unknown',
2274
+ f'{bad_remaining_args}'
2275
+ )
2250
2276
 
2251
2277
  # Remove unparsed args starting with '+', since those are commonly sent downstream to
2252
2278
  # single job (example, CommandSim plusargs).
@@ -91,6 +91,9 @@ file_extensions:
91
91
  synth_constraints:
92
92
  - .sdc
93
93
  - .xdc
94
+ dotf:
95
+ - .f
96
+ - .vc
94
97
 
95
98
  inferred_top:
96
99
  # file extensions that we can infer "top" module from, if --top omitted.
opencos/files.py CHANGED
@@ -24,6 +24,7 @@ FORCE_PREFIX_DICT = {
24
24
  'vhdl@': 'vhdl',
25
25
  'cpp@': 'cpp',
26
26
  'sdc@': 'synth_constraints',
27
+ 'f@': 'dotf'
27
28
  }
28
29
 
29
30
  ALL_FORCED_PREFIXES = set(list(FORCE_PREFIX_DICT.keys()))
opencos/tests/helpers.py CHANGED
@@ -171,6 +171,7 @@ class Helpers:
171
171
  '''Changes directory to self.DEFAULT_DIR and removes eda.work, eda.export paths'''
172
172
  chdir_remove_work_dir('', self.DEFAULT_DIR)
173
173
 
174
+
174
175
  def _resolve_logfile(self, logfile=None) -> str:
175
176
  '''Returns the logfile's filepath'''
176
177
  ret = logfile
@@ -232,7 +233,7 @@ class Helpers:
232
233
  return rc
233
234
 
234
235
  def is_in_log(self, *want_str, logfile=None, windows_path_support=False):
235
- '''Check if any of want_str args are in the logfile, or self.DEFAULT_LOG'''
236
+ '''Check if want_str (joined) is in the logfile, or self.DEFAULT_LOG'''
236
237
  logfile = self._resolve_logfile(logfile)
237
238
  want_str0 = ' '.join(list(want_str))
238
239
  want_str1 = want_str0.replace('/', '\\')
opencos/util.py CHANGED
@@ -435,25 +435,67 @@ def load_env_file(env_file: str) -> None:
435
435
  else:
436
436
  warning(f'--env-file {env_file} does not exist and is not loaded.')
437
437
 
438
- def read_tokens_from_dot_f(filepath: str) -> list:
438
+ def patch_args_for_dir(tokens: list, patch_dir: str, caller_info: str) -> list:
439
+ '''Given list of args, attempt to correct for relative dir'''
440
+
441
+ # deal with relative path args or files.
442
+ # Note the dot-f file could have been in a different directory (-f=path/to/my.f)
443
+ # As a workaround to deal with relative paths, attempt to replace relative
444
+ # path args within this dotf contents - so they are relative the dotf dir:
445
+ if not os.path.isdir(patch_dir):
446
+ return tokens
447
+
448
+ ret = []
449
+ for word in tokens:
450
+ if word.startswith('-') and '=' in word:
451
+ parts = word.split('=')
452
+ leftarg = parts[0] + '='
453
+ word = '='.join(parts[1:])
454
+ elif word.startswith('+incdir+'):
455
+ # do for +incdir+ too
456
+ leftarg = '+incdir+'
457
+ word = word[len('+incdir+'):]
458
+ else:
459
+ leftarg = ''
460
+
461
+ if word and not os.path.isabs(word) and \
462
+ os.path.exists(os.path.join(patch_dir, word)):
463
+ # fix relative path of word, or --arg=word
464
+ word = os.path.abspath(os.path.join(patch_dir, word))
465
+ info(f'Using relative path {patch_dir} for arg/token: {leftarg}{word}',
466
+ f'{caller_info}')
467
+ ret.append(f'{leftarg}{word}')
468
+ return ret
469
+
470
+ def read_tokens_from_dot_f(filepath: str, caller_info: str = '', verbose: bool = False) -> list:
439
471
  '''Returns list of tokens from a .f file, with ENV vars expanded'''
440
472
 
441
473
  # Let's defer 'info' printing out what input files were opened until after
442
474
  # args['quiet'] and debug is resolved (which may be in these .f files)
443
- debug(f"Opening -f / --input-file '{filepath}' for contents")
475
+ start_str = f"Opening -f / --input-file '{filepath}' for contents {caller_info}"
476
+ if verbose:
477
+ info(start_str)
478
+ else:
479
+ debug(start_str)
444
480
  if not os.path.isfile(filepath):
445
- error(f'-f (or --input-file): {filepath} does not exist',
481
+ error(f'-f (or --input-file): {filepath} does not exist {caller_info}',
446
482
  error_code=status_constants.EDA_GENERAL_FILE_NOT_FOUND)
447
483
  return []
448
484
  if os.path.abspath(filepath) in dot_f_files_expanded:
449
485
  error(f'-f (or --input-file): {filepath} has already been expanded',
450
- 'cannot traverse again (duplicate arg or nested .f files)')
486
+ f'cannot traverse again (duplicate arg or nested .f files) {caller_info}')
451
487
  dot_f_files_expanded.add(os.path.abspath(filepath))
452
488
  tokens = []
489
+ dotf_file_dir, _ = os.path.split(filepath)
453
490
  with open(filepath, encoding='utf-8') as f:
454
491
  for line in f:
455
492
  line = os.path.expandvars(line.strip())
456
- tokens.extend(line.split())
493
+ if not line or line.startswith('#') or line.startswith('//'):
494
+ continue
495
+ words = line.split()
496
+ tokens.extend(patch_args_for_dir(
497
+ tokens=words, patch_dir=dotf_file_dir, caller_info=f"(from dotf {filepath})"
498
+ ))
457
499
  return tokens
458
500
 
459
501
 
@@ -471,7 +513,7 @@ def process_debug_args(parsed: argparse.Namespace) -> None:
471
513
 
472
514
 
473
515
  def process_tokens( # pylint: disable=too-many-branches
474
- tokens: list
516
+ tokens: list, caller_info: str = ''
475
517
  ) -> (argparse.Namespace, list):
476
518
  '''Processes tokens (unparsed args list) on util's ArgumentParser
477
519
 
@@ -517,13 +559,15 @@ def process_tokens( # pylint: disable=too-many-branches
517
559
  if parsed.input_file:
518
560
  dotf_tokens = []
519
561
  for filepath in parsed.input_file:
520
- dotf_tokens.extend(read_tokens_from_dot_f(filepath))
562
+ dotf_tokens.extend(read_tokens_from_dot_f(
563
+ filepath=filepath, caller_info=caller_info
564
+ ))
521
565
 
522
566
  # put the .f files before the unparsed args.
523
567
  tokens2 = dotf_tokens + tokens2
524
568
 
525
569
  # recurse until we've resolved nested .f files.
526
- return process_tokens(tokens=tokens2)
570
+ return process_tokens(tokens=tokens2, caller_info=f'(from {parsed.input_file[-1]})')
527
571
 
528
572
 
529
573
  # Continue with all normal parsing beyond --debug and -f/--input-file,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.3.0
3
+ Version: 0.3.1
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
@@ -3,9 +3,9 @@ opencos/_version.py,sha256=KaWIjS0c08g-C0fgYY1kXwSPqhOFxaq5pYEeoZhOR_I,617
3
3
  opencos/_waves_pkg.sv,sha256=TL5YT9lT-fn2FD54MbVVZROmZ7vtW3ScA_rM2eRzKmU,2068
4
4
  opencos/deps_schema.py,sha256=VUdXuq43mKfM-U4x7DSA28-MH1Xqxre6V7Ttw2DeOqI,16762
5
5
  opencos/eda.py,sha256=91E-EsyZS-uRadApP-h2onW6rpvLBnrpJoT_9tRtsS8,23322
6
- opencos/eda_base.py,sha256=oJ8ISAN6IykQfun8eVNuzjggQ5RvIKeWwQ85Wv4ww_4,107887
6
+ opencos/eda_base.py,sha256=Spt_Ssq5aVZ6L_J1koaDMB1jo81srIStwl9KMG5_irU,108740
7
7
  opencos/eda_config.py,sha256=z3yQOPGBX7-yKp6BdQYfJ9eOJf-Jctl-mwCDj3vj2BI,12712
8
- opencos/eda_config_defaults.yml,sha256=u1kzmclo5nElsn2BHOIYHk9_djbL0rUts4CLWYJbuc8,16036
8
+ opencos/eda_config_defaults.yml,sha256=LF0yAncYeaPtZIoAfEeo2aiDXT4cjYa99soGks0WRzM,16063
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
@@ -14,11 +14,11 @@ opencos/eda_extract_targets.py,sha256=POlxZfqf2dNH2nc1CEw5B_53vSHAicSTkpU9_-2_6Z
14
14
  opencos/eda_tool_helper.py,sha256=_YgobDLEWW6Fzdr976LxaCDZ4DKRyuMs5CrYQHaTPrU,2558
15
15
  opencos/export_helper.py,sha256=5BnrkhiieJBgYKAryhXD7HSGtrgvXQpZ8B5ltdrhbRY,22649
16
16
  opencos/export_json_convert.py,sha256=tSIMbLFtc_Fo66EhFovMii1v_qJYyFZJrPNnoPdW7L0,4182
17
- opencos/files.py,sha256=aoq0O2KfISzZb-Vi_q_0TTGBER9xJc--FkVZf0ga7pA,1549
17
+ opencos/files.py,sha256=AQOnsrvoc0r76LiFrkoMbwOGdUO1FpBiFY_jyyI_ve8,1566
18
18
  opencos/names.py,sha256=Y2aJ5wgpbNIJ-_P5xUXnHMv_h-zMOX2Rt6iLuduqC1Q,1213
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=KK5_lSKSf8O6Wp-CtQ9bTg-izBEPkuxGh_N64DJhE-0,40038
21
+ opencos/util.py,sha256=ffaSoDDOsL6mx_fYgAyJA8fawsxZ5YHKqs67b8iW5rw,41921
22
22
  opencos/commands/__init__.py,sha256=oOOQmn5_jHAMSOfA3swJJ7mdoyHsJA0lJwKPTudlTns,1125
23
23
  opencos/commands/build.py,sha256=mvJYxk5J15k0Cr8R7oIdIIdsEtWV3gE-LnPweVwtSDo,1487
24
24
  opencos/commands/deps_help.py,sha256=WDrU7H9sypzDAxe_CHqhW5B_scbQMzBEdf-v-Jcfd5Q,10682
@@ -40,14 +40,14 @@ opencos/commands/waves.py,sha256=nrp3ALwfJujZns44tgCgia_dEedQyKe0T3fuws8h39U,769
40
40
  opencos/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  opencos/deps/defaults.py,sha256=NXh3V4oInrBVlDw64B2OCI77wzdn1NtaD64srhBnmZU,1486
42
42
  opencos/deps/deps_commands.py,sha256=q4JfSfzRO2nM2zdNT4enCy33FokEytZYQJn1HJ6osJk,16606
43
- opencos/deps/deps_file.py,sha256=nVZWrq6PVhWig1yMNpy8w_7LQJ1rgb7Js0N1ngoqLio,16306
44
- opencos/deps/deps_processor.py,sha256=i8R6lNSVc_ybTnC16qmGevB3Y-pkcbxkZaT04HTLE8Y,37890
43
+ opencos/deps/deps_file.py,sha256=36KvkixS_TcIjetpvJEmYpkdaYhuY42aVi7WvV3Qtw8,16445
44
+ opencos/deps/deps_processor.py,sha256=DBaMUEnpoIL4xaNPs2f2AFGcWLST5pP_Qgup9r-8D7M,41403
45
45
  opencos/hw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  opencos/hw/oc_cli.py,sha256=U1JGlshLZhtd0LgndZFBZVltAj_HemdhbjO_Zo8ZuVM,132252
47
47
  opencos/hw/pcie.py,sha256=VUJljaZJYgScAAx5yn7F6GoA8K9eTcw24otYZbkMpYs,3035
48
48
  opencos/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  opencos/tests/custom_config.yml,sha256=TRoVM9ZFKPOA_8JmlpzaMhnGO1txmaD14N_8P1oqzew,257
50
- opencos/tests/helpers.py,sha256=9KHSZ1JMmo2nUbJYiRehmNqd1mNQ29XbzReu_tHkxjk,11234
50
+ opencos/tests/helpers.py,sha256=fs7GRlCJWj_uwwilikKI6R9tbozgGH5Uxi6_qqvEEwc,11231
51
51
  opencos/tests/test_build.py,sha256=FQAxOpLVQShAHD_L5rqJctPeSAoqoOCNFI0RXflLuY0,387
52
52
  opencos/tests/test_deps_helpers.py,sha256=uQZxleh6aKO-mZQhagHh5xLIBbpQ8dav7-5D0eemq_g,8164
53
53
  opencos/tests/test_deps_schema.py,sha256=T3P9KjaMyKsk8b7snNVvNSsom2hIJcg6Z9apYiXoH9Y,941
@@ -88,10 +88,10 @@ opencos/utils/str_helpers.py,sha256=726ScK5-v7QkBi-zqESKZLsOl2_ya4vVJ5ZhxJqmBFo,
88
88
  opencos/utils/subprocess_helpers.py,sha256=xemAGPey6M0sWY_FElvr-Z0phCfdjaC-znP8FKihPaE,3535
89
89
  opencos/utils/vscode_helper.py,sha256=9nHyMUIL-gzfW-qLH06sgaCnVK-YTOtu6pusitNNhL8,1363
90
90
  opencos/utils/vsim_helper.py,sha256=1johPOGbjbMgnCDSTpgsQcSuAquiqq1Y2MBxS6WY6b4,1552
91
- opencos_eda-0.3.0.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
92
- opencos_eda-0.3.0.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
93
- opencos_eda-0.3.0.dist-info/METADATA,sha256=KFNlElAF1mTMOenvOMpVfD5MRlIj1shxNBUiFGTuTQM,666
94
- opencos_eda-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
95
- opencos_eda-0.3.0.dist-info/entry_points.txt,sha256=6n1T5NwVYDhN5l1h5zmyT197G4pE0SySDreB0QJzJR0,218
96
- opencos_eda-0.3.0.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
97
- opencos_eda-0.3.0.dist-info/RECORD,,
91
+ opencos_eda-0.3.1.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
92
+ opencos_eda-0.3.1.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
93
+ opencos_eda-0.3.1.dist-info/METADATA,sha256=Gc70L29pHLuc43gNk0yJw3-dGE98LYbpu-o7FdLM4sw,666
94
+ opencos_eda-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
95
+ opencos_eda-0.3.1.dist-info/entry_points.txt,sha256=6n1T5NwVYDhN5l1h5zmyT197G4pE0SySDreB0QJzJR0,218
96
+ opencos_eda-0.3.1.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
97
+ opencos_eda-0.3.1.dist-info/RECORD,,