opencos-eda 0.3.12__py3-none-any.whl → 0.3.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencos/commands/flist.py +222 -39
- opencos/commands/multi.py +4 -2
- opencos/commands/sim.py +192 -8
- opencos/deps/deps_file.py +4 -1
- opencos/deps_schema.py +2 -2
- opencos/eda.py +12 -9
- opencos/eda_base.py +39 -8
- opencos/eda_config.py +37 -6
- opencos/eda_config_defaults.yml +30 -5
- opencos/eda_tool_helper.py +4 -4
- opencos/tools/cocotb.py +0 -11
- opencos/tools/invio.py +0 -6
- opencos/tools/iverilog.py +17 -16
- opencos/tools/modelsim_ase.py +0 -12
- opencos/tools/quartus.py +21 -1
- opencos/tools/questa.py +0 -14
- opencos/tools/questa_common.py +54 -25
- opencos/tools/questa_fe.py +0 -14
- opencos/tools/questa_fse.py +0 -14
- opencos/tools/riviera.py +104 -25
- opencos/tools/slang.py +12 -9
- opencos/tools/slang_yosys.py +0 -6
- opencos/tools/surelog.py +11 -8
- opencos/tools/tabbycad_yosys.py +1 -7
- opencos/tools/verilator.py +18 -11
- opencos/tools/vivado.py +92 -25
- opencos/tools/yosys.py +8 -5
- opencos/util.py +14 -5
- opencos/utils/str_helpers.py +4 -1
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/METADATA +1 -2
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/RECORD +36 -36
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/WHEEL +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/entry_points.txt +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.3.12.dist-info → opencos_eda-0.3.14.dist-info}/top_level.txt +0 -0
opencos/tools/questa_common.py
CHANGED
|
@@ -53,8 +53,10 @@ class ToolQuesta(Tool):
|
|
|
53
53
|
if line.strip().startswith('Release Notes For'):
|
|
54
54
|
m = re.search(r'(\d+)\.(\d+)', line)
|
|
55
55
|
if m:
|
|
56
|
-
self.
|
|
57
|
-
|
|
56
|
+
if self._TOOL.startswith('questa'):
|
|
57
|
+
# don't set these for ModelsimASE:
|
|
58
|
+
self.questa_major = int(m.group(1))
|
|
59
|
+
self.questa_minor = int(m.group(2))
|
|
58
60
|
self._VERSION = str(self.questa_major) + '.' + str(self.questa_minor)
|
|
59
61
|
util.debug(f'version {self._VERSION} ({release_notes_txt_filepath})')
|
|
60
62
|
break
|
|
@@ -101,11 +103,14 @@ class ToolQuesta(Tool):
|
|
|
101
103
|
|
|
102
104
|
return self._VERSION
|
|
103
105
|
|
|
104
|
-
def set_tool_defines(self):
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
def set_tool_defines(self) -> None:
|
|
107
|
+
'''Override from class Tool, which handles picking up config['tools'][self._TOOL]
|
|
108
|
+
|
|
109
|
+
defines. We also set the OC_TOOL_QUESTA_[major]_[minor] if those exist
|
|
110
|
+
'''
|
|
111
|
+
super().set_tool_defines() # Tool, set from config.
|
|
112
|
+
if self.questa_major and self.questa_minor:
|
|
113
|
+
self.defines[f'OC_TOOL_QUESTA_{self.questa_major:d}_{self.questa_minor:d}'] = None
|
|
109
114
|
|
|
110
115
|
|
|
111
116
|
|
|
@@ -145,6 +150,7 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
145
150
|
|
|
146
151
|
def prepare_compile(self):
|
|
147
152
|
self.set_tool_defines()
|
|
153
|
+
self.update_library_map()
|
|
148
154
|
self.write_vlog_dot_f()
|
|
149
155
|
self.write_vsim_dot_do(dot_do_to_write='all')
|
|
150
156
|
|
|
@@ -250,21 +256,24 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
250
256
|
for value in self.incdirs:
|
|
251
257
|
vlog_dot_f_lines += [ f"+incdir+{value}" ]
|
|
252
258
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
# entire +define+NAME="hi" needs to wrapped in double quotes with the
|
|
260
|
-
# value v double-quotes escaped: "+define+NAME=\"hi\""
|
|
261
|
-
if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
|
|
262
|
-
str_v = v.replace('"', '\\"')
|
|
263
|
-
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
259
|
+
if self.args['ext-defines-sv-fname']:
|
|
260
|
+
self.create_ext_defines_sv()
|
|
261
|
+
else:
|
|
262
|
+
for k,v in self.defines.items():
|
|
263
|
+
if v is None:
|
|
264
|
+
vlog_dot_f_lines += [ f'+define+{k}' ]
|
|
264
265
|
else:
|
|
265
|
-
|
|
266
|
-
#
|
|
267
|
-
|
|
266
|
+
|
|
267
|
+
# if the value v is a double-quoted string, such as v='"hi"', the
|
|
268
|
+
# entire +define+NAME="hi" needs to wrapped in double quotes with the
|
|
269
|
+
# value v double-quotes escaped: "+define+NAME=\"hi\""
|
|
270
|
+
if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
|
|
271
|
+
str_v = v.replace('"', '\\"')
|
|
272
|
+
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
273
|
+
else:
|
|
274
|
+
# Generally we should only support int and str python types passed as
|
|
275
|
+
# +define+{k}={v}, but also for SystemVerilog plusargs
|
|
276
|
+
vlog_dot_f_lines += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
|
|
268
277
|
|
|
269
278
|
|
|
270
279
|
vlog_dot_f_lines += self.args['compile-args']
|
|
@@ -297,10 +306,17 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
297
306
|
# work around this by setting tcl varaibles for each parameter.
|
|
298
307
|
if self.parameters:
|
|
299
308
|
if not self.use_vopt:
|
|
300
|
-
voptargs_str += ' ' + ' '.join(
|
|
309
|
+
voptargs_str += ' ' + ' '.join(
|
|
310
|
+
self.process_parameters_get_list(
|
|
311
|
+
arg_prefix='-G', hier_delimiter='/', top_hier_str=f'/{self.args["top"]}/'
|
|
312
|
+
)
|
|
313
|
+
)
|
|
301
314
|
else:
|
|
302
315
|
for k,v in self.parameters.items():
|
|
303
|
-
s = sim.parameters_dict_get_command_list(
|
|
316
|
+
s = sim.parameters_dict_get_command_list(
|
|
317
|
+
params={k: v}, arg_prefix='', hier_delimiter='/',
|
|
318
|
+
top_hier_str=f'/{self.args["top"]}/'
|
|
319
|
+
)[0]
|
|
304
320
|
# At this point, s should be a str in form {k}={v}
|
|
305
321
|
if not s or '=' not in s:
|
|
306
322
|
continue
|
|
@@ -310,9 +326,12 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
310
326
|
# we'll do:
|
|
311
327
|
# set PARAMETERS(MyParam) "hi bye"
|
|
312
328
|
# vopt -GMyParam=$PARAMETERS(MyParam)
|
|
313
|
-
|
|
329
|
+
parts = s.split('=')
|
|
330
|
+
_name = parts[0]
|
|
331
|
+
_value = '='.join(parts[1:])
|
|
332
|
+
s = f'set PARAMETERS({_name}) {_value}'
|
|
314
333
|
vopt_do_lines.append(s)
|
|
315
|
-
voptargs_str += f' -G{
|
|
334
|
+
voptargs_str += f' -G{_name}=$PARAMETERS({_name}) '
|
|
316
335
|
else:
|
|
317
336
|
voptargs_str += f' -G{s} '
|
|
318
337
|
|
|
@@ -370,6 +389,10 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
370
389
|
+ f" -sv_seed {self.args['seed']} {sim_plusargs_str} {vsim_suppress_list_str}" \
|
|
371
390
|
+ f" {voptargs_str} {vsim_ext_args} work.{self.args['top']}"
|
|
372
391
|
|
|
392
|
+
# If there are additional top level libs, we wont' add them to the vopt step, add
|
|
393
|
+
# to vsim only (after work.TOP):
|
|
394
|
+
for l in self.args['add-top-library']:
|
|
395
|
+
vsim_one_liner += f' {l}'
|
|
373
396
|
|
|
374
397
|
vsim_one_liner = vsim_one_liner.replace('\n', ' ')
|
|
375
398
|
|
|
@@ -519,3 +542,9 @@ class CommonFListQuesta(CommandFList, ToolQuesta):
|
|
|
519
542
|
def __init__(self, config: dict):
|
|
520
543
|
CommandFList.__init__(self, config=config)
|
|
521
544
|
ToolQuesta.__init__(self, config=self.config)
|
|
545
|
+
self.args.update({
|
|
546
|
+
# an Flist, like vlog.f, cannot support parameters or sim-plusargs, so warn
|
|
547
|
+
# if they are present b/c they will not be emitted.
|
|
548
|
+
'emit-parameter': False,
|
|
549
|
+
'emit-plusargs': False,
|
|
550
|
+
})
|
opencos/tools/questa_fe.py
CHANGED
|
@@ -41,20 +41,6 @@ class CommandSimQuestaFe(CommonSimQuesta):
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def set_tool_defines(self):
|
|
45
|
-
'''Override from questa.ToolQuesta'''
|
|
46
|
-
# Update any defines from config.tools.questa_fse:
|
|
47
|
-
self.defines.update(
|
|
48
|
-
self.tool_config.get(
|
|
49
|
-
'defines',
|
|
50
|
-
# defaults, if not set:
|
|
51
|
-
{
|
|
52
|
-
'OC_TOOL_QUESTA_FE': 1
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
44
|
class CommandElabQuestaFe(CommandSimQuestaFe):
|
|
59
45
|
'''CommandElabQuesta is a command handler for: eda elab --tool=questa_fe'''
|
|
60
46
|
|
opencos/tools/questa_fse.py
CHANGED
|
@@ -38,20 +38,6 @@ class CommandSimQuestaFse(CommonSimQuesta):
|
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def set_tool_defines(self):
|
|
42
|
-
'''Override from questa.ToolQuesta'''
|
|
43
|
-
# Update any defines from config.tools.questa_fse:
|
|
44
|
-
self.defines.update(
|
|
45
|
-
self.tool_config.get(
|
|
46
|
-
'defines',
|
|
47
|
-
# defaults, if not set:
|
|
48
|
-
{
|
|
49
|
-
'OC_TOOL_QUESTA_FSE': 1
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
41
|
class CommandElabQuestaFse(CommandSimQuestaFse):
|
|
56
42
|
'''CommandElabQuestaFse is a command handler for: eda elab --tool=questa_fse'''
|
|
57
43
|
|
opencos/tools/riviera.py
CHANGED
|
@@ -9,6 +9,8 @@ Contains classes for ToolRiviera, CommandSimRiviera, CommandElabRiviera.
|
|
|
9
9
|
import os
|
|
10
10
|
import subprocess
|
|
11
11
|
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
12
14
|
from opencos import util
|
|
13
15
|
from opencos.commands import CommandFList
|
|
14
16
|
from opencos.files import safe_shutil_which
|
|
@@ -65,6 +67,8 @@ class ToolRiviera(ToolQuesta):
|
|
|
65
67
|
class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
66
68
|
'''CommandSimRiviera is a command handler for: eda sim --tool=riviera'''
|
|
67
69
|
|
|
70
|
+
library_map_supported = True
|
|
71
|
+
|
|
68
72
|
def __init__(self, config: dict):
|
|
69
73
|
CommonSimQuesta.__init__(self, config=config)
|
|
70
74
|
|
|
@@ -82,6 +86,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
82
86
|
'waves-fst': True,
|
|
83
87
|
'waves-vcd': False,
|
|
84
88
|
'coverage-tcl': '',
|
|
89
|
+
'ext-defines-sv-fname': '_ext_defines.sv',
|
|
85
90
|
})
|
|
86
91
|
self.args_help.update({
|
|
87
92
|
'waves-fst': (
|
|
@@ -99,6 +104,12 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
99
104
|
'Attempts to support UVM. Adds to vlog: -l uvm +incdir+PATH for the PATH to'
|
|
100
105
|
' uvm_macros.svh for the installed version of Riviera used.'
|
|
101
106
|
),
|
|
107
|
+
'license-queue': (
|
|
108
|
+
'Set to enable env vars (if unset) LICENSE_QUEUE=1, ALDEC_LICENSE_QUEUE=1,'
|
|
109
|
+
' FLEXLM_TIMEOUT=3000000 (3us), which should set Riviera to wait for licenses'
|
|
110
|
+
' instead of immediately exiting with error. You may wish to also set your own'
|
|
111
|
+
' env vars for ALDEC_LICENSE_FILE instead of LM_LICENSE_FILE.'
|
|
112
|
+
),
|
|
102
113
|
})
|
|
103
114
|
|
|
104
115
|
if self.uvm_versions:
|
|
@@ -109,15 +120,6 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
109
120
|
'uvm-version': { 'choices': list(self.uvm_versions) }
|
|
110
121
|
})
|
|
111
122
|
|
|
112
|
-
def set_tool_defines(self):
|
|
113
|
-
# Update any defines from config.tools.modelsim_ase:
|
|
114
|
-
self.defines.update(
|
|
115
|
-
self.tool_config.get(
|
|
116
|
-
'defines',
|
|
117
|
-
# defaults, if not set:
|
|
118
|
-
{'OC_TOOL_RIVIERA': 1}
|
|
119
|
-
)
|
|
120
|
-
)
|
|
121
123
|
|
|
122
124
|
# Note: many of these we follow the same flow as CommandSimModelsimAse:
|
|
123
125
|
# do_it, prepare_compile, compile, elaborate, simulate
|
|
@@ -192,23 +194,33 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
192
194
|
'-dbg'
|
|
193
195
|
])
|
|
194
196
|
|
|
197
|
+
# Note, in Riviera we have to put sim libs in vsim call (with -L) and in vlog (with -l)
|
|
198
|
+
vlog_dot_f_lines.extend([f'-l {x}' for x in self.args['sim-library']])
|
|
199
|
+
|
|
195
200
|
for value in self.incdirs:
|
|
196
201
|
vlog_dot_f_lines += [ f"+incdir+{value}" ]
|
|
197
202
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if
|
|
206
|
-
|
|
207
|
-
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
203
|
+
# For external defines, we will create a file in the work-dir named
|
|
204
|
+
# _ext_defines.sv, it will be the first file in the file list, and it
|
|
205
|
+
# will be valid Verilog/SV, not a list of +define+Name[=Value]
|
|
206
|
+
if self.args['ext-defines-sv-fname']:
|
|
207
|
+
self.create_ext_defines_sv()
|
|
208
|
+
else:
|
|
209
|
+
for k,v in self.defines.items():
|
|
210
|
+
if v is None:
|
|
211
|
+
vlog_dot_f_lines += [ f'+define+{k}' ]
|
|
208
212
|
else:
|
|
209
|
-
#
|
|
210
|
-
# +define+
|
|
211
|
-
|
|
213
|
+
# if the value v is a double-quoted string, such as v='"hi"', the
|
|
214
|
+
# entire +define+NAME="hi" needs to wrapped in double quotes with the
|
|
215
|
+
# value v double-quotes escaped: "+define+NAME=\"hi\""
|
|
216
|
+
if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
|
|
217
|
+
str_v = v.replace('"', '\\"')
|
|
218
|
+
vlog_dot_f_lines += [ f'"+define+{k}={str_v}"' ]
|
|
219
|
+
else:
|
|
220
|
+
# Generally we should only support int and str python types passed as
|
|
221
|
+
# +define+{k}={v}, but also for SystemVerilog plusargs
|
|
222
|
+
vlog_dot_f_lines += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
|
|
223
|
+
|
|
212
224
|
|
|
213
225
|
|
|
214
226
|
vlog_dot_f_lines += self.args['compile-args']
|
|
@@ -261,11 +273,22 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
261
273
|
if all(x not in voptargs_str for x in ('+access +r', '+access +w+r')):
|
|
262
274
|
voptargs_str += ' +access +r'
|
|
263
275
|
|
|
264
|
-
# parameters
|
|
276
|
+
# parameters, for Riviera we need to use the leading forward slash option
|
|
277
|
+
# aka -G/Name=Value, if our parameter name doesn't already have path information.
|
|
278
|
+
# If you do -GName=Value, all parameters in the hierachy with Name will be set,
|
|
279
|
+
# so to only do top level parameters, if hierarchy isn't mentioned in the Name,
|
|
280
|
+
# would need to do -G/{self.args['top']}/Name=Value.
|
|
265
281
|
if self.parameters:
|
|
266
|
-
voptargs_str += ' ' + ' '.join(
|
|
282
|
+
voptargs_str += ' ' + ' '.join(
|
|
283
|
+
self.process_parameters_get_list(
|
|
284
|
+
arg_prefix='-G', hier_delimiter='/', top_hier_str=f'/{self.args["top"]}/'
|
|
285
|
+
)
|
|
286
|
+
)
|
|
267
287
|
|
|
268
|
-
|
|
288
|
+
# Note, in Riviera we have to put sim libs in vsim call (with -L) and in vlog (with -l)
|
|
289
|
+
# we previously updated self.args['sim-library'] with self.update_library_map()
|
|
290
|
+
vmap_lines_str = self.get_vmap_lines_str()
|
|
291
|
+
vsim_libs = ' '.join([f'-L {x}' for x in self.args['sim-library']])
|
|
269
292
|
|
|
270
293
|
vsim_one_liner = (
|
|
271
294
|
"vsim"
|
|
@@ -273,11 +296,16 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
273
296
|
f" {voptargs_str} {vsim_ext_args} {vsim_libs} work.{self.args['top']}"
|
|
274
297
|
)
|
|
275
298
|
|
|
299
|
+
|
|
300
|
+
for l in self.args['add-top-library']:
|
|
301
|
+
vsim_one_liner += f' {l}'
|
|
302
|
+
|
|
276
303
|
vsim_one_liner = vsim_one_liner.replace('\n', ' ') # needs to be a one-liner
|
|
277
304
|
|
|
278
305
|
vsim_vlogonly_dot_do_lines = [
|
|
279
306
|
"if {[file exists work]} { vdel -all work; }",
|
|
280
307
|
"vlib work;",
|
|
308
|
+
vmap_lines_str,
|
|
281
309
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
282
310
|
" echo \"Caught $result \";",
|
|
283
311
|
" if {[batch_mode]} {",
|
|
@@ -293,6 +321,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
293
321
|
"if {[file exists work]} { vdel -all work; }",
|
|
294
322
|
"vlib work;",
|
|
295
323
|
"set qc 30;",
|
|
324
|
+
vmap_lines_str,
|
|
296
325
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
297
326
|
" echo \"Caught $result \";",
|
|
298
327
|
" if {[batch_mode]} {",
|
|
@@ -314,6 +343,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
314
343
|
"if {[file exists work]} { vdel -all work; }",
|
|
315
344
|
"vlib work;",
|
|
316
345
|
"set qc 30;",
|
|
346
|
+
vmap_lines_str,
|
|
317
347
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
318
348
|
" echo \"Caught $result \";",
|
|
319
349
|
" if {[batch_mode]} {",
|
|
@@ -365,6 +395,23 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
365
395
|
f.writelines(line + "\n" for line in vsim_vlogonly_dot_do_lines)
|
|
366
396
|
|
|
367
397
|
|
|
398
|
+
def handle_arg_license_queue(self) -> None:
|
|
399
|
+
'''Handles self.args['license-queue'] (bool) to set env vars
|
|
400
|
+
|
|
401
|
+
Overriden from opencos.command.sim::CommandSim.
|
|
402
|
+
'''
|
|
403
|
+
if not self.args['license-queue']:
|
|
404
|
+
return
|
|
405
|
+
|
|
406
|
+
if 'LICENSE_QUEUE' not in os.environ:
|
|
407
|
+
os.environ['LICENSE_QUEUE'] = '1'
|
|
408
|
+
if 'ALDEC_LICENSE_QUEUE' not in os.environ:
|
|
409
|
+
os.environ['ALDEC_LICENSE_QUEUE'] = '1'
|
|
410
|
+
|
|
411
|
+
# Anecdotal evidence, set this which may help
|
|
412
|
+
if 'FLEXLM_TIMEOUT' not in os.environ:
|
|
413
|
+
os.environ['FLEXLM_TIMEOUT'] = '3000000' # 3e6 us = 3 sec
|
|
414
|
+
|
|
368
415
|
|
|
369
416
|
def _get_vsim_suppress_list_str(self) -> str:
|
|
370
417
|
vsim_suppress_list = []
|
|
@@ -377,6 +424,38 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
377
424
|
|
|
378
425
|
return ' '.join(vsim_suppress_list)
|
|
379
426
|
|
|
427
|
+
def update_library_map(self, base_search_paths: list | None = None) -> None:
|
|
428
|
+
'''Override from sim::CommandSim
|
|
429
|
+
|
|
430
|
+
We add some common places to look relative to the Riviera install paths
|
|
431
|
+
'''
|
|
432
|
+
bsp = []
|
|
433
|
+
if isinstance(base_search_paths, list):
|
|
434
|
+
bsp += base_search_paths
|
|
435
|
+
bsp += [
|
|
436
|
+
Path(self.sim_exe_base_path),
|
|
437
|
+
Path(self.sim_exe_base_path) / '..',
|
|
438
|
+
Path(self.sim_exe_base_path) / '..' / 'vlib',
|
|
439
|
+
]
|
|
440
|
+
super().update_library_map(base_search_paths=bsp)
|
|
441
|
+
|
|
442
|
+
def get_vmap_lines_str(self) -> str:
|
|
443
|
+
'''Returns an empty str, or single str in the form:
|
|
444
|
+
|
|
445
|
+
vmap -global LibraryName AbsolutePathToDotLibFile
|
|
446
|
+
vmap -global LibraryName2 AbsolutePathToAnotherDotLibFile
|
|
447
|
+
...
|
|
448
|
+
uses self.args['library-map'], updates self.args['sim-library']
|
|
449
|
+
'''
|
|
450
|
+
if not self.library_map:
|
|
451
|
+
return ''
|
|
452
|
+
|
|
453
|
+
lines = []
|
|
454
|
+
for lib_name, lib_file_path in self.library_map.items():
|
|
455
|
+
lines.append(f'vmap -global {lib_name} {lib_file_path}')
|
|
456
|
+
|
|
457
|
+
return '\n'.join(lines)
|
|
458
|
+
|
|
380
459
|
|
|
381
460
|
class CommandElabRiviera(CommandSimRiviera):
|
|
382
461
|
'''CommandElabRiviera is a command handler for: eda elab --tool=riviera'''
|
opencos/tools/slang.py
CHANGED
|
@@ -63,7 +63,7 @@ class ToolSlang(Tool):
|
|
|
63
63
|
return self._VERSION
|
|
64
64
|
|
|
65
65
|
def set_tool_defines(self):
|
|
66
|
-
|
|
66
|
+
super().set_tool_defines()
|
|
67
67
|
if 'SYNTHESIS' not in self.defines:
|
|
68
68
|
self.defines['SIMULATION'] = None # add define
|
|
69
69
|
# Expected to manually add SYNTHESIS command line or target, otherwise.
|
|
@@ -139,14 +139,17 @@ class CommandElabSlang(CommandElab, ToolSlang):
|
|
|
139
139
|
command_list += [ '--include-directory', value ]
|
|
140
140
|
|
|
141
141
|
# defines:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
if self.args['ext-defines-sv-fname']:
|
|
143
|
+
self.create_ext_defines_sv()
|
|
144
|
+
else:
|
|
145
|
+
for k,v in self.defines.items():
|
|
146
|
+
command_list.append( '--define-macro' )
|
|
147
|
+
if v is None:
|
|
148
|
+
command_list.append( k )
|
|
149
|
+
else:
|
|
150
|
+
# Generally we should only support int and str python types passed as
|
|
151
|
+
# --define-macro {k}={v}
|
|
152
|
+
command_list.append( f'{k}={sanitize_defines_for_sh(v)}' )
|
|
150
153
|
|
|
151
154
|
# parameters
|
|
152
155
|
command_list.extend(
|
opencos/tools/slang_yosys.py
CHANGED
|
@@ -22,12 +22,6 @@ class ToolSlangYosys(ToolYosys):
|
|
|
22
22
|
'https://github.com/MikePopoloski/slang',
|
|
23
23
|
]
|
|
24
24
|
|
|
25
|
-
def set_tool_defines(self):
|
|
26
|
-
super().set_tool_defines()
|
|
27
|
-
self.defines.update({
|
|
28
|
-
'OC_TOOL_SLANG': None,
|
|
29
|
-
})
|
|
30
|
-
|
|
31
25
|
|
|
32
26
|
class CommandSynthSlangYosys(CommonSynthYosys, ToolSlangYosys):
|
|
33
27
|
'''CommandSynthSlangYosys is a command handler for: eda synth --tool=slang_yosys'''
|
opencos/tools/surelog.py
CHANGED
|
@@ -48,7 +48,7 @@ class ToolSurelog(Tool):
|
|
|
48
48
|
return self._VERSION
|
|
49
49
|
|
|
50
50
|
def set_tool_defines(self):
|
|
51
|
-
|
|
51
|
+
super().set_tool_defines()
|
|
52
52
|
if 'SYNTHESIS' not in self.defines:
|
|
53
53
|
self.defines['SIMULATION'] = None # add define
|
|
54
54
|
# Expected to manually add SYNTHESIS command line or target, otherwise.
|
|
@@ -116,13 +116,16 @@ class CommandElabSurelog(CommandElab, ToolSurelog):
|
|
|
116
116
|
)
|
|
117
117
|
|
|
118
118
|
# defines:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
119
|
+
if self.args['ext-defines-sv-fname']:
|
|
120
|
+
self.create_ext_defines_sv()
|
|
121
|
+
else:
|
|
122
|
+
for k,v in self.defines.items():
|
|
123
|
+
if v is None:
|
|
124
|
+
command_list.append( f'+define+{k}' )
|
|
125
|
+
else:
|
|
126
|
+
# Generally we should only support int and str python types passed as
|
|
127
|
+
# +define+{k}={v}
|
|
128
|
+
command_list.append( f'+define+{k}={sanitize_defines_for_sh(v)}' )
|
|
126
129
|
|
|
127
130
|
# Because many elab target-name won't match the --top needed for
|
|
128
131
|
# slang, we'll leave this to arg --surelog-top:
|
opencos/tools/tabbycad_yosys.py
CHANGED
|
@@ -21,17 +21,11 @@ class ToolTabbyCadYosys(ToolYosys):
|
|
|
21
21
|
_TOOL = 'tabbycad_yosys'
|
|
22
22
|
_URL = 'https://www.yosyshq.com/tabby-cad-datasheet'
|
|
23
23
|
|
|
24
|
-
def set_tool_defines(self):
|
|
25
|
-
super().set_tool_defines()
|
|
26
|
-
self.defines.update({
|
|
27
|
-
'OC_TOOL_TABBYCAD': None,
|
|
28
|
-
})
|
|
29
|
-
|
|
30
24
|
|
|
31
25
|
class CommandSynthTabbyCadYosys(CommonSynthYosys, ToolTabbyCadYosys):
|
|
32
26
|
'''Command handler for: eda synth --tool tabbycad_yosys.'''
|
|
33
27
|
|
|
34
|
-
def __init__(self, config:dict):
|
|
28
|
+
def __init__(self, config: dict):
|
|
35
29
|
CommonSynthYosys.__init__(self, config)
|
|
36
30
|
ToolTabbyCadYosys.__init__(self, config=self.config)
|
|
37
31
|
|
opencos/tools/verilator.py
CHANGED
|
@@ -67,9 +67,6 @@ class ToolVerilator(Tool):
|
|
|
67
67
|
self._VERSION = version
|
|
68
68
|
return self._VERSION
|
|
69
69
|
|
|
70
|
-
def set_tool_defines(self):
|
|
71
|
-
# We don't need to define VERILATOR, the verilated exe does that itself.
|
|
72
|
-
pass
|
|
73
70
|
|
|
74
71
|
class VerilatorSim(CommandSim, ToolVerilator):
|
|
75
72
|
'''VerilatorSim is a command handler for: eda sim --tool=verilator'''
|
|
@@ -150,6 +147,7 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
150
147
|
# We do not override CommandSim.do_it()
|
|
151
148
|
def prepare_compile(self):
|
|
152
149
|
self.set_tool_defines()
|
|
150
|
+
self.update_library_map()
|
|
153
151
|
|
|
154
152
|
# If there are C++ files here, then we will run Verilator in --cc mode:
|
|
155
153
|
if self.files_cpp:
|
|
@@ -222,7 +220,9 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
222
220
|
check_logs=False
|
|
223
221
|
)
|
|
224
222
|
|
|
225
|
-
def get_compile_command_lists(
|
|
223
|
+
def get_compile_command_lists( # pylint: disable=too-many-branches
|
|
224
|
+
self, **kwargs
|
|
225
|
+
) -> list:
|
|
226
226
|
|
|
227
227
|
# Support for lint_only (bool) in kwargs:
|
|
228
228
|
lint_only = kwargs.get('lint_only', False)
|
|
@@ -250,6 +250,10 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
250
250
|
'-top', self.args['top'],
|
|
251
251
|
]
|
|
252
252
|
|
|
253
|
+
if self.args['add-top-library']:
|
|
254
|
+
util.warning('--add-top-library: currently not supported in eda --tool=verilator:',
|
|
255
|
+
f'{self.args["add-top-library"]}')
|
|
256
|
+
|
|
253
257
|
if not lint_only:
|
|
254
258
|
verilate_command_list += [
|
|
255
259
|
'-o', 'sim.exe',
|
|
@@ -268,13 +272,16 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
268
272
|
verilate_command_list += [ f"+incdir+{value}" ]
|
|
269
273
|
|
|
270
274
|
# defines
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
if self.args['ext-defines-sv-fname']:
|
|
276
|
+
self.create_ext_defines_sv()
|
|
277
|
+
else:
|
|
278
|
+
for k,v in self.defines.items():
|
|
279
|
+
if v is None:
|
|
280
|
+
verilate_command_list += [ f'+define+{k}' ]
|
|
281
|
+
else:
|
|
282
|
+
# Generally we should only support int and str python types passed as
|
|
283
|
+
# +define+{k}={v}, but also for SystemVerilog plusargs
|
|
284
|
+
verilate_command_list += [ f'+define+{k}={sanitize_defines_for_sh(v)}' ]
|
|
278
285
|
|
|
279
286
|
# parameters
|
|
280
287
|
verilate_command_list.extend(
|