opencos-eda 0.2.42__tar.gz → 0.2.43__tar.gz

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 (82) hide show
  1. {opencos_eda-0.2.42/opencos_eda.egg-info → opencos_eda-0.2.43}/PKG-INFO +1 -1
  2. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_base.py +47 -33
  3. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/helpers.py +1 -1
  4. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/verilator.py +4 -0
  5. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/util.py +32 -0
  6. {opencos_eda-0.2.42 → opencos_eda-0.2.43/opencos_eda.egg-info}/PKG-INFO +1 -1
  7. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/pyproject.toml +1 -1
  8. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/LICENSE +0 -0
  9. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/LICENSE.spdx +0 -0
  10. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/README.md +0 -0
  11. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/__init__.py +0 -0
  12. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/_version.py +0 -0
  13. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/_waves_pkg.sv +0 -0
  14. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/__init__.py +0 -0
  15. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/build.py +0 -0
  16. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/elab.py +0 -0
  17. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/export.py +0 -0
  18. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/flist.py +0 -0
  19. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/multi.py +0 -0
  20. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/open.py +0 -0
  21. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/proj.py +0 -0
  22. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/sim.py +0 -0
  23. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/sweep.py +0 -0
  24. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/synth.py +0 -0
  25. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/targets.py +0 -0
  26. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/upload.py +0 -0
  27. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/commands/waves.py +0 -0
  28. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/deps_helpers.py +0 -0
  29. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/deps_schema.py +0 -0
  30. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda.py +0 -0
  31. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_config.py +0 -0
  32. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_config_defaults.yml +0 -0
  33. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_config_max_verilator_waivers.yml +0 -0
  34. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_config_reduced.yml +0 -0
  35. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_deps_bash_completion.bash +0 -0
  36. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_extract_targets.py +0 -0
  37. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/eda_tool_helper.py +0 -0
  38. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/export_helper.py +0 -0
  39. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/export_json_convert.py +0 -0
  40. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/files.py +0 -0
  41. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/names.py +0 -0
  42. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/oc_cli.py +0 -0
  43. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/pcie.py +0 -0
  44. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/peakrdl_cleanup.py +0 -0
  45. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/seed.py +0 -0
  46. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/__init__.py +0 -0
  47. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/custom_config.yml +0 -0
  48. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
  49. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
  50. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
  51. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
  52. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
  53. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
  54. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
  55. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_build.py +0 -0
  56. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_deps_helpers.py +0 -0
  57. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_deps_schema.py +0 -0
  58. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_eda.py +0 -0
  59. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_eda_elab.py +0 -0
  60. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_eda_synth.py +0 -0
  61. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_oc_cli.py +0 -0
  62. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tests/test_tools.py +0 -0
  63. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/__init__.py +0 -0
  64. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/invio.py +0 -0
  65. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/invio_helpers.py +0 -0
  66. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/invio_yosys.py +0 -0
  67. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/iverilog.py +0 -0
  68. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/modelsim_ase.py +0 -0
  69. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/questa.py +0 -0
  70. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/riviera.py +0 -0
  71. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/slang.py +0 -0
  72. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/slang_yosys.py +0 -0
  73. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/surelog.py +0 -0
  74. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/tabbycad_yosys.py +0 -0
  75. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/vivado.py +0 -0
  76. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos/tools/yosys.py +0 -0
  77. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos_eda.egg-info/SOURCES.txt +0 -0
  78. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos_eda.egg-info/dependency_links.txt +0 -0
  79. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos_eda.egg-info/entry_points.txt +0 -0
  80. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos_eda.egg-info/requires.txt +0 -0
  81. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/opencos_eda.egg-info/top_level.txt +0 -0
  82. {opencos_eda-0.2.42 → opencos_eda-0.2.43}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.42
3
+ Version: 0.2.43
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
@@ -696,6 +696,7 @@ class CommandDesign(Command):
696
696
 
697
697
  self.cached_deps = {} # key = abspath of DEPS markup file, has sub-dicts for 'data' and 'line_numbers'.
698
698
  self.targets_dict = {} # key = targets that we've already processed in DEPS files
699
+ self.last_added_source_file_inferred_top = ''
699
700
 
700
701
  def run_dep_commands(self):
701
702
  # Run any shell@ commands from DEPS files
@@ -1036,6 +1037,11 @@ class CommandDesign(Command):
1036
1037
  file_ext = known_file_ext_dict.get(forced_extension, [''])[0]
1037
1038
  util.debug(f"{forced_extension=} for {filename=} as type '{file_ext}'")
1038
1039
 
1040
+
1041
+ if not add_to_non_sources and \
1042
+ file_ext in known_file_ext_dict.get('inferred_top', []):
1043
+ self.last_added_source_file_inferred_top = file_abspath
1044
+
1039
1045
  if add_to_non_sources:
1040
1046
  self.files_non_source.append(file_abspath)
1041
1047
  util.debug("Added non-source file file %s as %s" % (filename, file_abspath))
@@ -1114,8 +1120,8 @@ class CommandDesign(Command):
1114
1120
 
1115
1121
  # by this point hopefully this is a target ... is it a simple filename?
1116
1122
  remove_list = []
1117
- last_potential_top = None # used for 'top' if top not specified.
1118
- last_potential_top_path = None
1123
+ last_potential_top_file = ('', '') # (top, fpath)
1124
+ last_potential_top_target = ('', '') # (top, path/to/full-target-name)
1119
1125
  last_potential_top_isfile = False
1120
1126
  caller_info = ''
1121
1127
  for token in unparsed:
@@ -1131,21 +1137,13 @@ class CommandDesign(Command):
1131
1137
  else:
1132
1138
  self.add_file(filename=fpath, caller_info=caller_info,
1133
1139
  forced_extension=forced_extension)
1134
-
1135
- known_file_ext_dict = self.config.get('file_extensions', {})
1136
- if forced_extension:
1137
- # If forced_extension='systemverilog', then use the first known extension for
1138
- # it ('.sv', from eda_config_defaults.yml):
1139
- file_ext = known_file_ext_dict.get(forced_extension, [''])[0]
1140
-
1141
- if not self.args['top'] and \
1142
- file_ext and \
1143
- file_ext in known_file_ext_dict.get('inferred_top', []):
1144
- # if we haven't yet been given a top, or inferred one, we take the last one we get
1145
- # from a raw list of RTL file names (from args or command line tokens)
1146
- last_potential_top_path = file_abspath
1147
- last_potential_top = self.get_top_name(file_abspath)
1148
- last_potential_top_isfile = True
1140
+ if not self.args['top']:
1141
+ known_file_ext_dict = self.config.get('file_extensions', {})
1142
+ if forced_extension:
1143
+ file_ext = known_file_ext_dict.get(forced_extension, [''])[0]
1144
+ if file_ext in known_file_ext_dict.get('inferred_top', []):
1145
+ # last cmd line arg was a filename that could have inferred top.
1146
+ last_potential_top_isfile = True
1149
1147
 
1150
1148
  remove_list.append(token)
1151
1149
  continue # done with token, consume it, we added the file.
@@ -1158,12 +1156,9 @@ class CommandDesign(Command):
1158
1156
 
1159
1157
  util.debug(f'Calling self.resolve_target on {target_name=}')
1160
1158
  if self.resolve_target(target_name, caller_info=caller_info):
1161
- if self.args['top'] == '':
1162
- # if we haven't yet been given a top, or inferred one, we take the last named target
1163
- # from args or command line tokens
1164
- # from a target name
1165
- last_potential_top = self.get_top_name(target_name)
1166
- last_potential_top_path = target_name
1159
+ if not self.args['top']:
1160
+ # last cmd line arg was a target that we'll likely use for inferred top.
1161
+ last_potential_top_target = (self.get_top_name(target_name), target_name)
1167
1162
  last_potential_top_isfile = False
1168
1163
 
1169
1164
  remove_list.append(token)
@@ -1176,16 +1171,35 @@ class CommandDesign(Command):
1176
1171
  if process_all and len(unparsed) > 0:
1177
1172
  self.error(f"Didn't understand command remaining tokens {unparsed=} in CommandDesign")
1178
1173
 
1179
- # handle a missing self.args['top'] with last filepath.
1180
- if self.args.get('top', '') == '' and last_potential_top is not None:
1181
- self.args['top'] = last_potential_top
1182
- self.args['top-path'] = last_potential_top_path
1183
- util.info(f"Inferred --top {self.args['top']} {self.args['top-path']}")
1184
- if last_potential_top_isfile:
1185
- # top wasn't set, we're using the final command-line 'arg' filename (not from DEPS.yml)
1186
- # need to override self.target if that was set. Otherwise it won't save to the correct
1187
- # work-dir:
1188
- self.target = last_potential_top
1174
+ # handle a missing self.args['top'] with last filepath or last target:
1175
+ if not self.args.get('top', ''):
1176
+ if not last_potential_top_isfile and last_potential_top_target[0]:
1177
+ # If we have a target name from DEPS, prefer to use that.
1178
+ self.args['top'], self.args['top-path'] = last_potential_top_target
1179
+ util.info("--top not specified, inferred from target:",
1180
+ f"{self.args['top']} ({self.args['top-path']})")
1181
+
1182
+ else:
1183
+ best_top_fname = self.last_added_source_file_inferred_top
1184
+ if best_top_fname:
1185
+ last_potential_top_file = (self.get_top_name(best_top_fname), best_top_fname)
1186
+
1187
+ if not self.args['top'] and last_potential_top_file[0]:
1188
+ # If we don't have a target name, and no top name yet, then go looking for the
1189
+ # module name in the final source file added.
1190
+ self.args['top-path'] = last_potential_top_file[1] # from tuple: (top, fpath)
1191
+ self.args['top'] = util.get_inferred_top_module_name(
1192
+ module_guess=last_potential_top_file[0],
1193
+ module_fpath=last_potential_top_file[1]
1194
+ )
1195
+ if self.args['top']:
1196
+ util.info("--top not specified, inferred from final source file:",
1197
+ f"{self.args['top']} ({self.args['top-path']})")
1198
+ # If top wasn't set, and we're using the final command-line 'arg' filename
1199
+ # (not from DEPS.yml) we need to override self.target if that was set. Otherwise
1200
+ # it won't save to the correct work-dir:
1201
+ self.target = self.args['top']
1202
+
1189
1203
  if self.error_on_missing_top and not self.args.get('top', ''):
1190
1204
  self.error(f"Did not get a --top or DEPS top, required to run command",
1191
1205
  f"'{self.command_name}' for tool={self.args.get('tool', None)}")
@@ -19,7 +19,7 @@ def can_run_eda_command(*commands, config: dict) -> bool:
19
19
  if not handler:
20
20
  return False
21
21
  if handler and getattr(handler, 'CHECK_REQUIRES', []):
22
- if not all(isinstance(handler, x) for x in getattr(handler, 'CHECK_REQUIRES', [])):
22
+ if not all(issubclass(handler, x) for x in getattr(handler, 'CHECK_REQUIRES', [])):
23
23
  return False
24
24
  runnable.append(True)
25
25
  return runnable and all(runnable)
@@ -166,6 +166,10 @@ class VerilatorSim(CommandSim, ToolVerilator):
166
166
  # don't run this if we're stopping before/after compile/elab
167
167
  return
168
168
 
169
+ if not os.path.isfile(os.path.join(self.args['work-dir'], 'obj_dir', 'sim.exe')):
170
+ self.error('Verilated executable obj_dir/sim.exe does not exist')
171
+ return
172
+
169
173
  # Note that this is not returning a pass/fail bash return code,
170
174
  # so we will likely have to log-scrape to deterimine pass/fail.
171
175
  # Also, if we ran in cc-mode, we will not get the "R e p o r t: Verilator"
@@ -635,6 +635,38 @@ def write_eda_config_and_args(dirpath : str, filename='eda_output_config.yml', c
635
635
  yaml_safe_writer(data=data, filepath=fullpath)
636
636
 
637
637
 
638
+ def get_inferred_top_module_name(module_guess: str, module_fpath: str) -> str:
639
+ '''Returns the best guess as the 'top' module name name, given a fpath where
640
+
641
+ module_fpath = /some/path/to/module_guess.[v|sv]
642
+
643
+ Use the module_guess if it exists in the file as: module <module_guess>
644
+ Otherwise use the last observed: module <best_guess>
645
+ Otherwise use blank str
646
+ '''
647
+
648
+ best_guess = ''
649
+ if not os.path.isfile(module_fpath):
650
+ return ''
651
+ with open(module_fpath, encoding='utf-8') as f:
652
+ for line in f.readlines():
653
+ line = line.strip()
654
+ if line.startswith('module '):
655
+ parts = line.split()
656
+ module_name = parts[1]
657
+ rstrip_nonword_pattern = r'\W+$'
658
+ module_name = re.sub(rstrip_nonword_pattern, '', module_name)
659
+ if bool(re.fullmatch(r'^\w+$', module_name)):
660
+ if module_name == module_guess:
661
+ return module_guess
662
+ elif module_name:
663
+ best_guess = module_name
664
+ if best_guess:
665
+ return best_guess
666
+ else:
667
+ return ''
668
+
669
+
638
670
  def subprocess_run(work_dir, command_list, fake:bool=False, shell=False) -> int:
639
671
  ''' Run command_list in the foreground, with preference to use bash if shell=True.'''
640
672
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.42
3
+ Version: 0.2.43
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  [project]
4
4
  name = "opencos-eda"
5
- version = "0.2.42"
5
+ version = "0.2.43"
6
6
  dependencies = [
7
7
  # opencos/eda.py dependencies
8
8
  "mergedeep >= 1.3.4",
File without changes
File without changes
File without changes
File without changes