opencos-eda 0.2.39__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.
- {opencos_eda-0.2.39/opencos_eda.egg-info → opencos_eda-0.2.41}/PKG-INFO +1 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda.py +9 -4
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_base.py +15 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_config.py +2 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_config_defaults.yml +32 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_tools.py +1 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/modelsim_ase.py +4 -2
- opencos_eda-0.2.41/opencos/tools/riviera.py +293 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41/opencos_eda.egg-info}/PKG-INFO +1 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos_eda.egg-info/SOURCES.txt +1 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/pyproject.toml +1 -1
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/LICENSE +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/LICENSE.spdx +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/README.md +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/__init__.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/_version.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/_waves_pkg.sv +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/__init__.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/build.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/elab.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/export.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/flist.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/multi.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/open.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/proj.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/sim.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/sweep.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/synth.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/targets.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/upload.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/commands/waves.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/deps_helpers.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/deps_schema.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_config_max_verilator_waivers.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_config_reduced.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_deps_bash_completion.bash +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_extract_targets.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/eda_tool_helper.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/export_helper.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/export_json_convert.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/files.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/names.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/oc_cli.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/pcie.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/peakrdl_cleanup.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/seed.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/__init__.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/custom_config.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/command_order/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/error_msgs/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/iverilog_test/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/no_deps_here/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/non_sv_reqs/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/tags_with_tools/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/deps_files/test_err_fatal/DEPS.yml +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/helpers.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_build.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_deps_helpers.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_deps_schema.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_eda.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_eda_elab.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_eda_synth.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tests/test_oc_cli.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/__init__.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/invio.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/invio_helpers.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/invio_yosys.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/iverilog.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/questa.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/slang.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/slang_yosys.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/surelog.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/tabbycad_yosys.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/verilator.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/vivado.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/tools/yosys.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos/util.py +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos_eda.egg-info/dependency_links.txt +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos_eda.egg-info/entry_points.txt +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos_eda.egg-info/requires.txt +0 -0
- {opencos_eda-0.2.39 → opencos_eda-0.2.41}/opencos_eda.egg-info/top_level.txt +0 -0
- {opencos_eda-0.2.39 → 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.
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
|
@@ -178,6 +178,7 @@ class Command:
|
|
|
178
178
|
"job-name" : "", # this is used to create a certain dir under "eda_dir"
|
|
179
179
|
"work-dir" : "", # this can be used to run the job in a certain dir, else it will be <eda-dir>/<job-name> else <eda-dir>/<target>_<command>
|
|
180
180
|
"sub-work-dir" : "", # this can be used to name the dir built under <eda-dir>, which seems to be same function as job-name??
|
|
181
|
+
"work-dir-use-target-dir": False,
|
|
181
182
|
"suffix" : "",
|
|
182
183
|
"design" : "", # not sure how this relates to top
|
|
183
184
|
'export': False,
|
|
@@ -196,6 +197,8 @@ class Command:
|
|
|
196
197
|
'export-json': 'export, and save a JSON file per target',
|
|
197
198
|
'work-dir': ('Optional override for working directory, often defaults to'
|
|
198
199
|
' ./eda.work/<top>.<command>'),
|
|
200
|
+
"work-dir-use-target-dir": ('Set the work-dir to be the same as the in-place location'
|
|
201
|
+
' where the target (DEPS) exists'),
|
|
199
202
|
'enable-tags': ('DEPS markup tag names to be force enabled for this'
|
|
200
203
|
' command (mulitple appends to list).'),
|
|
201
204
|
'diable-tags': ('DEPS markup tag names to be disabled (even if they'
|
|
@@ -207,6 +210,7 @@ class Command:
|
|
|
207
210
|
self.modified_args = {}
|
|
208
211
|
self.config = copy.deepcopy(config) # avoid external modifications.
|
|
209
212
|
self.target = ""
|
|
213
|
+
self.target_path = ""
|
|
210
214
|
self.status = 0
|
|
211
215
|
|
|
212
216
|
def error(self, *args, **kwargs):
|
|
@@ -228,6 +232,16 @@ class Command:
|
|
|
228
232
|
|
|
229
233
|
def create_work_dir(self):
|
|
230
234
|
util.debug(f"create_work_dir: {self.args['eda-dir']=} {self.args['work-dir']=}")
|
|
235
|
+
if self.args['work-dir-use-target-dir']:
|
|
236
|
+
if not self.target_path:
|
|
237
|
+
self.target_path = '.'
|
|
238
|
+
util.info(f"create_work_dir: --work-dir-use-target-dir: using:",
|
|
239
|
+
f"{os.path.abspath(self.target_path)}",
|
|
240
|
+
f'target={self.target}')
|
|
241
|
+
self.args['work-dir'] = self.target_path
|
|
242
|
+
self.args['sub-work-dir'] = ''
|
|
243
|
+
return self.args['work-dir']
|
|
244
|
+
|
|
231
245
|
if not os.path.exists(self.args['eda-dir']):
|
|
232
246
|
util.safe_mkdir(self.args['eda-dir'])
|
|
233
247
|
util.info(f"create_work_dir: created {self.args['eda-dir']}")
|
|
@@ -884,7 +898,7 @@ class CommandDesign(Command):
|
|
|
884
898
|
# self.target is a name we grab for the job (i.e. for naming work dir etc). we don't want the path prefix.
|
|
885
899
|
# TODO: too messy -- there's also a self.target, args['job-name'], args['work-dir'], args['design'], args['top'], args['sub-work-dir'] ...
|
|
886
900
|
|
|
887
|
-
self.target = os.path.
|
|
901
|
+
self.target_path, self.target = os.path.split(target)
|
|
888
902
|
|
|
889
903
|
if target in self.targets_dict:
|
|
890
904
|
# If we're encountered this target before, stop. We're not traversing again.
|
|
@@ -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',
|
|
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
|
|
@@ -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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|