opencos-eda 0.3.13__py3-none-any.whl → 0.3.15__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/_version.py +3 -1
- opencos/_waves_pkg.sv +50 -19
- opencos/commands/shell.py +1 -1
- opencos/commands/sim.py +78 -4
- opencos/commands/upload.py +2 -2
- opencos/eda_config_defaults.yml +2 -1
- opencos/eda_tool_helper.py +4 -4
- opencos/tools/iverilog.py +1 -0
- opencos/tools/questa_common.py +6 -0
- opencos/tools/riviera.py +56 -4
- opencos/tools/verilator.py +5 -0
- opencos/tools/vivado.py +43 -7
- opencos/tools/yosys.py +7 -2
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/METADATA +1 -1
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/RECORD +20 -20
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/WHEEL +1 -1
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/entry_points.txt +0 -0
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/licenses/LICENSE +0 -0
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/licenses/LICENSE.spdx +0 -0
- {opencos_eda-0.3.13.dist-info → opencos_eda-0.3.15.dist-info}/top_level.txt +0 -0
opencos/_version.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
|
+
# pylint: disable=invalid-name
|
|
6
|
+
|
|
5
7
|
NAME = 'opencos-eda'
|
|
6
8
|
|
|
7
9
|
# Use standard library metadata module starting Python 3.8
|
|
@@ -19,4 +21,4 @@ else:
|
|
|
19
21
|
ver = "unknown" # Or raise an error, or handle differently
|
|
20
22
|
|
|
21
23
|
|
|
22
|
-
VERSION = ver
|
|
24
|
+
VERSION = ver
|
opencos/_waves_pkg.sv
CHANGED
|
@@ -26,27 +26,25 @@ package _waves_pkg;
|
|
|
26
26
|
automatic string trace_str_value = "";
|
|
27
27
|
void'($value$plusargs("trace=%s", trace_str_value));
|
|
28
28
|
if (trace_str_value.tolower() == "vcd") begin
|
|
29
|
-
$display("%t %m: Starting tracing to ./dump.vcd, plusarg +trace
|
|
30
|
-
$realtime, trace_str_value);
|
|
29
|
+
$display("%t %m: Starting tracing to ./dump.vcd, plusarg +trace=vcd", $realtime);
|
|
31
30
|
$dumpfile("dump.vcd");
|
|
32
31
|
$dumpvars();
|
|
33
|
-
|
|
32
|
+
end else begin
|
|
33
|
+
$display("%t %m: Starting tracing to ./dump.fst", $realtime);
|
|
34
|
+
$dumpfile("dump.fst");
|
|
35
|
+
$dumpvars();
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
$display("%t %m: Starting tracing to ./dump.fst", $realtime);
|
|
38
|
-
$dumpfile("dump.fst");
|
|
39
|
-
$dumpvars();
|
|
40
39
|
return 1;
|
|
41
40
|
|
|
42
41
|
endfunction : init_trace
|
|
43
42
|
|
|
44
|
-
`elsif
|
|
43
|
+
`elsif IVERILOG
|
|
45
44
|
|
|
46
45
|
bit trace_en_init = 0;
|
|
47
46
|
bit trace_en = init_trace();
|
|
48
47
|
|
|
49
|
-
// Note: must be non-automatic function for --tool=riviera
|
|
50
48
|
function bit init_trace();
|
|
51
49
|
|
|
52
50
|
if (trace_en_init) // only do this once.
|
|
@@ -55,26 +53,59 @@ package _waves_pkg;
|
|
|
55
53
|
trace_en_init = 1;
|
|
56
54
|
|
|
57
55
|
if ($test$plusargs("trace") != 0) begin
|
|
58
|
-
|
|
56
|
+
$display("%t %m: Starting tracing to ./dump.vcd, plusarg +trace present", $realtime);
|
|
57
|
+
$dumpfile("dump.vcd");
|
|
58
|
+
$dumpvars();
|
|
59
|
+
return 1;
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
endfunction : init_trace
|
|
63
|
+
|
|
64
|
+
`endif
|
|
65
|
+
`endif
|
|
66
|
+
`endif
|
|
67
|
+
|
|
68
|
+
endpackage : _waves_pkg
|
|
69
|
+
|
|
70
|
+
//
|
|
71
|
+
// For RIVIERA (and SIMULATION, and not disabled):
|
|
72
|
+
// - it will not run system calls from a package function, unless that package was
|
|
73
|
+
// used by the testbench
|
|
74
|
+
// - so we have to
|
|
75
|
+
// - create a side module _waves_module. Fortunately the $dumpvars() in riviera
|
|
76
|
+
// dumps all module hier, not just that from _waves_module.
|
|
77
|
+
// - We will have to include work._waves_module in the vsim call (in riviera.py)
|
|
78
|
+
//
|
|
79
|
+
|
|
80
|
+
// TODO(drew): please test this on a file that doesn't involve ocsim_pkg.sv
|
|
81
|
+
|
|
82
|
+
`ifdef SIMULATION
|
|
83
|
+
`ifndef _WAVES_PKG_DISABLE_DUMPFILE // hook to disable this if user chooses
|
|
84
|
+
`ifdef RIVIERA
|
|
85
|
+
|
|
86
|
+
module _waves_module;
|
|
87
|
+
|
|
88
|
+
string trace_str_value = "";
|
|
89
|
+
|
|
90
|
+
initial begin
|
|
91
|
+
|
|
92
|
+
if ($test$plusargs("trace") != 0) begin
|
|
59
93
|
void'($value$plusargs("trace=%s", trace_str_value));
|
|
60
94
|
if (trace_str_value.tolower() == "vcd") begin
|
|
61
|
-
$display("%t %m: Starting tracing to ./dump.vcd, plusarg +trace
|
|
62
|
-
$realtime, trace_str_value);
|
|
95
|
+
$display("%t %m: Starting tracing to ./dump.vcd, plusarg +trace=vcd", $realtime);
|
|
63
96
|
$dumpfile("dump.vcd");
|
|
64
97
|
$dumpvars();
|
|
65
|
-
|
|
98
|
+
end else begin
|
|
99
|
+
$display("%t %m: Starting tracing to ./dump.fst", $realtime);
|
|
100
|
+
$dumpfile("dump.fst");
|
|
101
|
+
$dumpvars();
|
|
66
102
|
end
|
|
67
103
|
end
|
|
68
104
|
|
|
69
|
-
|
|
70
|
-
$dumpfile("dump.fst");
|
|
71
|
-
$dumpvars();
|
|
72
|
-
return 1;
|
|
105
|
+
end
|
|
73
106
|
|
|
74
|
-
|
|
107
|
+
endmodule : _waves_module
|
|
75
108
|
|
|
76
109
|
`endif
|
|
77
110
|
`endif
|
|
78
111
|
`endif
|
|
79
|
-
|
|
80
|
-
endpackage : _waves_pkg
|
opencos/commands/shell.py
CHANGED
|
@@ -9,7 +9,7 @@ Not intended to be overriden by Tool based classes.'''
|
|
|
9
9
|
# These also share a lot with CommandSim.* methods, so consider refactoring to share code,
|
|
10
10
|
# for example, CommandShell.do_export could move to CommandDesign, and derived classes
|
|
11
11
|
# set the allow-listed args to pass to export.
|
|
12
|
-
# pylint: disable=too-many-arguments
|
|
12
|
+
# pylint: disable=too-many-arguments
|
|
13
13
|
|
|
14
14
|
import os
|
|
15
15
|
|
opencos/commands/sim.py
CHANGED
|
@@ -9,17 +9,22 @@ Note that CommandSim is also a base class for opencos.commands.elab.CommandElab.
|
|
|
9
9
|
# pylint: disable=R0801
|
|
10
10
|
|
|
11
11
|
# TODO(drew): clean up CommandSim.check_logs_for_errors and CommandSim.run_commands_check_logs
|
|
12
|
-
# pylint: disable=too-many-arguments
|
|
12
|
+
# pylint: disable=too-many-arguments
|
|
13
13
|
|
|
14
14
|
import os
|
|
15
15
|
import shlex
|
|
16
16
|
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
17
19
|
from opencos import util, export_helper
|
|
18
20
|
from opencos.eda_base import CommandDesign, Tool
|
|
19
21
|
from opencos.utils import status_constants
|
|
20
22
|
|
|
21
23
|
from opencos.utils.str_helpers import strip_outer_quotes
|
|
22
24
|
|
|
25
|
+
THISPATH = os.path.dirname(__file__)
|
|
26
|
+
WAVES_PKG_SV_FNAME = str((Path(THISPATH) / '..' / '_waves_pkg.sv').resolve())
|
|
27
|
+
|
|
23
28
|
def parameters_dict_get_command_list(
|
|
24
29
|
params: dict, arg_prefix: str = '-G',
|
|
25
30
|
hier_delimiter: str = '.',
|
|
@@ -84,6 +89,7 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
84
89
|
error_on_no_files_or_targets = True
|
|
85
90
|
error_on_missing_top = True
|
|
86
91
|
tool_config = {} # Children with Tool parent classes will set on Tool constructor.
|
|
92
|
+
library_map_supported = False
|
|
87
93
|
|
|
88
94
|
command_name = 'sim'
|
|
89
95
|
|
|
@@ -114,6 +120,8 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
114
120
|
'verilate-args': [],
|
|
115
121
|
'ext-defines-sv-fname': '',
|
|
116
122
|
'license-queue': False,
|
|
123
|
+
'library-map': [],
|
|
124
|
+
'add-top-library': [],
|
|
117
125
|
})
|
|
118
126
|
self.args_help.update({
|
|
119
127
|
'pre-sim-tcl': (
|
|
@@ -168,6 +176,17 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
168
176
|
'license-queue': (
|
|
169
177
|
'Set to enable env vars LICENSE_QUEUE=1 which has effects on certain simulators'
|
|
170
178
|
),
|
|
179
|
+
'library-map': (
|
|
180
|
+
'list arg (can set multiple) with values LibName:Path, only supported'
|
|
181
|
+
' by certain simulation tools.'
|
|
182
|
+
' The Path search is relative to the tool exe, one level above the tool exe,'
|
|
183
|
+
' or can be absolute path.'
|
|
184
|
+
),
|
|
185
|
+
'add-top-library': (
|
|
186
|
+
'Add additional top levels, for example if you added the "unisim" library'
|
|
187
|
+
' you may need to --add-top-library=unisim.glbl for it to work with Xilinx'
|
|
188
|
+
' based projects that require "glbl" to be present at simulation $root scope.'
|
|
189
|
+
),
|
|
171
190
|
|
|
172
191
|
})
|
|
173
192
|
|
|
@@ -175,6 +194,9 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
175
194
|
'uvm-version': { 'choices': ['1.2'] },
|
|
176
195
|
})
|
|
177
196
|
|
|
197
|
+
# only used if self.library_map_supported=True:
|
|
198
|
+
self.library_map = {} # lib-name: path-to.lib dict from self.args['library-map']
|
|
199
|
+
|
|
178
200
|
|
|
179
201
|
|
|
180
202
|
def process_parameters_get_list(
|
|
@@ -425,7 +447,7 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
425
447
|
cmds2 = self.get_simulate_command_lists()
|
|
426
448
|
cmds3 = self.get_post_simulate_command_lists()
|
|
427
449
|
'''
|
|
428
|
-
|
|
450
|
+
self.update_library_map()
|
|
429
451
|
|
|
430
452
|
|
|
431
453
|
def check_logs_for_errors( # pylint: disable=dangerous-default-value,too-many-locals,too-many-branches
|
|
@@ -619,8 +641,7 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
619
641
|
break
|
|
620
642
|
|
|
621
643
|
if not found_dumpfile:
|
|
622
|
-
|
|
623
|
-
file_to_add = os.path.join(thispath, '..', '_waves_pkg.sv')
|
|
644
|
+
file_to_add = WAVES_PKG_SV_FNAME
|
|
624
645
|
util.info(f'--waves arg present, no $dumpfile found, adding SV file: {file_to_add}')
|
|
625
646
|
self.add_file(file_to_add)
|
|
626
647
|
|
|
@@ -686,3 +707,56 @@ class CommandSim(CommandDesign): # pylint: disable=too-many-public-methods
|
|
|
686
707
|
|
|
687
708
|
if 'LICENSE_QUEUE' not in os.environ:
|
|
688
709
|
os.environ['LICENSE_QUEUE'] = '1'
|
|
710
|
+
|
|
711
|
+
def update_library_map( # pylint: disable=dangerous-default-value
|
|
712
|
+
self, base_search_paths: list = []
|
|
713
|
+
) -> None:
|
|
714
|
+
'''
|
|
715
|
+
Returns None, uses self.args['library-map'] to update:
|
|
716
|
+
|
|
717
|
+
- self.library_map (dict)
|
|
718
|
+
- self.args['sim-library']
|
|
719
|
+
'''
|
|
720
|
+
if not self.args['library-map']:
|
|
721
|
+
return
|
|
722
|
+
|
|
723
|
+
if not self.library_map_supported:
|
|
724
|
+
tool = self.config.get('tool', None)
|
|
725
|
+
util.warning(f'Command: sim, --tool={tool}, args for --library-map are not supported:',
|
|
726
|
+
f'{self.args["library-map"]}')
|
|
727
|
+
return
|
|
728
|
+
|
|
729
|
+
for libmap in self.args['library-map']:
|
|
730
|
+
parts = libmap.split(':')
|
|
731
|
+
lib_name = parts[0]
|
|
732
|
+
lib_path = Path(':'.join(parts[1:]))
|
|
733
|
+
lib_abs_path = None
|
|
734
|
+
|
|
735
|
+
if not lib_name or not lib_path:
|
|
736
|
+
util.warning(f'library-map={libmap} could not parse {lib_name=} or {lib_path=}')
|
|
737
|
+
continue
|
|
738
|
+
|
|
739
|
+
if lib_name in self.library_map:
|
|
740
|
+
util.warning(
|
|
741
|
+
f'We have already mapped "{lib_name}" to {self.library_map[lib_name]}'
|
|
742
|
+
)
|
|
743
|
+
|
|
744
|
+
# We have to go looking for lib_path though
|
|
745
|
+
search_files = [lib_path]
|
|
746
|
+
if base_search_paths:
|
|
747
|
+
for x in base_search_paths:
|
|
748
|
+
search_files.append(Path(x) / lib_path)
|
|
749
|
+
for x in search_files:
|
|
750
|
+
if x.exists():
|
|
751
|
+
lib_abs_path = x.resolve()
|
|
752
|
+
util.info(f'library-map={libmap} found "{lib_name}" in: {lib_abs_path}')
|
|
753
|
+
break
|
|
754
|
+
util.debug(f'library-map={libmap} searching for "{lib_name}" in: {x}')
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
if lib_abs_path:
|
|
758
|
+
self.library_map[lib_name] = lib_abs_path
|
|
759
|
+
if lib_name not in self.args['sim-library']:
|
|
760
|
+
self.args['sim-library'].append(lib_name)
|
|
761
|
+
else:
|
|
762
|
+
util.warning(f'library-map={libmap}, for "{lib_name}" could not find {lib_path=}')
|
opencos/commands/upload.py
CHANGED
|
@@ -123,7 +123,7 @@ class CommandUpload(Command):
|
|
|
123
123
|
def get_list_bitfiles(self, display: bool = True) -> list:
|
|
124
124
|
'''Returns a list of bit files (ending with self.SUPPORTED_BIT_EXT)'''
|
|
125
125
|
|
|
126
|
-
bitfiles
|
|
126
|
+
bitfiles = [] # list[Path]
|
|
127
127
|
|
|
128
128
|
targets, files = self.get_targets_or_files_from_unparsed_args()
|
|
129
129
|
targets.extend(files)
|
|
@@ -136,7 +136,7 @@ class CommandUpload(Command):
|
|
|
136
136
|
if os.path.isfile(fullpath) and fullpath not in bitfiles:
|
|
137
137
|
bitfiles.append(fullpath)
|
|
138
138
|
|
|
139
|
-
matched
|
|
139
|
+
matched = [] # list[Path]
|
|
140
140
|
for cand in bitfiles:
|
|
141
141
|
debug(f"Looking for {cand=} in {targets=}")
|
|
142
142
|
passing = all(re.search(t, str(cand)) for t in targets)
|
opencos/eda_config_defaults.yml
CHANGED
|
@@ -412,7 +412,8 @@ tools:
|
|
|
412
412
|
-acdb -acdb_cov sbfectapm
|
|
413
413
|
simulate-coverage-tcl:
|
|
414
414
|
- acdb save
|
|
415
|
-
- acdb report -
|
|
415
|
+
- acdb report -i work.acdb -txt -o cov.txt
|
|
416
|
+
- acdb report -i work.acdb -txt -o covg.txt -show covergroups
|
|
416
417
|
|
|
417
418
|
|
|
418
419
|
modelsim_ase:
|
opencos/eda_tool_helper.py
CHANGED
|
@@ -111,8 +111,8 @@ def get_handler_tool_version(tool: str, eda_command: str, config: dict) -> str:
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
|
|
114
|
-
def get_handler_info_with_versions( # pylint: disable=too-many-branches
|
|
115
|
-
config: dict
|
|
114
|
+
def get_handler_info_with_versions( # pylint: disable=too-many-branches,dangerous-default-value
|
|
115
|
+
config: dict = {},
|
|
116
116
|
include_commands: bool = True,
|
|
117
117
|
sort: bool = True
|
|
118
118
|
) -> str:
|
|
@@ -202,8 +202,8 @@ def get_handler_info_with_versions( # pylint: disable=too-many-branches
|
|
|
202
202
|
return info
|
|
203
203
|
|
|
204
204
|
|
|
205
|
-
def pretty_info_handler_tools(
|
|
206
|
-
info: dict
|
|
205
|
+
def pretty_info_handler_tools( # pylint: disable=dangerous-default-value
|
|
206
|
+
info: dict = {}, config: dict = {}, command: str = ''
|
|
207
207
|
) -> None:
|
|
208
208
|
'''Pretty print (via util.info) the result from get_handler_info_with_versions()
|
|
209
209
|
|
opencos/tools/iverilog.py
CHANGED
|
@@ -70,6 +70,7 @@ class CommandSimIverilog(CommandSim, ToolIverilog):
|
|
|
70
70
|
# We do not override CommandSim.do_it()
|
|
71
71
|
def prepare_compile(self):
|
|
72
72
|
self.set_tool_defines()
|
|
73
|
+
self.update_library_map()
|
|
73
74
|
|
|
74
75
|
self.iverilog_command_lists = self.get_compile_command_lists()
|
|
75
76
|
self.iverilog_exec_command_lists = self.get_simulate_command_lists()
|
opencos/tools/questa_common.py
CHANGED
|
@@ -150,6 +150,8 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
150
150
|
|
|
151
151
|
def prepare_compile(self):
|
|
152
152
|
self.set_tool_defines()
|
|
153
|
+
self.update_library_map()
|
|
154
|
+
self.add_waves_pkg_file()
|
|
153
155
|
self.write_vlog_dot_f()
|
|
154
156
|
self.write_vsim_dot_do(dot_do_to_write='all')
|
|
155
157
|
|
|
@@ -388,6 +390,10 @@ class CommonSimQuesta(CommandSim, ToolQuesta):
|
|
|
388
390
|
+ f" -sv_seed {self.args['seed']} {sim_plusargs_str} {vsim_suppress_list_str}" \
|
|
389
391
|
+ f" {voptargs_str} {vsim_ext_args} work.{self.args['top']}"
|
|
390
392
|
|
|
393
|
+
# If there are additional top level libs, we wont' add them to the vopt step, add
|
|
394
|
+
# to vsim only (after work.TOP):
|
|
395
|
+
for l in self.args['add-top-library']:
|
|
396
|
+
vsim_one_liner += f' {l}'
|
|
391
397
|
|
|
392
398
|
vsim_one_liner = vsim_one_liner.replace('\n', ' ')
|
|
393
399
|
|
opencos/tools/riviera.py
CHANGED
|
@@ -9,9 +9,12 @@ 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
|
|
17
|
+
from opencos.commands.sim import WAVES_PKG_SV_FNAME
|
|
15
18
|
from opencos.tools.questa_common import ToolQuesta, CommonSimQuesta
|
|
16
19
|
from opencos.utils.str_helpers import sanitize_defines_for_sh
|
|
17
20
|
from opencos.utils import status_constants
|
|
@@ -65,6 +68,8 @@ class ToolRiviera(ToolQuesta):
|
|
|
65
68
|
class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
66
69
|
'''CommandSimRiviera is a command handler for: eda sim --tool=riviera'''
|
|
67
70
|
|
|
71
|
+
library_map_supported = True
|
|
72
|
+
|
|
68
73
|
def __init__(self, config: dict):
|
|
69
74
|
CommonSimQuesta.__init__(self, config=config)
|
|
70
75
|
|
|
@@ -123,8 +128,6 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
123
128
|
def compile(self):
|
|
124
129
|
'''Override for CommandSimModelsimAse.compile() so we can set our own must_strings'''
|
|
125
130
|
|
|
126
|
-
self.add_waves_pkg_file()
|
|
127
|
-
|
|
128
131
|
if self.args['stop-before-compile']:
|
|
129
132
|
# don't run anything, save everyting we've already run in _prep_compile()
|
|
130
133
|
return
|
|
@@ -190,6 +193,9 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
190
193
|
'-dbg'
|
|
191
194
|
])
|
|
192
195
|
|
|
196
|
+
# Note, in Riviera we have to put sim libs in vsim call (with -L) and in vlog (with -l)
|
|
197
|
+
vlog_dot_f_lines.extend([f'-l {x}' for x in self.args['sim-library']])
|
|
198
|
+
|
|
193
199
|
for value in self.incdirs:
|
|
194
200
|
vlog_dot_f_lines += [ f"+incdir+{value}" ]
|
|
195
201
|
|
|
@@ -233,7 +239,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
233
239
|
|
|
234
240
|
|
|
235
241
|
|
|
236
|
-
def write_vsim_dot_do( # pylint: disable=too-many-branches,too-many-locals
|
|
242
|
+
def write_vsim_dot_do( # pylint: disable=too-many-branches,too-many-locals,too-many-statements
|
|
237
243
|
self, dot_do_to_write: list
|
|
238
244
|
) -> None:
|
|
239
245
|
'''Writes files(s) based on dot_do_to_write(list of str)
|
|
@@ -278,7 +284,10 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
278
284
|
)
|
|
279
285
|
)
|
|
280
286
|
|
|
281
|
-
|
|
287
|
+
# Note, in Riviera we have to put sim libs in vsim call (with -L) and in vlog (with -l)
|
|
288
|
+
# we previously updated self.args['sim-library'] with self.update_library_map()
|
|
289
|
+
vmap_lines_str = self.get_vmap_lines_str()
|
|
290
|
+
vsim_libs = ' '.join([f'-L {x}' for x in self.args['sim-library']])
|
|
282
291
|
|
|
283
292
|
vsim_one_liner = (
|
|
284
293
|
"vsim"
|
|
@@ -286,11 +295,20 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
286
295
|
f" {voptargs_str} {vsim_ext_args} {vsim_libs} work.{self.args['top']}"
|
|
287
296
|
)
|
|
288
297
|
|
|
298
|
+
if self.args['waves'] and WAVES_PKG_SV_FNAME in self.files:
|
|
299
|
+
# kind of a hack, but add _waves_module (from _waves_pkg.sv) if that file
|
|
300
|
+
# was in our files list.
|
|
301
|
+
vsim_one_liner += ' work._waves_module'
|
|
302
|
+
|
|
303
|
+
for l in self.args['add-top-library']:
|
|
304
|
+
vsim_one_liner += f' {l}'
|
|
305
|
+
|
|
289
306
|
vsim_one_liner = vsim_one_liner.replace('\n', ' ') # needs to be a one-liner
|
|
290
307
|
|
|
291
308
|
vsim_vlogonly_dot_do_lines = [
|
|
292
309
|
"if {[file exists work]} { vdel -all work; }",
|
|
293
310
|
"vlib work;",
|
|
311
|
+
vmap_lines_str,
|
|
294
312
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
295
313
|
" echo \"Caught $result \";",
|
|
296
314
|
" if {[batch_mode]} {",
|
|
@@ -306,6 +324,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
306
324
|
"if {[file exists work]} { vdel -all work; }",
|
|
307
325
|
"vlib work;",
|
|
308
326
|
"set qc 30;",
|
|
327
|
+
vmap_lines_str,
|
|
309
328
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
310
329
|
" echo \"Caught $result \";",
|
|
311
330
|
" if {[batch_mode]} {",
|
|
@@ -327,6 +346,7 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
327
346
|
"if {[file exists work]} { vdel -all work; }",
|
|
328
347
|
"vlib work;",
|
|
329
348
|
"set qc 30;",
|
|
349
|
+
vmap_lines_str,
|
|
330
350
|
"if {[catch {vlog -f vlog.f} result]} {",
|
|
331
351
|
" echo \"Caught $result \";",
|
|
332
352
|
" if {[batch_mode]} {",
|
|
@@ -407,6 +427,38 @@ class CommandSimRiviera(CommonSimQuesta, ToolRiviera):
|
|
|
407
427
|
|
|
408
428
|
return ' '.join(vsim_suppress_list)
|
|
409
429
|
|
|
430
|
+
def update_library_map( # pylint: disable=dangerous-default-value
|
|
431
|
+
self, base_search_paths: list = []
|
|
432
|
+
) -> None:
|
|
433
|
+
'''Override from sim::CommandSim
|
|
434
|
+
|
|
435
|
+
We add some common places to look relative to the Riviera install paths
|
|
436
|
+
'''
|
|
437
|
+
bsp = [] + base_search_paths
|
|
438
|
+
bsp += [
|
|
439
|
+
Path(self.sim_exe_base_path),
|
|
440
|
+
Path(self.sim_exe_base_path) / '..',
|
|
441
|
+
Path(self.sim_exe_base_path) / '..' / 'vlib',
|
|
442
|
+
]
|
|
443
|
+
super().update_library_map(base_search_paths=bsp)
|
|
444
|
+
|
|
445
|
+
def get_vmap_lines_str(self) -> str:
|
|
446
|
+
'''Returns an empty str, or single str in the form:
|
|
447
|
+
|
|
448
|
+
vmap -global LibraryName AbsolutePathToDotLibFile
|
|
449
|
+
vmap -global LibraryName2 AbsolutePathToAnotherDotLibFile
|
|
450
|
+
...
|
|
451
|
+
uses self.args['library-map'], updates self.args['sim-library']
|
|
452
|
+
'''
|
|
453
|
+
if not self.library_map:
|
|
454
|
+
return ''
|
|
455
|
+
|
|
456
|
+
lines = []
|
|
457
|
+
for lib_name, lib_file_path in self.library_map.items():
|
|
458
|
+
lines.append(f'vmap -global {lib_name} {lib_file_path}')
|
|
459
|
+
|
|
460
|
+
return '\n'.join(lines)
|
|
461
|
+
|
|
410
462
|
|
|
411
463
|
class CommandElabRiviera(CommandSimRiviera):
|
|
412
464
|
'''CommandElabRiviera is a command handler for: eda elab --tool=riviera'''
|
opencos/tools/verilator.py
CHANGED
|
@@ -147,6 +147,7 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
147
147
|
# We do not override CommandSim.do_it()
|
|
148
148
|
def prepare_compile(self):
|
|
149
149
|
self.set_tool_defines()
|
|
150
|
+
self.update_library_map()
|
|
150
151
|
|
|
151
152
|
# If there are C++ files here, then we will run Verilator in --cc mode:
|
|
152
153
|
if self.files_cpp:
|
|
@@ -249,6 +250,10 @@ class VerilatorSim(CommandSim, ToolVerilator):
|
|
|
249
250
|
'-top', self.args['top'],
|
|
250
251
|
]
|
|
251
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
|
+
|
|
252
257
|
if not lint_only:
|
|
253
258
|
verilate_command_list += [
|
|
254
259
|
'-o', 'sim.exe',
|
opencos/tools/vivado.py
CHANGED
|
@@ -39,7 +39,10 @@ class ToolVivado(Tool):
|
|
|
39
39
|
})
|
|
40
40
|
self.args_help.update({
|
|
41
41
|
'part': 'Device used for commands: synth, build.',
|
|
42
|
-
'add-glbl-v':
|
|
42
|
+
'add-glbl-v': (
|
|
43
|
+
'(for simulation) add glbl.v to filelist, "glbl" to sim libraries, and "glbl"'
|
|
44
|
+
' as an additional top level hier.'
|
|
45
|
+
),
|
|
43
46
|
})
|
|
44
47
|
|
|
45
48
|
|
|
@@ -124,6 +127,8 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
124
127
|
Note that we attempt to run a generated .tcl script within vivado, that will perform the
|
|
125
128
|
3-step compile/elaborate/simulate steps'''
|
|
126
129
|
|
|
130
|
+
library_map_supported = True
|
|
131
|
+
|
|
127
132
|
def __init__(self, config: dict):
|
|
128
133
|
CommandSim.__init__(self, config)
|
|
129
134
|
ToolVivado.__init__(self, config=self.config)
|
|
@@ -139,7 +144,16 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
139
144
|
'gui': 'Run Vivado XSim in GUI mode',
|
|
140
145
|
'tcl-file': 'name of TCL file to be created for XSim',
|
|
141
146
|
'fpga': 'FPGA device name, can be used for various Xilinx IP or XCIs',
|
|
142
|
-
'add-glbl-v':
|
|
147
|
+
'add-glbl-v': (
|
|
148
|
+
'Use the glbl.v in xvlog, xelab for this version of Vivado. Adds glbl.v to'
|
|
149
|
+
' filelist(s), and add "glbl" as an additional top level hier to xelab.'
|
|
150
|
+
),
|
|
151
|
+
'library-map': (
|
|
152
|
+
'list arg (can set multiple) with values LibName:Path, for example:'
|
|
153
|
+
' --library-map=unisim:path/to/custom_lib_name.lib'
|
|
154
|
+
' The Path search is relative to the tool exe, one level above the tool exe,'
|
|
155
|
+
' or can be absolute path.'
|
|
156
|
+
)
|
|
143
157
|
})
|
|
144
158
|
|
|
145
159
|
self.sim_libraries = self.tool_config.get('sim-libraries', [])
|
|
@@ -165,6 +179,7 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
165
179
|
|
|
166
180
|
def prepare_compile(self):
|
|
167
181
|
self.set_tool_defines()
|
|
182
|
+
self.update_library_map()
|
|
168
183
|
|
|
169
184
|
# Don't use the return values, these will set values in self.vivado_tcl:
|
|
170
185
|
self.get_compile_command_lists()
|
|
@@ -321,11 +336,13 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
321
336
|
command_list += ['-debug', 'wave']
|
|
322
337
|
if util.args['verbose']:
|
|
323
338
|
command_list += ['-v', '2']
|
|
324
|
-
if self.args['sim-library']
|
|
339
|
+
if self.args['sim-library']:
|
|
325
340
|
self.sim_libraries += self.args['sim-library'] # Add any command line libraries
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
341
|
+
for x in self.sim_libraries:
|
|
342
|
+
command_list += ['-L', x]
|
|
343
|
+
if self.args['add-top-library']:
|
|
344
|
+
command_list += self.args['add-top-library'] # list
|
|
345
|
+
|
|
329
346
|
command_list += self.args['elab-args']
|
|
330
347
|
|
|
331
348
|
# For Windows compatibility, we have some issues with command/Powershell passing args
|
|
@@ -447,6 +464,10 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
447
464
|
command_list += self.tool_config.get('compile-args', '').split()
|
|
448
465
|
if util.args['verbose']:
|
|
449
466
|
command_list += ['-v', '2']
|
|
467
|
+
|
|
468
|
+
# If there were any external .lib files from --library-map args, add those now:
|
|
469
|
+
command_list.extend(self._get_xvlog_library_map_list())
|
|
470
|
+
|
|
450
471
|
for value in self.incdirs:
|
|
451
472
|
command_list.append('-i')
|
|
452
473
|
command_list.append(Path(value).as_posix())
|
|
@@ -491,13 +512,28 @@ class CommandSimVivado(CommandSim, ToolVivado):
|
|
|
491
512
|
glbl_v = self.vivado_base_path.replace(
|
|
492
513
|
'bin', os.path.join('data', 'verilog', 'src', 'glbl.v')
|
|
493
514
|
)
|
|
494
|
-
if any(x.
|
|
515
|
+
if any(x and os.path.split(x)[1] == 'glbl.v' for x in self.files_v):
|
|
495
516
|
util.warning(f'--add-glbl-v: Not adding {glbl_v=} b/c glbl.v already in',
|
|
496
517
|
f'{self.files_v=}')
|
|
497
518
|
elif not os.path.exists(glbl_v):
|
|
498
519
|
self.error(f"Could not find file {glbl_v=}")
|
|
499
520
|
else:
|
|
500
521
|
self.files_v.insert(0, glbl_v)
|
|
522
|
+
# add to self.args['add-top-library']
|
|
523
|
+
if 'glbl' not in self.args['add-top-library']:
|
|
524
|
+
self.args['add-top-library'].append('glbl')
|
|
525
|
+
|
|
526
|
+
def _get_xvlog_library_map_list(self) -> list:
|
|
527
|
+
'''Returns list of lines used in vlog step for --library-map args
|
|
528
|
+
|
|
529
|
+
Note that Vivado does not do library name re-mapping, the name comes
|
|
530
|
+
from the .lib file internals.
|
|
531
|
+
'''
|
|
532
|
+
|
|
533
|
+
lines = []
|
|
534
|
+
for _, lib_file_path in self.library_map.items():
|
|
535
|
+
lines.append(f'-libmap {lib_file_path}')
|
|
536
|
+
return lines
|
|
501
537
|
|
|
502
538
|
|
|
503
539
|
def artifacts_add(self, name: str, typ: str, description: str) -> None:
|
opencos/tools/yosys.py
CHANGED
|
@@ -22,7 +22,7 @@ def get_commands_to_run_scriptfiles(
|
|
|
22
22
|
|
|
23
23
|
list of yoysys script(s)'''
|
|
24
24
|
|
|
25
|
-
if script_fnames_list:
|
|
25
|
+
if not script_fnames_list:
|
|
26
26
|
return []
|
|
27
27
|
|
|
28
28
|
yosys_cmdlists = []
|
|
@@ -142,7 +142,12 @@ class CommonSynthYosys(CommandSynth, ToolYosys):
|
|
|
142
142
|
'yosys-scriptfile': (
|
|
143
143
|
'Instead of using a built-in flow from eda, use your own scripts that are called'
|
|
144
144
|
' via: yosys --scriptfile <this-arg>. You can set multiple args for multiple'
|
|
145
|
-
' scriptfile (appends)'
|
|
145
|
+
' scriptfile (appends). NOTE: the default for eda is to run in a work-dir such as'
|
|
146
|
+
' ./eda.work/<target>.synth/, which means you may want to use absolute paths for'
|
|
147
|
+
' source files (.sv, etc) in your custom scriptfile, or use ../.. to get back to '
|
|
148
|
+
' the current directory. If you want to run in place and avoid'
|
|
149
|
+
' ./eda.work/<target>.synth/ you can use arg --work-dir=. or to run in place from'
|
|
150
|
+
' the DEPS target directory, use --work-dir-use-target-dir'
|
|
146
151
|
),
|
|
147
152
|
'sta-scriptfile': (
|
|
148
153
|
'Instead of using a built-in flow from eda, use your own script that is called'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencos-eda
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.15
|
|
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
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
opencos/__init__.py,sha256=RwJA9oc1uUlvNX7v5zoqwjnSRNq2NZwRlHqtS-ICJkI,122
|
|
2
|
-
opencos/_version.py,sha256=
|
|
3
|
-
opencos/_waves_pkg.sv,sha256=
|
|
2
|
+
opencos/_version.py,sha256=FLlmTepF7P0hC-506fgEvv3NSxGxtWgeR7g2UkNK7PI,618
|
|
3
|
+
opencos/_waves_pkg.sv,sha256=yWojzRYVIqV2H5xa5e0v34LgK4oLMu3k9_N8EYXy2f0,2852
|
|
4
4
|
opencos/deps_schema.py,sha256=wKRMuFzOIapwpCPFGvWGM8Mcwdh9yngHOiDRMmvUaIg,17394
|
|
5
5
|
opencos/eda.py,sha256=2vJLMYMW9muWieNaOJz-U5EIVchmVyhTfmEcnZwQtvg,37382
|
|
6
6
|
opencos/eda_base.py,sha256=-nguHrrYVb8a853HEMfFrOoXlsEEeRnDdFR66nTwX0s,124332
|
|
7
7
|
opencos/eda_config.py,sha256=EPW0rhnbrpfV9h0OtKrp7By19FcEyDXT2-ud7y4jbRU,17266
|
|
8
|
-
opencos/eda_config_defaults.yml,sha256=
|
|
8
|
+
opencos/eda_config_defaults.yml,sha256=0rq6DNw2U0OjuoZPmYVDgPwu_WoaGUQmaNE3l7sP4wA,21601
|
|
9
9
|
opencos/eda_config_reduced.yml,sha256=BOKGfe-OmVIF0SKhTTglPIzfAoGuCZ8n-f2KpoLF8dk,883
|
|
10
10
|
opencos/eda_deps_bash_completion.bash,sha256=o1yZvGUQSbN-AYq95sDTzMFw7gNHCUSlv9tASEHnACA,2763
|
|
11
11
|
opencos/eda_deps_sanitize.py,sha256=SQjvrte9Hv9JesRY0wljvbdC6pAmLCikI-Wdzzy-D04,1939
|
|
12
12
|
opencos/eda_extract_targets.py,sha256=POlxZfqf2dNH2nc1CEw5B_53vSHAicSTkpU9_-2_6Zw,2851
|
|
13
|
-
opencos/eda_tool_helper.py,sha256=
|
|
13
|
+
opencos/eda_tool_helper.py,sha256=7KY-E7wnWCNRHXeekDg1tFivcZw86-MsrmXiw7Fc6h0,8578
|
|
14
14
|
opencos/export_helper.py,sha256=zDkvsUS6FVrpXl1UTy53QG3CuhYp5FFplI9rRzAE2g8,25395
|
|
15
15
|
opencos/export_json_convert.py,sha256=tSIMbLFtc_Fo66EhFovMii1v_qJYyFZJrPNnoPdW7L0,4182
|
|
16
16
|
opencos/files.py,sha256=-vHrddbFrwxEHU47VzeyLOU93q8XSXAmPiopClfV-bs,2296
|
|
@@ -29,12 +29,12 @@ opencos/commands/lint.py,sha256=piPb0l0zE3sAtNJkFQ-oNpuHxnaV_RNXkXtEj_9mwGs,1594
|
|
|
29
29
|
opencos/commands/multi.py,sha256=urm-IDllnMZWScH7e6Pg4ukHGHILBd4NbPlPmHU3vsw,27624
|
|
30
30
|
opencos/commands/open.py,sha256=XckvKUNwvc5KHbYGV-eQ2i0WG4X-yckroDaMC610MB4,804
|
|
31
31
|
opencos/commands/proj.py,sha256=cExW9ZZkw6nkpVyNfeQzJADzmPtbYgBgWml82tqO6jY,1158
|
|
32
|
-
opencos/commands/shell.py,sha256=
|
|
33
|
-
opencos/commands/sim.py,sha256
|
|
32
|
+
opencos/commands/shell.py,sha256=WPKS27fTr0MG4Gqz_RzSwv4n8AINuQ_ntSmJtHeat_I,7771
|
|
33
|
+
opencos/commands/sim.py,sha256=-dBxyHWMlUeLllsyhHa82jYKcLWxZA9qntS_vbeV3V0,31569
|
|
34
34
|
opencos/commands/sweep.py,sha256=62XmDHT-prdxJNy-6MbK6wEGJm1YC9caOaJapoekQ8s,9325
|
|
35
35
|
opencos/commands/synth.py,sha256=Qs6FP9Ge_gp9TH3EFzVXKFlrrqrMwIbr38VYVlZvmeA,4557
|
|
36
36
|
opencos/commands/targets.py,sha256=_jRNhm2Fqj0fmMvTw6Ba39DCsRHf_r_uZCy_R064kpA,1472
|
|
37
|
-
opencos/commands/upload.py,sha256=
|
|
37
|
+
opencos/commands/upload.py,sha256=OGMI4By0942jL9LK7xBy5_WjvVzRbAr_RB3rS5fNobI,7917
|
|
38
38
|
opencos/commands/waves.py,sha256=LYF1UcxkHFYYtYoebnh9iE_on80PbbmzIpaSk-XtZcI,9232
|
|
39
39
|
opencos/deps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
40
|
opencos/deps/defaults.py,sha256=Z6mIVJEV0zQ9rC-HkQFMBFAkixjqKS1TATPSc27wOeA,1502
|
|
@@ -61,21 +61,21 @@ opencos/tools/cocotb.py,sha256=mkhdbBbkOcPPct1TZcKH6wPPT7pjzRH_6wCNH2qgXOM,19660
|
|
|
61
61
|
opencos/tools/invio.py,sha256=pxrS5oaNTcEv-ToXdhFBJZF5XhTmZnJz9CQ8NnLoty8,3155
|
|
62
62
|
opencos/tools/invio_helpers.py,sha256=86WOGmSf4m_lEqBtK3DLjWqI0jnqAWzBEBRYfBUGiSY,8804
|
|
63
63
|
opencos/tools/invio_yosys.py,sha256=zPVX5Bv-mR4zaUZiH0QqGF4Vbm_LXAf75mDW6ywse5c,6026
|
|
64
|
-
opencos/tools/iverilog.py,sha256=
|
|
64
|
+
opencos/tools/iverilog.py,sha256=aehXQV22U7MIaH8XuEI9ApWztsez0NaW960_Z01oZWc,6789
|
|
65
65
|
opencos/tools/modelsim_ase.py,sha256=NEzAXJtiVWkKb3N-O3PYxSnnFmrq8LNrqjxFNBwzfKI,2254
|
|
66
66
|
opencos/tools/quartus.py,sha256=gtswIhpnHjUTmw5g1BRxhjB6tofXEsx-I6IySjwyF94,32303
|
|
67
67
|
opencos/tools/questa.py,sha256=QP0JCt8rWf0-snncNP0_Pi6oRY6_Z9Hwix1IYlRdGEc,2057
|
|
68
|
-
opencos/tools/questa_common.py,sha256=
|
|
68
|
+
opencos/tools/questa_common.py,sha256=JYF4MrAcELurcA-t3Hzjb9KKtzHBEEYmXWKWAt8Gi0c,21931
|
|
69
69
|
opencos/tools/questa_fe.py,sha256=yYNlUnA2pQ8-gELLajnvJgqg6ZXb6F26YRmyvrlNFOA,2155
|
|
70
70
|
opencos/tools/questa_fse.py,sha256=CjOAn1Ik-3Hd-vyUH_WyTTJxH2yPfhNEfXbedCir7J4,2116
|
|
71
|
-
opencos/tools/riviera.py,sha256=
|
|
71
|
+
opencos/tools/riviera.py,sha256=SsBOQ-xQQeBr_jPKI50bGzFHXKQeAa7WX3Ql6AC-3wE,19535
|
|
72
72
|
opencos/tools/slang.py,sha256=MxRwu4laSbv7oa3lO-BKg4McL7KAckSA003sL-9sY3U,9682
|
|
73
73
|
opencos/tools/slang_yosys.py,sha256=z8gUcNSGDl5S6Ufxdx54WWe5v73w0UydErBKFWBR6ZI,10154
|
|
74
74
|
opencos/tools/surelog.py,sha256=QaXS1EWI2b1TqBoekpXndoHxS6t2e8SD-I2Ryi-gHGs,6666
|
|
75
75
|
opencos/tools/tabbycad_yosys.py,sha256=J4RgfuzYLiBK1U8odXiovXZhgkcDFPlbxt73SppksVA,7657
|
|
76
|
-
opencos/tools/verilator.py,sha256=
|
|
77
|
-
opencos/tools/vivado.py,sha256=
|
|
78
|
-
opencos/tools/yosys.py,sha256=
|
|
76
|
+
opencos/tools/verilator.py,sha256=uxJs5VpE6pHIR3c5bJbQbjSoymIqNOG861ix2IR_c3Y,25363
|
|
77
|
+
opencos/tools/vivado.py,sha256=BHnfJ-TqUYwdKFC1zHJ3x6xkLOgn2xdQbxySbBEWFYk,50149
|
|
78
|
+
opencos/tools/yosys.py,sha256=8r3pxNod-ntWAHrDDL0HCT9mCkZ6qcNnOtLnIpOTi9g,28807
|
|
79
79
|
opencos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
80
|
opencos/utils/dict_helpers.py,sha256=xCdfE8SE-D6hNu5dG_d46A2g6au6h1h7SFpzYmeyRtA,810
|
|
81
81
|
opencos/utils/markup_helpers.py,sha256=F_Emh2kT2gETYf7C-Jy5yJjsiHiPUtBpQzONsCka6Eo,4604
|
|
@@ -84,10 +84,10 @@ opencos/utils/str_helpers.py,sha256=ctl0Zh0h0JW7OlReeSdGxB9wODQYzmMO-9-h55rSRv0,
|
|
|
84
84
|
opencos/utils/subprocess_helpers.py,sha256=Wqqs8FKm3XIjmD9GUYM-HWVJH7TxWJJA37A07J4fQ4w,6619
|
|
85
85
|
opencos/utils/vscode_helper.py,sha256=8epyEeYfXONwiSoc5KZjUfKc8vgLryct8yckJYie88U,1398
|
|
86
86
|
opencos/utils/vsim_helper.py,sha256=-TJK4Dh8LZ4DCM8GrS9Wka4HE_WMGG_aKwTZtKBrEOE,2994
|
|
87
|
-
opencos_eda-0.3.
|
|
88
|
-
opencos_eda-0.3.
|
|
89
|
-
opencos_eda-0.3.
|
|
90
|
-
opencos_eda-0.3.
|
|
91
|
-
opencos_eda-0.3.
|
|
92
|
-
opencos_eda-0.3.
|
|
93
|
-
opencos_eda-0.3.
|
|
87
|
+
opencos_eda-0.3.15.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
|
88
|
+
opencos_eda-0.3.15.dist-info/licenses/LICENSE.spdx,sha256=8gn1610RMP6eFgT3Hm6q9VKXt0RvdTItL_oxMo72jII,189
|
|
89
|
+
opencos_eda-0.3.15.dist-info/METADATA,sha256=eMegaTVGReQYdwr58zGGkc8fmhuJywlujQ1wawgA4dA,1165
|
|
90
|
+
opencos_eda-0.3.15.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
91
|
+
opencos_eda-0.3.15.dist-info/entry_points.txt,sha256=QOlMZnQeqqwOzIaeKBcY_WlMR3idmOAEbGFh2dXlqJw,290
|
|
92
|
+
opencos_eda-0.3.15.dist-info/top_level.txt,sha256=J4JDP-LpRyJqPNeh9bSjx6yrLz2Mk0h6un6YLmtqql4,8
|
|
93
|
+
opencos_eda-0.3.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|