siliconcompiler 0.33.2__py3-none-any.whl → 0.34.1__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.
- siliconcompiler/__init__.py +2 -0
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +1 -1
- siliconcompiler/apps/sc.py +1 -1
- siliconcompiler/apps/sc_issue.py +6 -4
- siliconcompiler/apps/sc_remote.py +3 -20
- siliconcompiler/apps/sc_show.py +2 -2
- siliconcompiler/apps/utils/replay.py +4 -4
- siliconcompiler/checklist.py +202 -1
- siliconcompiler/core.py +62 -293
- siliconcompiler/data/templates/email/general.j2 +3 -3
- siliconcompiler/data/templates/email/summary.j2 +1 -1
- siliconcompiler/data/templates/issue/README.txt +1 -1
- siliconcompiler/data/templates/report/sc_report.j2 +7 -7
- siliconcompiler/dependencyschema.py +392 -0
- siliconcompiler/design.py +758 -0
- siliconcompiler/flowgraph.py +79 -13
- siliconcompiler/optimizer/vizier.py +2 -2
- siliconcompiler/package/__init__.py +383 -223
- siliconcompiler/package/git.py +75 -77
- siliconcompiler/package/github.py +70 -97
- siliconcompiler/package/https.py +77 -93
- siliconcompiler/packageschema.py +260 -0
- siliconcompiler/pdk.py +5 -5
- siliconcompiler/remote/client.py +33 -15
- siliconcompiler/remote/server.py +2 -2
- siliconcompiler/report/dashboard/cli/__init__.py +6 -6
- siliconcompiler/report/dashboard/cli/board.py +4 -4
- siliconcompiler/report/dashboard/web/components/__init__.py +5 -5
- siliconcompiler/report/dashboard/web/components/flowgraph.py +4 -4
- siliconcompiler/report/dashboard/web/components/graph.py +2 -2
- siliconcompiler/report/dashboard/web/state.py +1 -1
- siliconcompiler/report/dashboard/web/utils/__init__.py +5 -5
- siliconcompiler/report/html_report.py +1 -1
- siliconcompiler/report/report.py +4 -4
- siliconcompiler/report/summary_table.py +2 -2
- siliconcompiler/report/utils.py +5 -5
- siliconcompiler/scheduler/__init__.py +3 -1382
- siliconcompiler/scheduler/docker.py +263 -0
- siliconcompiler/scheduler/run_node.py +10 -21
- siliconcompiler/scheduler/scheduler.py +311 -0
- siliconcompiler/scheduler/schedulernode.py +944 -0
- siliconcompiler/scheduler/send_messages.py +3 -3
- siliconcompiler/scheduler/slurm.py +149 -163
- siliconcompiler/scheduler/taskscheduler.py +45 -57
- siliconcompiler/schema/__init__.py +3 -3
- siliconcompiler/schema/baseschema.py +234 -11
- siliconcompiler/schema/editableschema.py +4 -0
- siliconcompiler/schema/journal.py +210 -0
- siliconcompiler/schema/namedschema.py +55 -2
- siliconcompiler/schema/parameter.py +14 -1
- siliconcompiler/schema/parametervalue.py +1 -34
- siliconcompiler/schema/schema_cfg.py +210 -349
- siliconcompiler/tool.py +412 -148
- siliconcompiler/tools/__init__.py +2 -0
- siliconcompiler/tools/builtin/_common.py +5 -5
- siliconcompiler/tools/builtin/concatenate.py +7 -7
- siliconcompiler/tools/builtin/minimum.py +4 -4
- siliconcompiler/tools/builtin/mux.py +4 -4
- siliconcompiler/tools/builtin/nop.py +4 -4
- siliconcompiler/tools/builtin/verify.py +8 -9
- siliconcompiler/tools/execute/exec_input.py +1 -1
- siliconcompiler/tools/genfasm/genfasm.py +1 -6
- siliconcompiler/tools/openroad/_apr.py +5 -1
- siliconcompiler/tools/openroad/antenna_repair.py +1 -1
- siliconcompiler/tools/openroad/macro_placement.py +1 -1
- siliconcompiler/tools/openroad/power_grid.py +1 -1
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +32 -25
- siliconcompiler/tools/opensta/timing.py +26 -3
- siliconcompiler/tools/slang/__init__.py +2 -2
- siliconcompiler/tools/surfer/__init__.py +0 -0
- siliconcompiler/tools/surfer/show.py +53 -0
- siliconcompiler/tools/surfer/surfer.py +30 -0
- siliconcompiler/tools/vpr/route.py +82 -0
- siliconcompiler/tools/vpr/vpr.py +23 -6
- siliconcompiler/tools/yosys/__init__.py +1 -1
- siliconcompiler/tools/yosys/scripts/procs.tcl +143 -0
- siliconcompiler/tools/yosys/{sc_synth_asic.tcl → scripts/sc_synth_asic.tcl} +4 -0
- siliconcompiler/tools/yosys/{sc_synth_fpga.tcl → scripts/sc_synth_fpga.tcl} +24 -77
- siliconcompiler/tools/yosys/syn_fpga.py +14 -0
- siliconcompiler/toolscripts/_tools.json +9 -13
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +0 -2
- siliconcompiler/toolscripts/ubuntu22/install-surfer.sh +33 -0
- siliconcompiler/toolscripts/ubuntu24/install-surfer.sh +33 -0
- siliconcompiler/utils/__init__.py +4 -24
- siliconcompiler/utils/flowgraph.py +29 -28
- siliconcompiler/utils/issue.py +23 -29
- siliconcompiler/utils/logging.py +37 -7
- siliconcompiler/utils/showtools.py +6 -1
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/METADATA +16 -25
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/RECORD +98 -91
- siliconcompiler/scheduler/docker_runner.py +0 -254
- siliconcompiler/schema/journalingschema.py +0 -242
- siliconcompiler/tools/yosys/procs.tcl +0 -71
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +0 -68
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +0 -68
- /siliconcompiler/tools/yosys/{sc_lec.tcl → scripts/sc_lec.tcl} +0 -0
- /siliconcompiler/tools/yosys/{sc_screenshot.tcl → scripts/sc_screenshot.tcl} +0 -0
- /siliconcompiler/tools/yosys/{syn_strategies.tcl → scripts/syn_strategies.tcl} +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.33.2.dist-info → siliconcompiler-0.34.1.dist-info}/top_level.txt +0 -0
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import docker
|
|
2
|
-
import os
|
|
3
|
-
from siliconcompiler.package import get_cache_path
|
|
4
|
-
from siliconcompiler.package import path as sc_path
|
|
5
|
-
from siliconcompiler.utils import default_email_credentials_file
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
import sys
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def get_image(chip, step, index):
|
|
11
|
-
from siliconcompiler import __version__
|
|
12
|
-
|
|
13
|
-
queue = chip.get('option', 'scheduler', 'queue', step=step, index=index)
|
|
14
|
-
if queue:
|
|
15
|
-
return queue
|
|
16
|
-
|
|
17
|
-
return os.getenv(
|
|
18
|
-
'SC_DOCKER_IMAGE',
|
|
19
|
-
f'ghcr.io/siliconcompiler/sc_runner:v{__version__}')
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def get_volumes_directories(chip, cache_dir, workdir, step, index):
|
|
23
|
-
all_dirs = set()
|
|
24
|
-
# Collect files
|
|
25
|
-
for key in chip.allkeys():
|
|
26
|
-
sc_type = chip.get(*key, field='type')
|
|
27
|
-
|
|
28
|
-
if 'file' in sc_type or 'dir' in sc_type:
|
|
29
|
-
cstep = step
|
|
30
|
-
cindex = index
|
|
31
|
-
|
|
32
|
-
if chip.get(*key, field='pernode').is_never():
|
|
33
|
-
cstep = None
|
|
34
|
-
cindex = None
|
|
35
|
-
|
|
36
|
-
files = chip.find_files(*key, step=cstep, index=cindex, missing_ok=True)
|
|
37
|
-
if files:
|
|
38
|
-
if not isinstance(files, list):
|
|
39
|
-
files = [files]
|
|
40
|
-
for path in files:
|
|
41
|
-
if path is None:
|
|
42
|
-
continue
|
|
43
|
-
if 'file' in sc_type:
|
|
44
|
-
all_dirs.add(os.path.dirname(path))
|
|
45
|
-
else:
|
|
46
|
-
all_dirs.add(path)
|
|
47
|
-
|
|
48
|
-
# Collect caches
|
|
49
|
-
for package in chip.getkeys('package', 'source'):
|
|
50
|
-
all_dirs.add(sc_path(chip, package))
|
|
51
|
-
|
|
52
|
-
all_dirs = [
|
|
53
|
-
Path(cache_dir),
|
|
54
|
-
Path(workdir),
|
|
55
|
-
Path(chip.scroot),
|
|
56
|
-
*[Path(path) for path in all_dirs]]
|
|
57
|
-
|
|
58
|
-
pruned_dirs = all_dirs.copy()
|
|
59
|
-
for base_path in all_dirs:
|
|
60
|
-
if base_path not in pruned_dirs:
|
|
61
|
-
continue
|
|
62
|
-
|
|
63
|
-
new_pruned_dirs = [base_path]
|
|
64
|
-
for check_path in pruned_dirs:
|
|
65
|
-
if base_path == check_path:
|
|
66
|
-
continue
|
|
67
|
-
|
|
68
|
-
if base_path not in check_path.parents:
|
|
69
|
-
new_pruned_dirs.append(check_path)
|
|
70
|
-
pruned_dirs = new_pruned_dirs
|
|
71
|
-
|
|
72
|
-
pruned_dirs = set(pruned_dirs)
|
|
73
|
-
|
|
74
|
-
builddir = chip.find_files('option', 'builddir')
|
|
75
|
-
|
|
76
|
-
rw_volumes = set()
|
|
77
|
-
|
|
78
|
-
for path in pruned_dirs:
|
|
79
|
-
for rw_allow in (Path(builddir), Path(workdir), Path(cache_dir)):
|
|
80
|
-
if path == rw_allow or path in rw_allow.parents:
|
|
81
|
-
rw_volumes.add(path)
|
|
82
|
-
|
|
83
|
-
ro_volumes = pruned_dirs.difference(rw_volumes)
|
|
84
|
-
|
|
85
|
-
return rw_volumes, ro_volumes
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def init(chip):
|
|
89
|
-
if sys.platform == 'win32':
|
|
90
|
-
# this avoids the issue of different file system types
|
|
91
|
-
chip.logger.error('Setting copy field to true for docker run on Windows')
|
|
92
|
-
for key in chip.allkeys():
|
|
93
|
-
if key[0] == 'history':
|
|
94
|
-
continue
|
|
95
|
-
sc_type = chip.get(*key, field='type')
|
|
96
|
-
if 'dir' in sc_type or 'file' in sc_type:
|
|
97
|
-
chip.set(*key, True, field='copy')
|
|
98
|
-
chip.collect()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def run(chip, step, index, replay):
|
|
102
|
-
# Import here to avoid circular import
|
|
103
|
-
from siliconcompiler.scheduler import _haltstep
|
|
104
|
-
|
|
105
|
-
try:
|
|
106
|
-
client = docker.from_env()
|
|
107
|
-
client.version()
|
|
108
|
-
except (docker.errors.DockerException, docker.errors.APIError) as e:
|
|
109
|
-
chip.logger.error(f'Unable to connect to docker: {e}')
|
|
110
|
-
_haltstep(chip, chip.get('option', 'flow'), step, index)
|
|
111
|
-
|
|
112
|
-
is_windows = sys.platform == 'win32'
|
|
113
|
-
|
|
114
|
-
workdir = chip.getworkdir()
|
|
115
|
-
start_cwd = os.getcwd()
|
|
116
|
-
|
|
117
|
-
# Remove handlers from logger
|
|
118
|
-
for handler in chip.logger.handlers.copy():
|
|
119
|
-
chip.logger.removeHandler(handler)
|
|
120
|
-
|
|
121
|
-
# Reinit logger
|
|
122
|
-
chip._init_logger(step=step, index=index, in_run=True)
|
|
123
|
-
|
|
124
|
-
# Change working directory since the run may delete this folder
|
|
125
|
-
os.chdir(workdir)
|
|
126
|
-
|
|
127
|
-
image_name = get_image(chip, step, index)
|
|
128
|
-
|
|
129
|
-
# Pull image if needed
|
|
130
|
-
try:
|
|
131
|
-
image = client.images.get(image_name)
|
|
132
|
-
except docker.errors.ImageNotFound:
|
|
133
|
-
# Needs a lock to avoid downloading a bunch in parallel
|
|
134
|
-
image_repo, image_tag = image_name.split(':')
|
|
135
|
-
chip.logger.info(f'Pulling docker image {image_name}')
|
|
136
|
-
try:
|
|
137
|
-
image = client.images.pull(image_repo, tag=image_tag)
|
|
138
|
-
except docker.errors.APIError as e:
|
|
139
|
-
chip.logger.error(f'Unable to pull image: {e}')
|
|
140
|
-
image_src = image_repo.split('/')[0]
|
|
141
|
-
chip.logger.error(f" if you are logged into {image_src} with expired credentials, "
|
|
142
|
-
f"please use 'docker logout {image_src}'")
|
|
143
|
-
_haltstep(chip, chip.get('option', 'flow'), step, index)
|
|
144
|
-
|
|
145
|
-
email_file = default_email_credentials_file()
|
|
146
|
-
if is_windows:
|
|
147
|
-
# Hack to get around manifest merging
|
|
148
|
-
chip.set('option', 'cachedir', None)
|
|
149
|
-
cache_dir = '/sc_cache'
|
|
150
|
-
cwd = '/sc_docker'
|
|
151
|
-
builddir = f'{cwd}/build'
|
|
152
|
-
|
|
153
|
-
local_cfg = os.path.join(start_cwd, 'sc_docker.json')
|
|
154
|
-
job = chip.get('option', 'jobname')
|
|
155
|
-
cfg = f'{builddir}/{chip.design}/{job}/{step}/{index}/sc_docker.json'
|
|
156
|
-
|
|
157
|
-
user = None
|
|
158
|
-
|
|
159
|
-
volumes = [
|
|
160
|
-
f"{chip.cwd}:{cwd}:rw",
|
|
161
|
-
f"{get_cache_path(chip)}:{cache_dir}:rw"
|
|
162
|
-
]
|
|
163
|
-
chip.logger.debug(f'Volumes: {volumes}')
|
|
164
|
-
|
|
165
|
-
env = {}
|
|
166
|
-
|
|
167
|
-
if os.path.exists(email_file):
|
|
168
|
-
env["HOME"] = "/sc_home"
|
|
169
|
-
|
|
170
|
-
volumes.append(f'{os.path.dirname(email_file)}:/sc_home/.sc:ro')
|
|
171
|
-
else:
|
|
172
|
-
cache_dir = get_cache_path(chip)
|
|
173
|
-
cwd = chip.cwd
|
|
174
|
-
builddir = chip.find_files('option', 'builddir')
|
|
175
|
-
|
|
176
|
-
local_cfg = os.path.abspath('sc_docker.json')
|
|
177
|
-
cfg = local_cfg
|
|
178
|
-
|
|
179
|
-
user = os.getuid()
|
|
180
|
-
|
|
181
|
-
rw_volumes, ro_volumes = get_volumes_directories(chip, cache_dir, workdir, step, index)
|
|
182
|
-
volumes = [
|
|
183
|
-
*[
|
|
184
|
-
f'{path}:{path}:rw' for path in rw_volumes
|
|
185
|
-
],
|
|
186
|
-
*[
|
|
187
|
-
f'{path}:{path}:ro' for path in ro_volumes
|
|
188
|
-
]
|
|
189
|
-
]
|
|
190
|
-
chip.logger.debug(f'Read write volumes: {rw_volumes}')
|
|
191
|
-
chip.logger.debug(f'Read only volumes: {ro_volumes}')
|
|
192
|
-
|
|
193
|
-
env = {}
|
|
194
|
-
if os.path.exists(email_file):
|
|
195
|
-
env["HOME"] = "/sc_home"
|
|
196
|
-
|
|
197
|
-
volumes.append(f'{os.path.dirname(email_file)}:/sc_home/.sc:ro')
|
|
198
|
-
|
|
199
|
-
container = None
|
|
200
|
-
try:
|
|
201
|
-
container = client.containers.run(
|
|
202
|
-
image.id,
|
|
203
|
-
volumes=volumes,
|
|
204
|
-
labels=[
|
|
205
|
-
"siliconcompiler",
|
|
206
|
-
f"sc_node:{chip.design}:{step}{index}"
|
|
207
|
-
],
|
|
208
|
-
user=user,
|
|
209
|
-
detach=True,
|
|
210
|
-
tty=True,
|
|
211
|
-
auto_remove=True,
|
|
212
|
-
environment=env)
|
|
213
|
-
|
|
214
|
-
# Write manifest to make it available to the docker runner
|
|
215
|
-
chip.write_manifest(local_cfg)
|
|
216
|
-
|
|
217
|
-
cachemap = []
|
|
218
|
-
for package in chip.getkeys('package', 'source'):
|
|
219
|
-
cachemap.append(f'{package}:{sc_path(chip, package)}')
|
|
220
|
-
|
|
221
|
-
chip.logger.info(f'Running in docker container: {container.name} ({container.short_id})')
|
|
222
|
-
args = [
|
|
223
|
-
'-cfg', cfg,
|
|
224
|
-
'-cwd', cwd,
|
|
225
|
-
'-builddir', builddir,
|
|
226
|
-
'-cachedir', cache_dir,
|
|
227
|
-
'-step', step,
|
|
228
|
-
'-index', index,
|
|
229
|
-
'-unset_scheduler'
|
|
230
|
-
]
|
|
231
|
-
if not is_windows and cachemap:
|
|
232
|
-
args.append('-cachemap')
|
|
233
|
-
args.append(' '.join(cachemap))
|
|
234
|
-
cmd = f'python3 -m siliconcompiler.scheduler.run_node {" ".join(args)}'
|
|
235
|
-
exec_handle = client.api.exec_create(container.name, cmd)
|
|
236
|
-
stream = client.api.exec_start(exec_handle, stream=True)
|
|
237
|
-
|
|
238
|
-
# Print the log
|
|
239
|
-
for chunk in stream:
|
|
240
|
-
for line in chunk.decode().splitlines():
|
|
241
|
-
print(line)
|
|
242
|
-
|
|
243
|
-
if client.api.exec_inspect(exec_handle['Id']).get('ExitCode') != 0:
|
|
244
|
-
_haltstep(chip, chip.get('option', 'flow'), step, index, log=False)
|
|
245
|
-
finally:
|
|
246
|
-
# Ensure we clean up containers
|
|
247
|
-
if container:
|
|
248
|
-
try:
|
|
249
|
-
container.stop()
|
|
250
|
-
except docker.errors.APIError:
|
|
251
|
-
chip.logger.error('Failed to stop docker container')
|
|
252
|
-
|
|
253
|
-
# Restore working directory
|
|
254
|
-
os.chdir(start_cwd)
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
import types
|
|
3
|
-
|
|
4
|
-
from .baseschema import BaseSchema
|
|
5
|
-
from .baseschema import json
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class JournalingSchema(BaseSchema):
|
|
9
|
-
"""
|
|
10
|
-
This class provides the ability to record the schema transactions:
|
|
11
|
-
:meth:`set`, :meth:`add`, :meth:`remove`, and :meth:`unset`.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
schema (:class:`BaseSchema`): schema to track
|
|
15
|
-
keyprefix (list of str): keypath to prefix on to recorded path
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, schema, keyprefix=None):
|
|
19
|
-
if not isinstance(schema, BaseSchema):
|
|
20
|
-
raise TypeError(f"schema must be of BaseSchema type, not: {type(schema)}")
|
|
21
|
-
if isinstance(schema, JournalingSchema):
|
|
22
|
-
raise TypeError("schema must be of cannot be a JournalingSchema")
|
|
23
|
-
|
|
24
|
-
self.__schema = schema
|
|
25
|
-
|
|
26
|
-
journal_attrs = dir(self)
|
|
27
|
-
|
|
28
|
-
# Transfer access to internal schema
|
|
29
|
-
for param, value in self.__schema.__dict__.items():
|
|
30
|
-
setattr(self, param, value)
|
|
31
|
-
for param in dir(type(self.__schema)):
|
|
32
|
-
if param in journal_attrs:
|
|
33
|
-
continue
|
|
34
|
-
method = getattr(type(self.__schema), param)
|
|
35
|
-
if callable(method):
|
|
36
|
-
setattr(self, param, types.MethodType(method, self))
|
|
37
|
-
|
|
38
|
-
if not keyprefix:
|
|
39
|
-
self.__keyprefix = tuple()
|
|
40
|
-
else:
|
|
41
|
-
self.__keyprefix = tuple(keyprefix)
|
|
42
|
-
|
|
43
|
-
self.__record_types = set()
|
|
44
|
-
self.stop_journal()
|
|
45
|
-
|
|
46
|
-
self.__parent = self
|
|
47
|
-
|
|
48
|
-
@classmethod
|
|
49
|
-
def from_manifest(cls, filepath=None, cfg=None):
|
|
50
|
-
raise RuntimeError("Journal cannot be generated from manifest")
|
|
51
|
-
|
|
52
|
-
def get(self, *keypath, field='value', step=None, index=None):
|
|
53
|
-
get_ret = super().get(*keypath, field=field, step=step, index=index)
|
|
54
|
-
self.__record_journal("get", keypath, field=field, step=step, index=index)
|
|
55
|
-
if field == 'schema':
|
|
56
|
-
child = JournalingSchema(get_ret, keyprefix=[*self.__keyprefix, *keypath])
|
|
57
|
-
child.__parent = self.__parent
|
|
58
|
-
return child
|
|
59
|
-
|
|
60
|
-
return get_ret
|
|
61
|
-
|
|
62
|
-
def set(self, *args, field='value', clobber=True, step=None, index=None):
|
|
63
|
-
ret = super().set(*args, field=field, clobber=clobber, step=step, index=index)
|
|
64
|
-
if ret:
|
|
65
|
-
*keypath, value = args
|
|
66
|
-
self.__record_journal("set", keypath, value=value, field=field, step=step, index=index)
|
|
67
|
-
return ret
|
|
68
|
-
|
|
69
|
-
def add(self, *args, field='value', step=None, index=None):
|
|
70
|
-
ret = super().add(*args, field=field, step=step, index=index)
|
|
71
|
-
if ret:
|
|
72
|
-
*keypath, value = args
|
|
73
|
-
self.__record_journal("add", keypath, value=value, field=field, step=step, index=index)
|
|
74
|
-
return ret
|
|
75
|
-
|
|
76
|
-
def remove(self, *keypath):
|
|
77
|
-
self.__record_journal("remove", keypath)
|
|
78
|
-
return super().remove(*keypath)
|
|
79
|
-
|
|
80
|
-
def unset(self, *keypath, step=None, index=None):
|
|
81
|
-
self.__record_journal("unset", keypath, step=step, index=index)
|
|
82
|
-
return super().unset(*keypath, step=step, index=index)
|
|
83
|
-
|
|
84
|
-
def _from_dict(self, manifest, keypath, version=None):
|
|
85
|
-
if "__journal__" in manifest:
|
|
86
|
-
self.__journal = manifest["__journal__"]
|
|
87
|
-
del manifest["__journal__"]
|
|
88
|
-
|
|
89
|
-
self.__schema._from_dict(manifest, keypath, version=version)
|
|
90
|
-
|
|
91
|
-
def getdict(self, *keypath, include_default=True):
|
|
92
|
-
manifest = super().getdict(*keypath, include_default=include_default)
|
|
93
|
-
|
|
94
|
-
if self.__journal:
|
|
95
|
-
manifest["__journal__"] = self.get_journal()
|
|
96
|
-
|
|
97
|
-
return manifest
|
|
98
|
-
|
|
99
|
-
def get_journal(self):
|
|
100
|
-
"""
|
|
101
|
-
Returns a copy of the current journal
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
return copy.deepcopy(self.__journal)
|
|
105
|
-
|
|
106
|
-
def is_journaling(self):
|
|
107
|
-
"""
|
|
108
|
-
Returns true if the schema is currently setup for journaling
|
|
109
|
-
"""
|
|
110
|
-
return self.__journal is not None
|
|
111
|
-
|
|
112
|
-
def get_journaling_types(self):
|
|
113
|
-
"""
|
|
114
|
-
Returns the current schema accesses that are being recorded
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
return self.__record_types.copy()
|
|
118
|
-
|
|
119
|
-
def add_journaling_type(self, value):
|
|
120
|
-
"""
|
|
121
|
-
Adds a new access type to the journal record.
|
|
122
|
-
|
|
123
|
-
Args:
|
|
124
|
-
value (str): access type
|
|
125
|
-
"""
|
|
126
|
-
|
|
127
|
-
if value not in ("set", "add", "remove", "unset", "get"):
|
|
128
|
-
raise ValueError(f"{value} is not a valid type")
|
|
129
|
-
|
|
130
|
-
return self.__record_types.add(value)
|
|
131
|
-
|
|
132
|
-
def remove_journaling_type(self, value):
|
|
133
|
-
"""
|
|
134
|
-
Removes a new access type to the journal record.
|
|
135
|
-
|
|
136
|
-
Args:
|
|
137
|
-
value (str): access type
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
try:
|
|
141
|
-
self.__record_types.remove(value)
|
|
142
|
-
except KeyError:
|
|
143
|
-
pass
|
|
144
|
-
|
|
145
|
-
def get_base_schema(self):
|
|
146
|
-
"""
|
|
147
|
-
Returns the base schema
|
|
148
|
-
"""
|
|
149
|
-
|
|
150
|
-
return self.__schema
|
|
151
|
-
|
|
152
|
-
def __record_journal(self, record_type, key, value=None, field=None, step=None, index=None):
|
|
153
|
-
'''
|
|
154
|
-
Record the schema transaction
|
|
155
|
-
'''
|
|
156
|
-
|
|
157
|
-
if self.__parent.__journal is None:
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
if record_type not in self.__parent.__record_types:
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
self.__parent.__journal.append({
|
|
164
|
-
"type": record_type,
|
|
165
|
-
"key": tuple([*self.__keyprefix, *key]),
|
|
166
|
-
"value": value,
|
|
167
|
-
"field": field,
|
|
168
|
-
"step": step,
|
|
169
|
-
"index": index
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
def start_journal(self):
|
|
173
|
-
'''
|
|
174
|
-
Start journaling the schema transactions
|
|
175
|
-
'''
|
|
176
|
-
self.__journal = []
|
|
177
|
-
self.add_journaling_type("set")
|
|
178
|
-
self.add_journaling_type("add")
|
|
179
|
-
self.add_journaling_type("remove")
|
|
180
|
-
self.add_journaling_type("unset")
|
|
181
|
-
|
|
182
|
-
def stop_journal(self):
|
|
183
|
-
'''
|
|
184
|
-
Stop journaling the schema transactions
|
|
185
|
-
'''
|
|
186
|
-
self.__journal = None
|
|
187
|
-
self.__record_types.clear()
|
|
188
|
-
|
|
189
|
-
def read_journal(self, filename):
|
|
190
|
-
'''
|
|
191
|
-
Reads a manifest and replays the journal
|
|
192
|
-
'''
|
|
193
|
-
|
|
194
|
-
with open(filename) as f:
|
|
195
|
-
data = json.loads(f.read())
|
|
196
|
-
|
|
197
|
-
self.import_journal(cfg=data)
|
|
198
|
-
|
|
199
|
-
def import_journal(self, schema=None, cfg=None):
|
|
200
|
-
'''
|
|
201
|
-
Import the journaled transactions from a different schema.
|
|
202
|
-
Only one argument is supported at a time.
|
|
203
|
-
|
|
204
|
-
Args:
|
|
205
|
-
schema (:class:`JournalingSchema`): schema to replay transactions from
|
|
206
|
-
cfg (dict): dictionary to replay transactions from
|
|
207
|
-
'''
|
|
208
|
-
|
|
209
|
-
if schema and cfg:
|
|
210
|
-
raise ValueError("only one argument is supported")
|
|
211
|
-
|
|
212
|
-
journal = []
|
|
213
|
-
if schema:
|
|
214
|
-
if isinstance(schema, JournalingSchema):
|
|
215
|
-
journal = schema.__journal
|
|
216
|
-
else:
|
|
217
|
-
raise TypeError(f"schema must be a JournalingSchema, not {type(schema)}")
|
|
218
|
-
elif cfg and "__journal__" in cfg:
|
|
219
|
-
journal = cfg["__journal__"]
|
|
220
|
-
|
|
221
|
-
if journal is None:
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
for action in journal:
|
|
225
|
-
record_type = action['type']
|
|
226
|
-
keypath = action['key']
|
|
227
|
-
value = action['value']
|
|
228
|
-
field = action['field']
|
|
229
|
-
step = action['step']
|
|
230
|
-
index = action['index']
|
|
231
|
-
if record_type == 'set':
|
|
232
|
-
self.set(*keypath, value, field=field, step=step, index=index)
|
|
233
|
-
elif record_type == 'add':
|
|
234
|
-
self.add(*keypath, value, field=field, step=step, index=index)
|
|
235
|
-
elif record_type == 'unset':
|
|
236
|
-
self.unset(*keypath, step=step, index=index)
|
|
237
|
-
elif record_type == 'remove':
|
|
238
|
-
self.remove(*keypath)
|
|
239
|
-
elif record_type == 'get':
|
|
240
|
-
continue
|
|
241
|
-
else:
|
|
242
|
-
raise ValueError(f'Unknown record type {record_type}')
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# This file contains a set of procedures that are shared
|
|
2
|
-
# between syn_asic.tcl and syn_fpga.tcl
|
|
3
|
-
|
|
4
|
-
proc post_techmap { { opt_args "" } } {
|
|
5
|
-
# perform techmap in case previous techmaps introduced constructs
|
|
6
|
-
# that need techmapping
|
|
7
|
-
yosys techmap
|
|
8
|
-
# Quick optimization
|
|
9
|
-
yosys opt {*}$opt_args -purge
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
proc sc_map_memory { lib_file techmap_file do_rom } {
|
|
13
|
-
set design_mod 0
|
|
14
|
-
|
|
15
|
-
if { $lib_file != "" } {
|
|
16
|
-
yosys memory_libmap -lib $lib_file
|
|
17
|
-
set design_mod 1
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if { $do_rom } {
|
|
21
|
-
yosys memory_map -rom-only
|
|
22
|
-
set design_mod 1
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if { $techmap_file != "" } {
|
|
26
|
-
yosys techmap -map $techmap_file
|
|
27
|
-
set design_mod 1
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return $design_mod
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
proc sc_apply_params { } {
|
|
34
|
-
global sc_design
|
|
35
|
-
|
|
36
|
-
yosys chparam -list $sc_design
|
|
37
|
-
if { [sc_cfg_exists option param] } {
|
|
38
|
-
yosys echo off
|
|
39
|
-
set module_params [yosys tee -q -s result.string chparam -list $sc_design]
|
|
40
|
-
yosys echo on
|
|
41
|
-
|
|
42
|
-
dict for {key value} [sc_cfg_get option param] {
|
|
43
|
-
if { ![string is integer $value] } {
|
|
44
|
-
set value [concat \"$value\"]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if { [string first $key $module_params] != -1 } {
|
|
48
|
-
yosys chparam -set $key $value $sc_design
|
|
49
|
-
} else {
|
|
50
|
-
puts "Warning: $key is not a defined parameter in $sc_design"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
proc sc_get_scratchpad { name } {
|
|
57
|
-
yosys echo off
|
|
58
|
-
set value [yosys tee -q -s result.string scratchpad -get $name]
|
|
59
|
-
yosys echo on
|
|
60
|
-
|
|
61
|
-
return $value
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
proc sc_load_plugin { name } {
|
|
65
|
-
catch { yosys tee -q -s sc.load.test plugin -i $name }
|
|
66
|
-
set load_test [sc_get_scratchpad sc.load.test]
|
|
67
|
-
if { [string first "ERROR" $load_test] == -1 } {
|
|
68
|
-
return 1
|
|
69
|
-
}
|
|
70
|
-
return 0
|
|
71
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -ex
|
|
4
|
-
|
|
5
|
-
# Get directory of script
|
|
6
|
-
src_path=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)/..
|
|
7
|
-
|
|
8
|
-
USE_SUDO_INSTALL="${USE_SUDO_INSTALL:-yes}"
|
|
9
|
-
if [ "${USE_SUDO_INSTALL:-yes}" = "yes" ]; then
|
|
10
|
-
SUDO_INSTALL=sudo
|
|
11
|
-
else
|
|
12
|
-
SUDO_INSTALL=""
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
sudo yum install -y git
|
|
16
|
-
|
|
17
|
-
mkdir -p deps
|
|
18
|
-
cd deps
|
|
19
|
-
|
|
20
|
-
git clone $(python3 ${src_path}/_tools.py --tool yosys-parmys --field git-url) yosys-parmys
|
|
21
|
-
cd yosys-parmys
|
|
22
|
-
git checkout $(python3 ${src_path}/_tools.py --tool yosys-parmys --field git-commit)
|
|
23
|
-
git submodule update --init --recursive
|
|
24
|
-
|
|
25
|
-
# apply patch
|
|
26
|
-
cat > build_patch <<EOF
|
|
27
|
-
diff --git a/parmys/parmys-plugin/Makefile b/parmys/parmys-plugin/Makefile
|
|
28
|
-
index dbb3eb11e..cb85631bc 100644
|
|
29
|
-
--- a/parmys/parmys-plugin/Makefile
|
|
30
|
-
+++ b/parmys/parmys-plugin/Makefile
|
|
31
|
-
@@ -49,7 +49,7 @@ VTR_INSTALL_DIR ?= /usr/local
|
|
32
|
-
|
|
33
|
-
include ../Makefile_plugin.common
|
|
34
|
-
|
|
35
|
-
-CXXFLAGS += -std=c++14 -Wall -W -Wextra \\
|
|
36
|
-
+CXXFLAGS += -std=c++17 -Wall -W -Wextra \\
|
|
37
|
-
-Wno-deprecated-declarations \\
|
|
38
|
-
-Wno-unused-parameter \\
|
|
39
|
-
-I. \\
|
|
40
|
-
diff --git a/parmys/parmys-plugin/parmys_update.cc b/parmys/parmys-plugin/parmys_update.cc
|
|
41
|
-
index ef55213c5..4e4d6dd15 100644
|
|
42
|
-
--- a/parmys/parmys-plugin/parmys_update.cc
|
|
43
|
-
+++ b/parmys/parmys-plugin/parmys_update.cc
|
|
44
|
-
@@ -506,9 +506,9 @@ void define_logical_function_yosys(nnode_t *node, Module *module)
|
|
45
|
-
lutptr = &cell->parameters.at(ID::LUT);
|
|
46
|
-
for (int i = 0; i < (1 << node->num_input_pins); i++) {
|
|
47
|
-
if (i == 3 || i == 5 || i == 6 || i == 7) //"011 1\n101 1\n110 1\n111 1\n"
|
|
48
|
-
- lutptr->bits.at(i) = RTLIL::State::S1;
|
|
49
|
-
+ lutptr->bits().at(i) = RTLIL::State::S1;
|
|
50
|
-
else
|
|
51
|
-
- lutptr->bits.at(i) = RTLIL::State::S0;
|
|
52
|
-
+ lutptr->bits().at(i) = RTLIL::State::S0;
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
cell->parameters[ID::A_WIDTH] = RTLIL::Const(int(node->num_input_pins));
|
|
56
|
-
EOF
|
|
57
|
-
|
|
58
|
-
git apply build_patch
|
|
59
|
-
|
|
60
|
-
export VTR_INSTALL_DIR=$(dirname $(which vpr))/..
|
|
61
|
-
YOSYS_PLUGIN=$(yosys-config --datdir)/plugins/
|
|
62
|
-
|
|
63
|
-
cd parmys
|
|
64
|
-
|
|
65
|
-
make -j$(nproc)
|
|
66
|
-
$SUDO_INSTALL mkdir -p $YOSYS_PLUGIN
|
|
67
|
-
$SUDO_INSTALL cp parmys-plugin/build/parmys.so $YOSYS_PLUGIN
|
|
68
|
-
cd -
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -ex
|
|
4
|
-
|
|
5
|
-
# Get directory of script
|
|
6
|
-
src_path=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)/..
|
|
7
|
-
|
|
8
|
-
USE_SUDO_INSTALL="${USE_SUDO_INSTALL:-yes}"
|
|
9
|
-
if [ "${USE_SUDO_INSTALL:-yes}" = "yes" ]; then
|
|
10
|
-
SUDO_INSTALL=sudo
|
|
11
|
-
else
|
|
12
|
-
SUDO_INSTALL=""
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
sudo apt-get install -y git
|
|
16
|
-
|
|
17
|
-
mkdir -p deps
|
|
18
|
-
cd deps
|
|
19
|
-
|
|
20
|
-
git clone $(python3 ${src_path}/_tools.py --tool yosys-parmys --field git-url) yosys-parmys
|
|
21
|
-
cd yosys-parmys
|
|
22
|
-
git checkout $(python3 ${src_path}/_tools.py --tool yosys-parmys --field git-commit)
|
|
23
|
-
git submodule update --init --recursive
|
|
24
|
-
|
|
25
|
-
# apply patch
|
|
26
|
-
cat > build_patch <<EOF
|
|
27
|
-
diff --git a/parmys/parmys-plugin/Makefile b/parmys/parmys-plugin/Makefile
|
|
28
|
-
index dbb3eb11e..cb85631bc 100644
|
|
29
|
-
--- a/parmys/parmys-plugin/Makefile
|
|
30
|
-
+++ b/parmys/parmys-plugin/Makefile
|
|
31
|
-
@@ -49,7 +49,7 @@ VTR_INSTALL_DIR ?= /usr/local
|
|
32
|
-
|
|
33
|
-
include ../Makefile_plugin.common
|
|
34
|
-
|
|
35
|
-
-CXXFLAGS += -std=c++14 -Wall -W -Wextra \\
|
|
36
|
-
+CXXFLAGS += -std=c++17 -Wall -W -Wextra \\
|
|
37
|
-
-Wno-deprecated-declarations \\
|
|
38
|
-
-Wno-unused-parameter \\
|
|
39
|
-
-I. \\
|
|
40
|
-
diff --git a/parmys/parmys-plugin/parmys_update.cc b/parmys/parmys-plugin/parmys_update.cc
|
|
41
|
-
index ef55213c5..4e4d6dd15 100644
|
|
42
|
-
--- a/parmys/parmys-plugin/parmys_update.cc
|
|
43
|
-
+++ b/parmys/parmys-plugin/parmys_update.cc
|
|
44
|
-
@@ -506,9 +506,9 @@ void define_logical_function_yosys(nnode_t *node, Module *module)
|
|
45
|
-
lutptr = &cell->parameters.at(ID::LUT);
|
|
46
|
-
for (int i = 0; i < (1 << node->num_input_pins); i++) {
|
|
47
|
-
if (i == 3 || i == 5 || i == 6 || i == 7) //"011 1\n101 1\n110 1\n111 1\n"
|
|
48
|
-
- lutptr->bits.at(i) = RTLIL::State::S1;
|
|
49
|
-
+ lutptr->bits().at(i) = RTLIL::State::S1;
|
|
50
|
-
else
|
|
51
|
-
- lutptr->bits.at(i) = RTLIL::State::S0;
|
|
52
|
-
+ lutptr->bits().at(i) = RTLIL::State::S0;
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
cell->parameters[ID::A_WIDTH] = RTLIL::Const(int(node->num_input_pins));
|
|
56
|
-
EOF
|
|
57
|
-
|
|
58
|
-
git apply build_patch
|
|
59
|
-
|
|
60
|
-
export VTR_INSTALL_DIR=$(dirname $(which vpr))/..
|
|
61
|
-
YOSYS_PLUGIN=$(yosys-config --datdir)/plugins/
|
|
62
|
-
|
|
63
|
-
cd parmys
|
|
64
|
-
|
|
65
|
-
make -j$(nproc)
|
|
66
|
-
$SUDO_INSTALL mkdir -p $YOSYS_PLUGIN
|
|
67
|
-
$SUDO_INSTALL cp parmys-plugin/build/parmys.so $YOSYS_PLUGIN
|
|
68
|
-
cd -
|