opencos-eda 0.3.5__tar.gz → 0.3.7__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 (102) hide show
  1. {opencos_eda-0.3.5/opencos_eda.egg-info → opencos_eda-0.3.7}/PKG-INFO +5 -2
  2. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/flist.py +2 -2
  3. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/multi.py +4 -3
  4. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/sim.py +28 -9
  5. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps/deps_processor.py +13 -2
  6. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda.py +23 -20
  7. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_base.py +224 -90
  8. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_config.py +2 -1
  9. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_config_defaults.yml +5 -1
  10. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/export_helper.py +89 -31
  11. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/files.py +3 -1
  12. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/command_order/DEPS.yml +13 -0
  13. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/helpers.py +32 -22
  14. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_eda.py +1 -1
  15. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_tools.py +9 -3
  16. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/cocotb.py +94 -21
  17. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/verilator.py +6 -4
  18. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/yosys.py +3 -3
  19. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/util.py +100 -55
  20. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/subprocess_helpers.py +23 -6
  21. {opencos_eda-0.3.5 → opencos_eda-0.3.7/opencos_eda.egg-info}/PKG-INFO +5 -2
  22. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos_eda.egg-info/requires.txt +5 -1
  23. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/pyproject.toml +8 -2
  24. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/LICENSE +0 -0
  25. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/LICENSE.spdx +0 -0
  26. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/README.md +0 -0
  27. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/__init__.py +0 -0
  28. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/_version.py +0 -0
  29. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/_waves_pkg.sv +0 -0
  30. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/__init__.py +0 -0
  31. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/build.py +0 -0
  32. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/deps_help.py +0 -0
  33. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/elab.py +0 -0
  34. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/export.py +0 -0
  35. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/lec.py +0 -0
  36. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/lint.py +0 -0
  37. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/open.py +0 -0
  38. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/proj.py +0 -0
  39. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/shell.py +0 -0
  40. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/sweep.py +0 -0
  41. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/synth.py +0 -0
  42. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/targets.py +0 -0
  43. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/upload.py +0 -0
  44. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/commands/waves.py +0 -0
  45. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps/__init__.py +0 -0
  46. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps/defaults.py +0 -0
  47. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps/deps_commands.py +0 -0
  48. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps/deps_file.py +0 -0
  49. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/deps_schema.py +0 -0
  50. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_config_max_verilator_waivers.yml +0 -0
  51. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_config_reduced.yml +0 -0
  52. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_deps_bash_completion.bash +0 -0
  53. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_deps_sanitize.py +0 -0
  54. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_extract_targets.py +0 -0
  55. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/eda_tool_helper.py +0 -0
  56. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/export_json_convert.py +0 -0
  57. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/hw/__init__.py +0 -0
  58. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/hw/oc_cli.py +0 -0
  59. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/hw/pcie.py +0 -0
  60. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/names.py +0 -0
  61. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/peakrdl_cleanup.py +0 -0
  62. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/seed.py +0 -0
  63. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/__init__.py +0 -0
  64. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/custom_config.yml +0 -0
  65. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
  66. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
  67. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
  68. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
  69. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
  70. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
  71. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_build.py +0 -0
  72. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_deps_helpers.py +0 -0
  73. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_deps_schema.py +0 -0
  74. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_eda_elab.py +0 -0
  75. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_eda_synth.py +0 -0
  76. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tests/test_oc_cli.py +0 -0
  77. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/__init__.py +0 -0
  78. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/invio.py +0 -0
  79. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/invio_helpers.py +0 -0
  80. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/invio_yosys.py +0 -0
  81. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/iverilog.py +0 -0
  82. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/modelsim_ase.py +0 -0
  83. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/quartus.py +0 -0
  84. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/questa.py +0 -0
  85. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/questa_fse.py +0 -0
  86. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/riviera.py +0 -0
  87. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/slang.py +0 -0
  88. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/slang_yosys.py +0 -0
  89. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/surelog.py +0 -0
  90. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/tabbycad_yosys.py +0 -0
  91. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/tools/vivado.py +0 -0
  92. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/__init__.py +0 -0
  93. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/markup_helpers.py +0 -0
  94. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/status_constants.py +0 -0
  95. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/str_helpers.py +0 -0
  96. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/vscode_helper.py +0 -0
  97. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos/utils/vsim_helper.py +0 -0
  98. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos_eda.egg-info/SOURCES.txt +0 -0
  99. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos_eda.egg-info/dependency_links.txt +0 -0
  100. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos_eda.egg-info/entry_points.txt +0 -0
  101. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/opencos_eda.egg-info/top_level.txt +0 -0
  102. {opencos_eda-0.3.5 → opencos_eda-0.3.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.3.5
3
+ Version: 0.3.7
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
@@ -16,11 +16,14 @@ Requires-Dist: schema>=0.7.7
16
16
  Requires-Dist: toml>=0.10.2
17
17
  Requires-Dist: yamllint>=1.35.1
18
18
  Requires-Dist: PySerial>=3.5
19
- Requires-Dist: cocotb>=2.0
20
19
  Requires-Dist: supports_color>=0.2.0
21
20
  Provides-Extra: dev
22
21
  Requires-Dist: pylint>=3.0.0; extra == "dev"
23
22
  Requires-Dist: pytest>=8.3.5; extra == "dev"
23
+ Provides-Extra: cocotb
24
+ Requires-Dist: cocotb>=2.0; extra == "cocotb"
25
+ Requires-Dist: pytest>=8.3.5; extra == "cocotb"
26
+ Requires-Dist: coverage>=7.6.1; extra == "cocotb"
24
27
  Provides-Extra: docs
25
28
  Requires-Dist: mkdocs; extra == "docs"
26
29
  Requires-Dist: mkdocs-material; extra == "docs"
@@ -48,7 +48,7 @@ class CommandFList(CommandDesign):
48
48
  'bracket-quote-path' : False,
49
49
  'single-quote-path' : False,
50
50
  'double-quote-path' : False,
51
- 'no-quote-path' : False,
51
+ 'quote-path' : True,
52
52
  'build-script' : "", # we don't want this to error either
53
53
 
54
54
  'print-to-stdout': False,
@@ -122,7 +122,7 @@ class CommandFList(CommandDesign):
122
122
 
123
123
  pq1 = ""
124
124
  pq2 = "" # pq = path quote
125
- if self.args['no-quote-path']:
125
+ if not self.args['quote-path']:
126
126
  pass # if we decide to make one of the below default, this will override
127
127
  elif self.args['bracket-quote-path']:
128
128
  pq1 = "{"
@@ -28,7 +28,7 @@ class CommandMulti(CommandParallel):
28
28
  'fake': False,
29
29
  'parallel': 1,
30
30
  'single-timeout': None,
31
- 'fail-if-no-targets': False,
31
+ 'fail-if-no-targets': True,
32
32
  'export-jsonl': False,
33
33
  'print-targets': False,
34
34
  }
@@ -325,8 +325,9 @@ class CommandMulti(CommandParallel):
325
325
  current_targets = len(self.targets)
326
326
  util.info(f"Multi: Expanded {target_globs} to {len(self.targets)} {command} targets")
327
327
 
328
- if parsed.fail_if_no_targets and len(self.targets) == 0:
329
- self.error(f'Multi: --fail-if-no-targets set, and {self.targets=}')
328
+ if self.args['fail-if-no-targets'] and not self.targets:
329
+ self.error(f'Multi: --fail-if-no-targets set, and {self.targets=}. Disable with',
330
+ '--no-fail-if-no-targets, or see: eda multi --help')
330
331
  if not all_multi_tools:
331
332
  possible_tools = self.all_handler_commands.get(command, [])
332
333
  self.error(f'Multi: no tools to run for {command=}, available tools: {possible_tools}')
@@ -59,11 +59,11 @@ class CommandSim(CommandDesign):
59
59
  self.args.update({
60
60
  "pre-sim-tcl": [],
61
61
  'compile-args': [],
62
+ 'compile-waivers': [],
62
63
  'elab-args': [],
63
64
  'sim-args': [],
64
65
  'sim-plusargs': [], # lists are handled by 'set_arg(k,v)' so they append.
65
66
  'sim-library': [],
66
- 'compile-waivers': [],
67
67
  'sim-waivers': [],
68
68
  'coverage': False,
69
69
  'waves': False,
@@ -78,7 +78,13 @@ class CommandSim(CommandDesign):
78
78
  'verilate-args': [],
79
79
  })
80
80
  self.args_help.update({
81
+ 'pre-sim-tcl': (
82
+ 'Tool dependent, TCL file to run prior to simulation (if tool supports TCL)'
83
+ ),
81
84
  'compile-args': 'args added to sim/elab "compile" step',
85
+ 'compile-waivers': (
86
+ 'simulation tool depenent waivers by name, applied at compilation step'
87
+ ),
82
88
  'coverage': 'attempt to run coverage steps on the compile/elab/simulation',
83
89
  'elab-args': 'args added to sim/elab "elaboration" step, if required by tool',
84
90
  'log-bad-strings': 'strings that if present in the log will fail the simulation',
@@ -90,6 +96,10 @@ class CommandSim(CommandDesign):
90
96
  'sim-args': 'args added to final "simulation" step',
91
97
  'sim-plusargs': ('"simulation" step run-time args passed to tool, these can also'
92
98
  ' be set using --sim-plusargs=name[=value], or simply +name[=value]'),
99
+ 'sim-library': 'named libraries added to simulation, tool dependent',
100
+ 'sim-waivers': (
101
+ 'simulation tool depenent waivers by name, applied at "simulation" step'
102
+ ),
93
103
  'stop-before-compile': ('Create work-dir sh scripts for compile/elab/simulate, but do'
94
104
  ' not run them.'),
95
105
  'stop-after-compile': 'Create work-dir sh scripts, but only run the compile step.',
@@ -97,10 +107,9 @@ class CommandSim(CommandDesign):
97
107
  ' simulation step.'),
98
108
  'top': 'Name of topmost Verilog/SystemVerilog module, or VHDL entity',
99
109
  'verilate-args': ('args added to "compile" step in Verilator simulation'
100
- ' (for --tool=verilator)'),
110
+ ' (for --tool=verilator) these are identical to --compile-args'),
101
111
  'waves': 'Include waveforms, if possible for tool',
102
112
  'waves-start': 'Starting time of waveform capture, if possible for tool',
103
- 'work-dir': 'Optional override for working directory, defaults to ./eda.work/<top>.sim',
104
113
  'test-mode': ('stops the command early without executing, if --gui is present will'
105
114
  ' instead test without spawning gui')
106
115
 
@@ -145,6 +154,7 @@ class CommandSim(CommandDesign):
145
154
  self.run_dep_commands()
146
155
  self.do_it()
147
156
  self.run_post_tool_dep_commands()
157
+ self.report_pass_fail()
148
158
  return unparsed
149
159
 
150
160
 
@@ -198,6 +208,9 @@ class CommandSim(CommandDesign):
198
208
 
199
209
  clist = list(obj).copy()
200
210
  tee_fpath = getattr(obj, 'tee_fpath', None)
211
+ work_dir = getattr(obj, 'work_dir', None)
212
+ if not work_dir:
213
+ work_dir = self.args['work-dir']
201
214
 
202
215
  util.debug(f'run_commands_check_logs: {clist=}, {tee_fpath=}')
203
216
 
@@ -207,24 +220,28 @@ class CommandSim(CommandDesign):
207
220
  if log_filename:
208
221
  log_fname = log_filename
209
222
 
223
+
210
224
  _, stdout, _ = self.exec(
211
- work_dir=self.args['work-dir'], command_list=clist, tee_fpath=tee_fpath
225
+ work_dir=work_dir, command_list=clist, tee_fpath=tee_fpath
212
226
  )
213
227
 
214
228
  if check_logs and log_fname:
215
229
  # Note this call will check on stdout if not GUI, not opening the log_fname,
216
230
  # but if this is GUI we normally lose stdout and have to open the log.
217
- gui_mode = self.args.get('gui', False)
218
- file_contents_str = '' if gui_mode else stdout
231
+ if self.args.get('gui', False):
232
+ file_contents_str = ''
233
+ else:
234
+ file_contents_str = stdout
235
+
219
236
  self.check_logs_for_errors(
220
- filename=os.path.join(self.args['work-dir'], log_fname),
237
+ filename=os.path.join(work_dir, log_fname),
221
238
  file_contents_str=file_contents_str,
222
239
  bad_strings=bad_strings, must_strings=must_strings,
223
240
  use_bad_strings=use_bad_strings, use_must_strings=use_must_strings
224
241
  )
225
242
  if log_fname:
226
243
  self.artifacts_add(
227
- name=os.path.join(self.args['work-dir'], log_fname),
244
+ name=os.path.join(work_dir, log_fname),
228
245
  typ='text', description='Simulator stdout/stderr log file'
229
246
  )
230
247
 
@@ -253,6 +270,7 @@ class CommandSim(CommandDesign):
253
270
  tool = self.args.get('tool', None)
254
271
  # Certain args are allow-listed here
255
272
  deps_file_args = []
273
+ print(f'SUPER DREW DEBUG: {self.get_command_line_args()=}')
256
274
  for a in self.get_command_line_args():
257
275
  if any(a.startswith(x) for x in [
258
276
  '--compile-args',
@@ -265,7 +283,8 @@ class CommandSim(CommandDesign):
265
283
  '--stop-',
266
284
  '--lint-',
267
285
  '--verilate',
268
- '--verilator']):
286
+ '--verilator',
287
+ '--cocotb-test-']):
269
288
  deps_file_args.append(a)
270
289
 
271
290
  export_obj.run(
@@ -10,7 +10,7 @@ import os
10
10
  from opencos import files
11
11
  from opencos import eda_config
12
12
  from opencos.util import debug, info, warning, error, read_tokens_from_dot_f, \
13
- patch_args_for_dir
13
+ patch_args_for_dir, load_env_file
14
14
  from opencos.utils.str_helpers import dep_str2list
15
15
  from opencos.deps.deps_file import deps_target_get_deps_list
16
16
  from opencos.deps.deps_commands import deps_commands_handler
@@ -192,9 +192,15 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
192
192
  # Since some args (util.py, eda_config.py, eda.py) can only be handled from command
193
193
  # line, it would be nice if -f or --input-file is handled from DEPS, so we'll special
194
194
  # case that now. Recursively resolve -f / --input-file.
195
+ # Do similary for --env-file (also only supported in util.py)
195
196
  parser = argparse.ArgumentParser(
196
197
  prog='deps_processor -f/--input-file', add_help=False, allow_abbrev=False
197
198
  )
199
+ parser.add_argument('--env-file', default=[], action='append',
200
+ help=(
201
+ "dotenv file(s) to pass ENV vars, (default: .env loaded first,"
202
+ " subsequent files' vars override .env"
203
+ ))
198
204
  parser.add_argument('-f', '--input-file', default=[], action='append',
199
205
  help=(
200
206
  'Input .f file to be expanded as eda args, defines, incdirs,'
@@ -225,7 +231,12 @@ class DepsProcessor: # pylint: disable=too-many-instance-attributes
225
231
  # recurse until we've resolved nested .f files.
226
232
  return self.apply_args(args_list=tokens2)
227
233
 
228
- tokens = tokens2 # if no --input-file values, keep parsing the remaining tokens2
234
+ if parsed.env_file:
235
+ for env_file in parsed.env_file:
236
+ load_env_file(env_file)
237
+
238
+ # if no --input-file/--env-file values, keep parsing the remaining tokens2:
239
+ tokens = tokens2
229
240
 
230
241
  # We have to special-case anything with --tool[=value] in tokens, otherwise
231
242
  # the user may think they were allowed to set --tool, but in our flow the Command handler
@@ -20,7 +20,8 @@ from pathlib import Path
20
20
 
21
21
  import opencos
22
22
  from opencos import util, eda_config, eda_base
23
- from opencos.eda_base import Tool, which_tool, get_eda_exec
23
+ from opencos.util import safe_emoji, Colors
24
+ from opencos.eda_base import Tool, which_tool, get_eda_exec, print_eda_usage_line
24
25
  from opencos.utils import vsim_helper, vscode_helper
25
26
  from opencos.utils.subprocess_helpers import subprocess_run_background
26
27
  from opencos.utils import status_constants, str_helpers, subprocess_helpers
@@ -75,7 +76,7 @@ def get_all_commands_help_str(config: dict) -> str:
75
76
  all_commands_help.append(f' {key:<{max_command_str_len}} - {value.strip()}')
76
77
  if all_commands_help:
77
78
  all_commands_help = [
78
- 'Where <command> is one of:',
79
+ f'Where {Colors.byellow}COMMAND{Colors.normal} is one of:',
79
80
  '',
80
81
  ] + all_commands_help
81
82
  return '\n'.join(all_commands_help)
@@ -94,22 +95,24 @@ def usage(tokens: list, config: dict, command: str = "", tool: str = "") -> int:
94
95
  '''
95
96
 
96
97
  if command == "":
97
- print(
98
- """
99
- Usage:
100
- eda [<options>] <command> [options] <files|targets, ...>
101
- """
102
- )
98
+ util.info('Help:', color=Colors.cyan)
99
+ print()
100
+ print_eda_usage_line()
103
101
  print(get_all_commands_help_str(config=config))
104
- print(
105
- """
106
- And <files|targets, ...> is one or more source file or DEPS markup file target,
107
- such as .v, .sv, .vhd[l], .cpp files, or a target key in a DEPS.[yml|yaml|toml|json].
108
- Note that you can prefix source files with `sv@`, `v@`, `vhdl@` or `cpp@` to
109
- force use that file as systemverilog, verilog, vhdl, or C++, respectively.
110
-
111
- """
112
- )
102
+ print()
103
+ print(str_helpers.indent_wrap_long_text(
104
+ (
105
+ f'{safe_emoji("❕ ")}where {Colors.byellow}FILES|TARGETS{Colors.normal}'
106
+ ' is one or more source file or DEPS markup file target,'
107
+ ' such as .v, .sv, .vhd[l], .cpp files, or a target key in a'
108
+ f' {Colors.byellow}DEPS.[yml|yaml|toml|json]{Colors.normal}. Note that you can'
109
+ f' prefix source files with {Colors.bcyan}sv@{Colors.normal},'
110
+ f' {Colors.bcyan}v@{Colors.normal}, {Colors.bcyan}vhdl@{Colors.normal},'
111
+ f' or {Colors.bcyan}cpp@{Colors.normal}'
112
+ ' to force use that file as systemverilog, verilog, vhdl, or C++, respectively.'
113
+ ), width=str_helpers.get_terminal_columns(), indent=4
114
+ ))
115
+ print()
113
116
  eda_base.print_base_help()
114
117
  return 0
115
118
 
@@ -495,7 +498,7 @@ def check_command_handler_cls(command_obj:object, command:str, parsed_args) -> i
495
498
  def signal_handler(sig, frame) -> None: # pylint: disable=unused-argument
496
499
  '''Handles Ctrl-C, called by main_cli() if running from command line'''
497
500
  util.fancy_stop()
498
- util.info('Received Ctrl+C...', start='\nINFO: [EDA] ')
501
+ util.error(f'{safe_emoji("❌ ")}Received Ctrl+C...', start='\nINFO: [EDA] ')
499
502
  subprocess_helpers.cleanup_all()
500
503
  util.exit(-1)
501
504
 
@@ -526,7 +529,7 @@ def main(*args):
526
529
  sys.exit(0)
527
530
 
528
531
  if not util.args['quiet']:
529
- util.info(f'eda: version {opencos.__version__}')
532
+ util.info(f'eda: version {opencos.__version__}', color=Colors.bcyan)
530
533
  # And show the command that was run (all args):
531
534
  util.info(f"main: eda {' '.join(args)}; (run from {os.getcwd()})")
532
535
 
@@ -536,7 +539,7 @@ def main(*args):
536
539
  # Note - we used to call: config = init_config(config=config)
537
540
  # However, we now defer calling init_config(..) until eda.process_tokens(..)
538
541
 
539
- util.info("*** OpenCOS EDA ***")
542
+ util.info("*** OpenCOS EDA ***", color=Colors.bcyan)
540
543
 
541
544
  if len(args) == 0 or (len(args) == 1 and '--debug' in args):
542
545
  # special snowflake case if someone called with a singular arg --debug