opencos-eda 0.2.40__tar.gz → 0.2.41__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.40/opencos_eda.egg-info → opencos_eda-0.2.41}/PKG-INFO +1 -1
  2. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda.py +9 -4
  3. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_config.py +2 -1
  4. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_config_defaults.yml +32 -0
  5. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_tools.py +1 -1
  6. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/modelsim_ase.py +4 -2
  7. opencos_eda-0.2.41/opencos/tools/riviera.py +293 -0
  8. {opencos_eda-0.2.40 → opencos_eda-0.2.41/opencos_eda.egg-info}/PKG-INFO +1 -1
  9. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos_eda.egg-info/SOURCES.txt +1 -0
  10. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/pyproject.toml +1 -1
  11. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/LICENSE +0 -0
  12. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/LICENSE.spdx +0 -0
  13. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/README.md +0 -0
  14. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/__init__.py +0 -0
  15. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/_version.py +0 -0
  16. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/_waves_pkg.sv +0 -0
  17. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/__init__.py +0 -0
  18. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/build.py +0 -0
  19. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/elab.py +0 -0
  20. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/export.py +0 -0
  21. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/flist.py +0 -0
  22. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/multi.py +0 -0
  23. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/open.py +0 -0
  24. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/proj.py +0 -0
  25. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/sim.py +0 -0
  26. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/sweep.py +0 -0
  27. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/synth.py +0 -0
  28. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/targets.py +0 -0
  29. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/upload.py +0 -0
  30. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/commands/waves.py +0 -0
  31. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/deps_helpers.py +0 -0
  32. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/deps_schema.py +0 -0
  33. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_base.py +0 -0
  34. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_config_max_verilator_waivers.yml +0 -0
  35. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_config_reduced.yml +0 -0
  36. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_deps_bash_completion.bash +0 -0
  37. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_extract_targets.py +0 -0
  38. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/eda_tool_helper.py +0 -0
  39. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/export_helper.py +0 -0
  40. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/export_json_convert.py +0 -0
  41. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/files.py +0 -0
  42. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/names.py +0 -0
  43. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/oc_cli.py +0 -0
  44. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/pcie.py +0 -0
  45. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/peakrdl_cleanup.py +0 -0
  46. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/seed.py +0 -0
  47. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/__init__.py +0 -0
  48. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/custom_config.yml +0 -0
  49. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
  50. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
  51. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
  52. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
  53. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
  54. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
  55. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
  56. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/helpers.py +0 -0
  57. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_build.py +0 -0
  58. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_deps_helpers.py +0 -0
  59. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_deps_schema.py +0 -0
  60. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_eda.py +0 -0
  61. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_eda_elab.py +0 -0
  62. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_eda_synth.py +0 -0
  63. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tests/test_oc_cli.py +0 -0
  64. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/__init__.py +0 -0
  65. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/invio.py +0 -0
  66. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/invio_helpers.py +0 -0
  67. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/invio_yosys.py +0 -0
  68. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/iverilog.py +0 -0
  69. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/questa.py +0 -0
  70. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/slang.py +0 -0
  71. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/slang_yosys.py +0 -0
  72. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/surelog.py +0 -0
  73. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/tabbycad_yosys.py +0 -0
  74. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/verilator.py +0 -0
  75. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/vivado.py +0 -0
  76. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/tools/yosys.py +0 -0
  77. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos/util.py +0 -0
  78. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos_eda.egg-info/dependency_links.txt +0 -0
  79. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos_eda.egg-info/entry_points.txt +0 -0
  80. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos_eda.egg-info/requires.txt +0 -0
  81. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/opencos_eda.egg-info/top_level.txt +0 -0
  82. {opencos_eda-0.2.40 → opencos_eda-0.2.41}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.40
3
+ Version: 0.2.41
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
@@ -166,7 +166,7 @@ def auto_tool_setup(warnings:bool=True, config=None, quiet=False, tool=None) ->
166
166
  continue
167
167
 
168
168
  has_all_py = True
169
- requires_py_list = value.get('requires_py', list())
169
+ requires_py_list = value.get('requires_py', [])
170
170
  for pkg in requires_py_list:
171
171
  spec = importlib.util.find_spec(pkg)
172
172
  if not spec:
@@ -174,22 +174,27 @@ def auto_tool_setup(warnings:bool=True, config=None, quiet=False, tool=None) ->
174
174
  util.debug(f"... No, missing pkg {spec}")
175
175
 
176
176
  has_all_env = True
177
- requires_env_list = value.get('requires_env', list())
177
+ requires_env_list = value.get('requires_env', [])
178
178
  for env in requires_env_list:
179
179
  if not os.environ.get(env, ''):
180
180
  has_all_env = False
181
181
  util.debug(f"... No, missing env {env}")
182
182
 
183
183
  has_all_exe = True
184
+ has_all_in_exe_path = True
184
185
  for exe in exe_list:
185
186
  assert exe != '', f'{tool=} {value=} value missing "exe" {exe=}'
186
187
  p = shutil.which(exe)
187
188
  if not p:
188
189
  has_all_exe = False
189
190
  util.debug(f"... No, missing exe {exe}")
191
+ for req in value.get('requires_in_exe_path', []):
192
+ if p and req and str(req).lower() not in str(p).lower():
193
+ has_all_in_exe_path = False
194
+ util.debug(f"... No, missing path requirement {req}")
190
195
 
191
196
  if has_all_exe:
192
- requires_cmd_list = value.get('requires_cmd', list())
197
+ requires_cmd_list = value.get('requires_cmd', [])
193
198
  for cmd in requires_cmd_list:
194
199
  cmd_list = shlex.split(cmd)
195
200
  try:
@@ -203,7 +208,7 @@ def auto_tool_setup(warnings:bool=True, config=None, quiet=False, tool=None) ->
203
208
  util.debug(f"... No, exception running {cmd_list}")
204
209
 
205
210
 
206
- if all([has_all_py, has_all_env, has_all_exe]):
211
+ if all([has_all_py, has_all_env, has_all_exe, has_all_in_exe_path]):
207
212
  exe = exe_list[0]
208
213
  p = shutil.which(exe)
209
214
  config['auto_tools_found'][name] = exe # populate key-value pairs w/ first exe in list
@@ -35,7 +35,8 @@ class Defaults:
35
35
  'auto_tools_order',
36
36
  ])
37
37
  supported_config_auto_tools_order_keys = set([
38
- 'exe', 'handlers', 'requires_env', 'requires_py', 'requires_cmd',
38
+ 'exe', 'handlers',
39
+ 'requires_env', 'requires_py', 'requires_cmd', 'requires_in_exe_path',
39
40
  'disable-tools-multi',
40
41
  ])
41
42
  supported_config_tool_keys = set([
@@ -86,6 +86,7 @@ tools:
86
86
  # log-must-strings: <Array of strings>
87
87
  # sim-libraries: <Array of strings>
88
88
  # compile-args: <string space separated>
89
+ # compile-coverage-args: <string space separated>
89
90
  # compile-waves-args: <string space separated>
90
91
  # compile-waivers: <Array of strings, no spaces>
91
92
  # elab-args: <string space separated>
@@ -192,6 +193,24 @@ tools:
192
193
  VERIFIC: null
193
194
 
194
195
 
196
+ riviera:
197
+ defines:
198
+ OC_TOOL_RIVIERA: 1
199
+ log-bad-strings:
200
+ - "Error:"
201
+ log-must-strings:
202
+ - "VSIM: Simulation has finished"
203
+ compile-args: |
204
+ -echo -sv -input_ports net -lcu -dbg +accb +accr +accs +dacc
205
+ compile-coverage-args: |
206
+ -coverage sbecam -coverage_options count
207
+ # -uvm -ovm
208
+ simulate-waves-args: |
209
+ +accb +accr +access +r+w
210
+ coverage-args: |
211
+ -acdb -acdb_cov sbfectapm
212
+
213
+
195
214
  modelsim_ase:
196
215
  defines:
197
216
  OC_ASSERT_PROPERTY_NOT_SUPPORTED: 1
@@ -348,10 +367,23 @@ auto_tools_order:
348
367
  elab: opencos.tools.queta.CommandElabQuesta
349
368
  sim: opencos.tools.queta.CommandSimQuesta
350
369
 
370
+ riviera:
371
+ exe: vsim
372
+ requires_cmd:
373
+ - vsim -version
374
+ - which riviera # Do not run it, make sure it's in PATH
375
+ requires_in_exe_path:
376
+ - riviera
377
+ handlers:
378
+ elab: opencos.tools.riviera.CommandElabRiviera
379
+ sim: opencos.tools.riviera.CommandSimRiviera
380
+
351
381
  modelsim_ase:
352
382
  exe: vsim
353
383
  requires_cmd:
354
384
  - vsim -version
385
+ requires_in_exe_path:
386
+ - modelsim
355
387
  handlers:
356
388
  elab: opencos.tools.modelsim_ase.CommandElabModelsimAse
357
389
  sim: opencos.tools.modelsim_ase.CommandSimModelsimAse
@@ -71,7 +71,7 @@ list_of_tools = [
71
71
  'iverilog',
72
72
  'verilator',
73
73
  'vivado',
74
- 'modelsim_ase'
74
+ 'modelsim_ase',
75
75
  ]
76
76
 
77
77
  list_of_deps_targets = [
@@ -3,6 +3,8 @@
3
3
  Contains classes for ToolModelsimAse, CommandSimModelsimAse, CommandElabModelsimAse.
4
4
  '''
5
5
 
6
+ # pylint: disable=R0801 # (duplicate code in derived classes, such as if-condition return.)
7
+
6
8
  import os
7
9
 
8
10
  from opencos import util
@@ -133,7 +135,7 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
133
135
  def get_post_simulate_command_lists(self, **kwargs) -> list:
134
136
  return []
135
137
 
136
- def write_vlog_dot_f(self, filename='vlog.f'):
138
+ def write_vlog_dot_f(self, filename='vlog.f') -> None:
137
139
  '''Returns none, creates filename (str) for a vlog.f'''
138
140
  vlog_dot_f_lines = []
139
141
 
@@ -186,7 +188,7 @@ class CommandSimModelsimAse(CommandSim, ToolModelsimAse):
186
188
  with open(vlog_dot_f_fpath, 'w', encoding='utf-8') as f:
187
189
  f.writelines(line + "\n" for line in vlog_dot_f_lines)
188
190
 
189
- def write_vsim_dot_do(self, dot_do_to_write: list):
191
+ def write_vsim_dot_do(self, dot_do_to_write: list) -> None:
190
192
  '''Writes files(s) based on dot_do_to_write(list of str)
191
193
 
192
194
  list arg values can be empty (all) or have items 'all', 'sim', 'lint', 'vlog'.'''
@@ -0,0 +1,293 @@
1
+ ''' opencos.tools.riviera - Used by opencos.eda for sim/elab commands w/ --tool=riviera.
2
+
3
+ Contains classes for ToolRiviera, CommandSimRiviera, CommandElabRiviera.
4
+ '''
5
+
6
+ # pylint: disable=too-many-ancestors
7
+ # pylint: disable=R0801 # (duplicate code in derived classes, such as if-condition return.)
8
+
9
+ import os
10
+ import shutil
11
+ import subprocess
12
+
13
+ from opencos import util
14
+ from opencos.util import sanitize_defines_for_sh
15
+ from opencos.tools.modelsim_ase import ToolModelsimAse, CommandSimModelsimAse
16
+
17
+ class ToolRiviera(ToolModelsimAse):
18
+ '''ToolRiviera used by opencos.eda for --tool=riviera'''
19
+
20
+ _TOOL = 'riviera'
21
+ _EXE = 'vsim'
22
+
23
+ def get_versions(self) -> str:
24
+ if self._VERSION:
25
+ return self._VERSION
26
+ path = shutil.which(self._EXE)
27
+ if not path:
28
+ self.error(f"{self._EXE} not in path, need to setup or add to PATH")
29
+ util.debug(f"{path=}")
30
+ else:
31
+ self.sim_exe = path
32
+ self.sim_exe_base_path, _ = os.path.split(path)
33
+
34
+ version_ret = subprocess.run(
35
+ [self.sim_exe, '-version'],
36
+ capture_output=True,
37
+ check=False
38
+ )
39
+ stdout = version_ret.stdout.decode('utf-8').rstrip()
40
+
41
+ # Expect:
42
+ # Aldec, Inc. Riviera-PRO version 2025.04.139.9738 built for Linux64 on May 30, 2025
43
+ left, right = stdout.split('version')
44
+ if 'Riviera' not in left:
45
+ self.error(f'{stdout}: does not show Riviera')
46
+ self._VERSION = right.split()[0]
47
+ return self._VERSION
48
+
49
+
50
+ class CommandSimRiviera(CommandSimModelsimAse, ToolRiviera):
51
+ '''CommandSimRiviera is a command handler for: eda sim --tool=riviera'''
52
+
53
+ def __init__(self, config: dict):
54
+ CommandSimModelsimAse.__init__(self, config=config)
55
+ ToolRiviera.__init__(self, config=self.config)
56
+ self.shell_command = os.path.join(self.sim_exe_base_path, 'vsim')
57
+ self.starter_edition = True
58
+ self.args.update({
59
+ 'tool': self._TOOL, # override
60
+ 'gui': False,
61
+ })
62
+
63
+ def set_tool_defines(self):
64
+ # Update any defines from config.tools.modelsim_ase:
65
+ self.defines.update(
66
+ self.tool_config.get(
67
+ 'defines',
68
+ # defaults, if not set:
69
+ {'OC_TOOL_RIVIERA': 1}
70
+ )
71
+ )
72
+
73
+ # Note: many of these we follow the same flow as CommandSimModelsimAse:
74
+ # do_it, prepare_compile, compile, elaborate, simulate
75
+
76
+ def get_compile_command_lists(self, **kwargs) -> list:
77
+ # This will also set up a compile.
78
+ vsim_command_list = [
79
+ self.sim_exe,
80
+ '' if self.args['gui'] else '-c',
81
+ '-l', 'sim.log', '-do', 'vsim_vlogonly.do'
82
+ ]
83
+ return [vsim_command_list]
84
+
85
+ def get_elaborate_command_lists(self, **kwargs) -> list:
86
+ # This will also set up a compile, for vlog + vsim (0 time)
87
+ vsim_command_list = [
88
+ self.sim_exe,
89
+ '' if self.args['gui'] else '-c',
90
+ '-l', 'sim.log', '-do', 'vsim_lintonly.do',
91
+ ]
92
+ return [vsim_command_list]
93
+
94
+ def get_simulate_command_lists(self, **kwargs) -> list:
95
+ # This will also set up a compile, for vlog + vsim (with run -all)
96
+ vsim_command_list = [
97
+ self.sim_exe,
98
+ '' if self.args['gui'] else '-c',
99
+ '-l', 'sim.log', '-do', 'vsim.do',
100
+ ]
101
+ return [vsim_command_list]
102
+
103
+ def get_post_simulate_command_lists(self, **kwargs) -> list:
104
+ return []
105
+
106
+
107
+ def write_vlog_dot_f(self, filename='vlog.f') -> None:
108
+ '''Returns none, creates filename (str) for a vlog.f'''
109
+ vlog_dot_f_lines = []
110
+
111
+ # Add compile args from config.tool.riviera
112
+ vlog_dot_f_lines += self.tool_config.get(
113
+ 'compile-args',
114
+ '-sv -input_ports net').split()
115
+
116
+ # Add waivers from config.tool.riviera, convert to warning:
117
+ for waiver in self.tool_config.get('compile-waivers', []):
118
+ vlog_dot_f_lines += [f'-err {waiver} W1']
119
+
120
+ vlog_dot_f_fname = filename
121
+ vlog_dot_f_fpath = os.path.join(self.args['work-dir'], vlog_dot_f_fname)
122
+
123
+ for value in self.incdirs:
124
+ vlog_dot_f_lines += [ f"+incdir+{value}" ]
125
+
126
+ for k,v in self.defines.items():
127
+ if v is None:
128
+ vlog_dot_f_lines += [ f'+define+{k}' ]
129
+ else:
130
+
131
+ # if the value v is a double-quoted string, such as v='"hi"', the
132
+ # entire +define+NAME="hi" needs to wrapped in double quotes with the
133
+ # value v double-quotes escaped: "+define+NAME=\"hi\""
134
+ if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
135
+ str_v = v.replace('"', '\\"')
136
+ vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
137
+ else:
138
+ # Generally we should only support int and str python types passed as
139
+ # +define+{k}={v}, but also for SystemVerilog plusargs
140
+ vlog_dot_f_lines += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
141
+
142
+
143
+ vlog_dot_f_lines += self.args['compile-args']
144
+ if self.args['coverage']:
145
+ vlog_dot_f_lines += self.tool_config.get('compile-coverage-args', '').split()
146
+
147
+ vlog_dot_f_lines += [
148
+ ] + list(self.files_sv) + list(self.files_v)
149
+
150
+ if not self.files_sv and not self.files_v:
151
+ if not self.args['stop-before-compile']:
152
+ self.error(f'{self.target=} {self.files_sv=} and {self.files_v=} are empty,',
153
+ 'cannot create a valid vlog.f')
154
+
155
+ with open(vlog_dot_f_fpath, 'w', encoding='utf-8') as f:
156
+ f.writelines(line + "\n" for line in vlog_dot_f_lines)
157
+
158
+
159
+ def write_vsim_dot_do(self, dot_do_to_write: list) -> None:
160
+ '''Writes files(s) based on dot_do_to_write(list of str)
161
+
162
+ list arg values can be empty (all) or have items 'all', 'sim', 'lint', 'vlog'.'''
163
+
164
+ vsim_dot_do_fpath = os.path.join(self.args['work-dir'], 'vsim.do')
165
+ vsim_lintonly_dot_do_fpath = os.path.join(self.args['work-dir'], 'vsim_lintonly.do')
166
+ vsim_vlogonly_dot_do_fpath = os.path.join(self.args['work-dir'], 'vsim_vlogonly.do')
167
+
168
+ sim_plusargs_str = self._get_sim_plusargs_str()
169
+
170
+ voptargs_str = ""
171
+ if self.args['gui'] or self.args['waves'] or self.args['coverage']:
172
+ voptargs_str = self.tool_config.get('simulate-waves-args',
173
+ '+accb +accr +access +r+w')
174
+ if self.args['coverage']:
175
+ voptargs_str += self.tool_config.get('coverage-args', '')
176
+
177
+ # TODO(drew): support self.args['sim_libary', 'elab-args', sim-args'] (3 lists)
178
+ # to add to vsim_one_liner.
179
+
180
+ vsim_one_liner = (
181
+ "vsim"
182
+ f" -sv_seed {self.args['seed']} {sim_plusargs_str}"
183
+ f" {voptargs_str} work.{self.args['top']}"
184
+ )
185
+
186
+ vsim_one_liner = vsim_one_liner.replace('\n', ' ') # needs to be a one-liner
187
+
188
+ vsim_vlogonly_dot_do_lines = [
189
+ "if {[file exists work]} { vdel -all work; }",
190
+ "vlib work;",
191
+ "if {[catch {vlog -f vlog.f} result]} {",
192
+ " echo \"Caught $result \";",
193
+ " if {[batch_mode]} {",
194
+ " quit -code 20 -force;",
195
+ " }",
196
+ "}",
197
+ "if {[batch_mode]} {",
198
+ " quit -code 0 -force;",
199
+ "}",
200
+ ]
201
+
202
+ vsim_lintonly_dot_do_lines = [
203
+ "if {[file exists work]} { vdel -all work; }",
204
+ "vlib work;",
205
+ "set qc 30;",
206
+ "if {[catch {vlog -f vlog.f} result]} {",
207
+ " echo \"Caught $result \";",
208
+ " if {[batch_mode]} {",
209
+ " quit -code 20 -force;",
210
+ " }",
211
+ "}",
212
+ "if {[catch { " + vsim_one_liner + " } result] } {",
213
+ " echo \"Caught $result\";",
214
+ " if {[batch_mode]} {",
215
+ " quit -code 19 -force;",
216
+ " }",
217
+ "}",
218
+ "if {[batch_mode]} {",
219
+ " quit -code 0 -force;",
220
+ "}",
221
+ ]
222
+
223
+ vsim_dot_do_lines = [
224
+ "if {[file exists work]} { vdel -all work; }",
225
+ "vlib work;",
226
+ "set qc 30;",
227
+ "if {[catch {vlog -f vlog.f} result]} {",
228
+ " echo \"Caught $result \";",
229
+ " if {[batch_mode]} {",
230
+ " quit -code 20 -force;",
231
+ " }",
232
+ "}",
233
+ "if {[catch { " + vsim_one_liner + " } result] } {",
234
+ " echo \"Caught $result\";",
235
+ " if {[batch_mode]} {",
236
+ " quit -code 19 -force;",
237
+ " }",
238
+ "}",
239
+ ]
240
+
241
+ if self.args['coverage']:
242
+ vsim_dot_do_lines += [
243
+ "run -all;",
244
+ "acdb save",
245
+ "acdb report -db work.acdb -txt -o cov.txt",
246
+ # Note - could try:
247
+ ##"cover report -o cov.report.txt -fullverbose -all_columns",
248
+ ]
249
+ else:
250
+ vsim_dot_do_lines += [
251
+ "run -all;",
252
+ ]
253
+
254
+
255
+ vsim_dot_do_lines += [
256
+ "if {[batch_mode]} {",
257
+ " quit -code 0 -force;",
258
+ "}",
259
+ ]
260
+
261
+ write_all = len(dot_do_to_write) == 0 or 'all' in dot_do_to_write
262
+ if write_all or 'sim' in dot_do_to_write:
263
+ with open(vsim_dot_do_fpath, 'w', encoding='utf-8') as f:
264
+ f.writelines(line + "\n" for line in vsim_dot_do_lines)
265
+
266
+ if write_all or 'lint' in dot_do_to_write:
267
+ with open(vsim_lintonly_dot_do_fpath, 'w', encoding='utf-8') as f:
268
+ f.writelines(line + "\n" for line in vsim_lintonly_dot_do_lines)
269
+
270
+ if write_all or 'vlog' in dot_do_to_write:
271
+ with open(vsim_vlogonly_dot_do_fpath, 'w', encoding='utf-8') as f:
272
+ f.writelines(line + "\n" for line in vsim_vlogonly_dot_do_lines)
273
+
274
+
275
+
276
+ def _get_vsim_suppress_list_str(self) -> str:
277
+ vsim_suppress_list = []
278
+ # Add waivers from config.tool.modelsim_ase:
279
+ for waiver in self.tool_config.get(
280
+ 'simulate-waivers', [
281
+ #defaults: none
282
+ ]):
283
+ vsim_suppress_list += ['-filter', str(waiver)]
284
+
285
+ return ' '.join(vsim_suppress_list)
286
+
287
+
288
+ class CommandElabRiviera(CommandSimRiviera):
289
+ '''CommandElabRiviera is a command handler for: eda elab --tool=riviera'''
290
+
291
+ def __init__(self, config:dict):
292
+ super().__init__(config)
293
+ self.args['stop-after-elaborate'] = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencos-eda
3
- Version: 0.2.40
3
+ Version: 0.2.41
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
@@ -64,6 +64,7 @@ opencos/tools/invio_yosys.py
64
64
  opencos/tools/iverilog.py
65
65
  opencos/tools/modelsim_ase.py
66
66
  opencos/tools/questa.py
67
+ opencos/tools/riviera.py
67
68
  opencos/tools/slang.py
68
69
  opencos/tools/slang_yosys.py
69
70
  opencos/tools/surelog.py
@@ -2,7 +2,7 @@
2
2
 
3
3
  [project]
4
4
  name = "opencos-eda"
5
- version = "0.2.40"
5
+ version = "0.2.41"
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