ciel 0.21.0.dev0__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.
- ciel/__init__.py +29 -0
- ciel/__main__.py +429 -0
- ciel/__version__.py +44 -0
- ciel/build/__init__.py +267 -0
- ciel/build/common.py +98 -0
- ciel/build/gf180mcu.py +263 -0
- ciel/build/git_multi_clone.py +220 -0
- ciel/build/ihp_sg13g2.py +148 -0
- ciel/build/sky130.py +358 -0
- ciel/click_common.py +119 -0
- ciel/common.py +256 -0
- ciel/families.py +119 -0
- ciel/github.py +184 -0
- ciel/manage.py +355 -0
- ciel/py.typed +0 -0
- ciel-0.21.0.dev0.dist-info/METADATA +168 -0
- ciel-0.21.0.dev0.dist-info/RECORD +19 -0
- ciel-0.21.0.dev0.dist-info/WHEEL +4 -0
- ciel-0.21.0.dev0.dist-info/entry_points.txt +3 -0
ciel/manage.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Copyright 2022-2023 Efabless Corporation
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import io
|
|
15
|
+
import os
|
|
16
|
+
import shutil
|
|
17
|
+
import tarfile
|
|
18
|
+
import tempfile
|
|
19
|
+
import warnings
|
|
20
|
+
from typing import Iterable, List, Optional, Union
|
|
21
|
+
|
|
22
|
+
import rich
|
|
23
|
+
import httpx
|
|
24
|
+
import rich.tree
|
|
25
|
+
import rich.progress
|
|
26
|
+
import zstandard as zstd
|
|
27
|
+
from rich.console import Console
|
|
28
|
+
|
|
29
|
+
from .build.git_multi_clone import mkdirp
|
|
30
|
+
from .github import GitHubSession
|
|
31
|
+
from .common import (
|
|
32
|
+
Version,
|
|
33
|
+
get_versions_dir,
|
|
34
|
+
get_cielo_dir,
|
|
35
|
+
)
|
|
36
|
+
from .build import build, push
|
|
37
|
+
from .families import Family
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class VersionNotFound(Exception):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def print_installed_list(
|
|
45
|
+
pdk_root: str,
|
|
46
|
+
pdk: str,
|
|
47
|
+
*,
|
|
48
|
+
console: Console,
|
|
49
|
+
installed_list: List[Version],
|
|
50
|
+
session: Optional[GitHubSession] = None,
|
|
51
|
+
):
|
|
52
|
+
if len(installed_list) == 0:
|
|
53
|
+
console.print("[red]No PDKs installed.")
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
versions = installed_list
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
all_remote_versions = Version._from_github(session)
|
|
60
|
+
remote_versions = all_remote_versions.get(pdk) or []
|
|
61
|
+
remote_version_dict = {rv.name: rv for rv in remote_versions}
|
|
62
|
+
for installed in installed_list:
|
|
63
|
+
remote_version = remote_version_dict.get(installed.name)
|
|
64
|
+
if remote_version is not None:
|
|
65
|
+
installed.commit_date = remote_version.commit_date
|
|
66
|
+
installed.upload_date = remote_version.upload_date
|
|
67
|
+
versions.sort(reverse=True)
|
|
68
|
+
except httpx.HTTPError:
|
|
69
|
+
console.print(
|
|
70
|
+
"[red]Failed to connect to GitHub. Date information may be unavailable."
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
versions_dir = get_versions_dir(pdk_root, pdk)
|
|
74
|
+
tree = rich.tree.Tree(f"In {versions_dir}:")
|
|
75
|
+
for installed in versions:
|
|
76
|
+
day: Optional[str] = None
|
|
77
|
+
if installed.commit_date is not None:
|
|
78
|
+
day = installed.commit_date.strftime("%Y.%m.%d")
|
|
79
|
+
desc = f"{installed.name}"
|
|
80
|
+
if day is not None:
|
|
81
|
+
desc += f" ({day})"
|
|
82
|
+
if installed.is_current(pdk_root):
|
|
83
|
+
tree.add(f"[green][bold]{desc} (enabled)")
|
|
84
|
+
else:
|
|
85
|
+
tree.add(desc)
|
|
86
|
+
console.print(tree)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def print_remote_list(
|
|
90
|
+
pdk_root: str,
|
|
91
|
+
pdk: str,
|
|
92
|
+
console: Console,
|
|
93
|
+
pdk_list: List[Version],
|
|
94
|
+
):
|
|
95
|
+
installed_list = Version.get_all_installed(pdk_root, pdk)
|
|
96
|
+
|
|
97
|
+
tree = rich.tree.Tree(f"Pre-built {pdk} PDK versions")
|
|
98
|
+
for remote_version in pdk_list:
|
|
99
|
+
name = remote_version.name
|
|
100
|
+
assert (
|
|
101
|
+
remote_version.commit_date is not None
|
|
102
|
+
), f"Remote version {name} has no commit date"
|
|
103
|
+
day = remote_version.commit_date.strftime("%Y.%m.%d")
|
|
104
|
+
desc = f"[green]{name} ({day})"
|
|
105
|
+
if remote_version.prerelease:
|
|
106
|
+
desc = f"[red]PRE-RELEASE {desc}"
|
|
107
|
+
if remote_version.is_current(pdk_root):
|
|
108
|
+
tree.add(f"[bold]{desc} (enabled)")
|
|
109
|
+
elif name in installed_list:
|
|
110
|
+
tree.add(f"{desc} (installed)")
|
|
111
|
+
else:
|
|
112
|
+
tree.add(desc)
|
|
113
|
+
console.print(tree)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def fetch(
|
|
117
|
+
pdk_root: str,
|
|
118
|
+
pdk: str,
|
|
119
|
+
version: str,
|
|
120
|
+
*,
|
|
121
|
+
build_if_not_found=False,
|
|
122
|
+
also_push=False,
|
|
123
|
+
build_kwargs: dict = {},
|
|
124
|
+
push_kwargs: dict = {},
|
|
125
|
+
include_libraries: Optional[Iterable[str]] = None,
|
|
126
|
+
output: Union[Console, io.TextIOWrapper] = Console(),
|
|
127
|
+
session: Optional[GitHubSession] = None,
|
|
128
|
+
) -> Version:
|
|
129
|
+
if session is None:
|
|
130
|
+
session = GitHubSession()
|
|
131
|
+
|
|
132
|
+
console = output
|
|
133
|
+
if not isinstance(console, Console):
|
|
134
|
+
console = Console(file=console)
|
|
135
|
+
|
|
136
|
+
version_object = Version(version, pdk)
|
|
137
|
+
|
|
138
|
+
version_directory = version_object.get_dir(pdk_root)
|
|
139
|
+
|
|
140
|
+
pdk_family = Family.by_name.get(pdk)
|
|
141
|
+
if pdk_family is None:
|
|
142
|
+
raise ValueError(f"Unsupported PDK family '{pdk}'.")
|
|
143
|
+
|
|
144
|
+
library_set = pdk_family.resolve_libraries(include_libraries)
|
|
145
|
+
|
|
146
|
+
variants = pdk_family.variants
|
|
147
|
+
|
|
148
|
+
common_missing = False
|
|
149
|
+
missing_libraries = set()
|
|
150
|
+
libs_tech = os.path.join(version_directory, variants[0], "libs.tech")
|
|
151
|
+
if not os.path.isdir(libs_tech):
|
|
152
|
+
common_missing = True
|
|
153
|
+
|
|
154
|
+
for library in library_set:
|
|
155
|
+
if library not in pdk_family.all_libraries:
|
|
156
|
+
raise RuntimeError(f"Unknown library {library}.")
|
|
157
|
+
found = False
|
|
158
|
+
for variant in variants:
|
|
159
|
+
lib_path = os.path.join(version_directory, variant, "libs.ref", library)
|
|
160
|
+
if os.path.isdir(lib_path):
|
|
161
|
+
found = True
|
|
162
|
+
if not found:
|
|
163
|
+
missing_libraries.add(library)
|
|
164
|
+
|
|
165
|
+
affected_paths = []
|
|
166
|
+
if len(missing_libraries) != 0 or common_missing:
|
|
167
|
+
if common_missing:
|
|
168
|
+
console.print(
|
|
169
|
+
f"Version {version} not found locally, attempting to download…"
|
|
170
|
+
)
|
|
171
|
+
affected_paths.append(version_directory)
|
|
172
|
+
else:
|
|
173
|
+
console.print(f"Libraries {missing_libraries} not found, downloading them…")
|
|
174
|
+
for variant in variants:
|
|
175
|
+
affected_paths.append(
|
|
176
|
+
os.path.join(version_directory, variant, "libs.ref", library)
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
tarball_paths = []
|
|
180
|
+
try:
|
|
181
|
+
release_link_list = version_object.get_release_links(
|
|
182
|
+
missing_libraries,
|
|
183
|
+
include_common=common_missing,
|
|
184
|
+
session=session,
|
|
185
|
+
)
|
|
186
|
+
tarball_directory = tempfile.TemporaryDirectory(suffix=".cielo")
|
|
187
|
+
for name, link in release_link_list:
|
|
188
|
+
tarball_path = os.path.join(tarball_directory.name, name)
|
|
189
|
+
tarball_paths.append(tarball_path)
|
|
190
|
+
with session.stream("get", link) as r, rich.progress.Progress(
|
|
191
|
+
console=console
|
|
192
|
+
) as p:
|
|
193
|
+
total_str: Optional[str] = r.headers.get("Content-length", None)
|
|
194
|
+
total_int: Optional[int] = None
|
|
195
|
+
if total_str is not None:
|
|
196
|
+
total_int = int(total_str)
|
|
197
|
+
task = p.add_task(
|
|
198
|
+
f"Downloading {name}…",
|
|
199
|
+
total=total_int,
|
|
200
|
+
)
|
|
201
|
+
r.raise_for_status()
|
|
202
|
+
with open(tarball_path, "wb") as f:
|
|
203
|
+
for chunk in r.iter_bytes(chunk_size=8192):
|
|
204
|
+
p.advance(task, advance=len(chunk))
|
|
205
|
+
f.write(chunk)
|
|
206
|
+
|
|
207
|
+
with console.status(f"Unpacking {name}…"):
|
|
208
|
+
stream = zstd.open(tarball_path, mode="rb")
|
|
209
|
+
with tarfile.TarFile(fileobj=stream, mode="r") as tf:
|
|
210
|
+
for file in tf:
|
|
211
|
+
if file.isdir():
|
|
212
|
+
continue
|
|
213
|
+
final_path = os.path.join(version_directory, file.name)
|
|
214
|
+
final_dir = os.path.dirname(final_path)
|
|
215
|
+
mkdirp(final_dir)
|
|
216
|
+
io = tf.extractfile(file)
|
|
217
|
+
if io is None:
|
|
218
|
+
raise IOError(
|
|
219
|
+
f"Failed to unpack file in {name}'s tarball: {file.name}."
|
|
220
|
+
)
|
|
221
|
+
with open(final_path, "wb") as f:
|
|
222
|
+
f.write(io.read())
|
|
223
|
+
except httpx.HTTPStatusError as e:
|
|
224
|
+
if e.response is not None and e.response.status_code == 404:
|
|
225
|
+
if not build_if_not_found:
|
|
226
|
+
raise RuntimeError(f"Version {version} not found remotely.")
|
|
227
|
+
console.print(
|
|
228
|
+
f"Version {version} not found remotely, attempting to build…"
|
|
229
|
+
)
|
|
230
|
+
build(
|
|
231
|
+
pdk_root=pdk_root,
|
|
232
|
+
pdk=pdk,
|
|
233
|
+
version=version,
|
|
234
|
+
**build_kwargs,
|
|
235
|
+
)
|
|
236
|
+
if also_push:
|
|
237
|
+
if push_kwargs["push_libraries"] is None:
|
|
238
|
+
push_kwargs["push_libraries"] = Family.by_name[
|
|
239
|
+
pdk
|
|
240
|
+
].default_includes.copy()
|
|
241
|
+
push(
|
|
242
|
+
pdk_root=pdk_root,
|
|
243
|
+
pdk=pdk,
|
|
244
|
+
version=version,
|
|
245
|
+
session=session,
|
|
246
|
+
**push_kwargs,
|
|
247
|
+
)
|
|
248
|
+
else:
|
|
249
|
+
if e.response is not None:
|
|
250
|
+
raise RuntimeError(
|
|
251
|
+
f"Failed to obtain {version} remotely: {e.response}."
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
raise RuntimeError(f"Failed to request {version} from server: {e}.")
|
|
255
|
+
except KeyboardInterrupt as e:
|
|
256
|
+
console.print("Interrupted.")
|
|
257
|
+
for path in affected_paths:
|
|
258
|
+
shutil.rmtree(path, ignore_errors=True)
|
|
259
|
+
raise e from None
|
|
260
|
+
except Exception as e:
|
|
261
|
+
for path in affected_paths:
|
|
262
|
+
shutil.rmtree(path, ignore_errors=True)
|
|
263
|
+
raise e from None
|
|
264
|
+
finally:
|
|
265
|
+
for path in tarball_paths:
|
|
266
|
+
try:
|
|
267
|
+
os.unlink(path)
|
|
268
|
+
except FileNotFoundError:
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
for variant in variants:
|
|
272
|
+
variant_install_path = os.path.join(version_directory, variant)
|
|
273
|
+
if not os.path.isdir(variant_install_path):
|
|
274
|
+
continue
|
|
275
|
+
variant_sources_file = os.path.join(variant_install_path, "SOURCES")
|
|
276
|
+
if not os.path.isfile(variant_sources_file):
|
|
277
|
+
with open(variant_sources_file, "w") as f:
|
|
278
|
+
print(f"{pdk_family.repo.name} {version}", file=f)
|
|
279
|
+
|
|
280
|
+
return Version(version, pdk)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def enable(
|
|
284
|
+
pdk_root: str,
|
|
285
|
+
pdk: str,
|
|
286
|
+
version: str,
|
|
287
|
+
*,
|
|
288
|
+
build_if_not_found: bool = False,
|
|
289
|
+
also_push: bool = False,
|
|
290
|
+
build_kwargs: dict = {},
|
|
291
|
+
push_kwargs: dict = {},
|
|
292
|
+
include_libraries: Optional[List[str]] = None,
|
|
293
|
+
output: Union[Console, io.TextIOWrapper] = Console(),
|
|
294
|
+
session: Optional[GitHubSession] = None,
|
|
295
|
+
) -> Version:
|
|
296
|
+
if session is None:
|
|
297
|
+
session = GitHubSession()
|
|
298
|
+
|
|
299
|
+
console = output
|
|
300
|
+
if not isinstance(console, Console):
|
|
301
|
+
console = Console(file=console)
|
|
302
|
+
|
|
303
|
+
version_object = Version(version, pdk)
|
|
304
|
+
version_directory = version_object.get_dir(pdk_root)
|
|
305
|
+
|
|
306
|
+
pdk_family = Family.by_name.get(pdk)
|
|
307
|
+
if pdk_family is None:
|
|
308
|
+
raise ValueError(f"Unsupported PDK family '{pdk}'.")
|
|
309
|
+
|
|
310
|
+
variants = pdk_family.variants
|
|
311
|
+
version_paths = [os.path.join(version_directory, variant) for variant in variants]
|
|
312
|
+
final_paths = [os.path.join(pdk_root, variant) for variant in variants]
|
|
313
|
+
|
|
314
|
+
fetch(
|
|
315
|
+
pdk_root,
|
|
316
|
+
pdk,
|
|
317
|
+
version,
|
|
318
|
+
build_if_not_found=build_if_not_found,
|
|
319
|
+
also_push=also_push,
|
|
320
|
+
build_kwargs=build_kwargs,
|
|
321
|
+
push_kwargs=push_kwargs,
|
|
322
|
+
include_libraries=include_libraries,
|
|
323
|
+
output=output,
|
|
324
|
+
session=session,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
current_file = os.path.join(get_cielo_dir(pdk_root, pdk), "current")
|
|
328
|
+
current_file_dir = os.path.dirname(current_file)
|
|
329
|
+
mkdirp(current_file_dir)
|
|
330
|
+
|
|
331
|
+
with console.status(f"Enabling version {version}…"):
|
|
332
|
+
for path in final_paths:
|
|
333
|
+
if os.path.exists(path):
|
|
334
|
+
if os.path.islink(path):
|
|
335
|
+
os.unlink(path)
|
|
336
|
+
else:
|
|
337
|
+
raise FileExistsError(
|
|
338
|
+
f"{path} exists, and not as a symlink. Remove it then try re-enabling."
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
for vpath, fpath in zip(version_paths, final_paths):
|
|
342
|
+
src = os.path.relpath(vpath, pdk_root)
|
|
343
|
+
if os.path.isdir(vpath):
|
|
344
|
+
os.symlink(src=src, dst=fpath)
|
|
345
|
+
|
|
346
|
+
with open(current_file, "w") as f:
|
|
347
|
+
f.write(version)
|
|
348
|
+
|
|
349
|
+
console.print(f"Version {version} enabled for the {pdk} PDK.")
|
|
350
|
+
return version_object
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def get(*args, **kwargs):
|
|
354
|
+
warnings.warn("get() has been deprecated: use fetch()")
|
|
355
|
+
return fetch(*args, **kwargs)
|
ciel/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ciel
|
|
3
|
+
Version: 0.21.0.dev0
|
|
4
|
+
Summary: An PDK builder/version manager for PDKs in the open_pdks format
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Author: Efabless Corporation and Contributors
|
|
7
|
+
Author-email: donn@efabless.com
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Requires-Dist: click (>=8,<9)
|
|
21
|
+
Requires-Dist: httpx (>=0.22.0,<0.29)
|
|
22
|
+
Requires-Dist: pcpp (>=1.2,<2)
|
|
23
|
+
Requires-Dist: pyyaml (>=5,<7)
|
|
24
|
+
Requires-Dist: rich (>=12,<14)
|
|
25
|
+
Requires-Dist: zstandard (>=0.19.0,<1)
|
|
26
|
+
Project-URL: Repository, https://github.com/donn/cielo
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
<h1 align="center">☁️ Cielo</h1>
|
|
30
|
+
<p align="center">
|
|
31
|
+
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"/></a>
|
|
32
|
+
<img src="https://github.com/efabless/cielo/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI Status" />
|
|
33
|
+
<a href="https://invite.skywater.tools"><img src="https://img.shields.io/badge/Community-Skywater%20PDK%20Slack-ff69b4?logo=slack" alt="Invite to the Skywater PDK Slack"/></a>
|
|
34
|
+
<a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: Black"/></a>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<p align="center">Cielo is a version manager (and builder) for builds of <a href="https://github.com/google/open-source-pdks">Google open-source PDKs</a> using <a href="https://github.com/rtimothyedwards/open_pdks">open_pdks</a>.</p>
|
|
38
|
+
|
|
39
|
+
# Requirements
|
|
40
|
+
* Python 3.8+ with PIP
|
|
41
|
+
* macOS or GNU/Linux
|
|
42
|
+
|
|
43
|
+
## macOS
|
|
44
|
+
Get [Homebrew](https://brew.sh) then:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
brew install python3
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Debian and Ubuntu
|
|
51
|
+
Debian 11+ or Ubuntu 20.04+ is required.
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
sudo apt-get update
|
|
55
|
+
sudo apt-get install python3 python3-pip xz-utils
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## RHEL and Derivatives
|
|
59
|
+
RHEL 8+ or compatible operating system required.
|
|
60
|
+
```sh
|
|
61
|
+
sudo yum install -y python3 python3-pip
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Installation and Upgrades
|
|
66
|
+
```sh
|
|
67
|
+
# To install (or upgrade)
|
|
68
|
+
python3 -m pip install --user --upgrade --no-cache-dir cielo
|
|
69
|
+
|
|
70
|
+
# To verify it works
|
|
71
|
+
cielo --version
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
# About the builds
|
|
75
|
+
In its current inception, cielo supports builds of **sky130** and **gf180mcu** PDKs using [Open_PDKs](https://github.com/efabless/open_pdks), including the following libraries:
|
|
76
|
+
|
|
77
|
+
|sky130|gf180mcu|
|
|
78
|
+
|-|-|
|
|
79
|
+
|sky130_fd_io|gf180mcu_fd_io|
|
|
80
|
+
|sky130_fd_pr|gf180mcu_fd_pr|
|
|
81
|
+
|sky130_fd_sc_hd|gf180mcu_fd_sc_mcu7t5v0|
|
|
82
|
+
|sky130_fd_sc_hvl|gf180mcu_fd_sc_mcu9t5v0|
|
|
83
|
+
|sky130 sram modules|gf180mcu_fd_ip_sram|
|
|
84
|
+
|
|
85
|
+
All builds are identified by their **open_pdks** commit hash.
|
|
86
|
+
|
|
87
|
+
# Usage
|
|
88
|
+
Cielo requires a so-called **PDK Root**. This PDK root can be anywhere on your computer, but by default it's the folder `~/.cielo` in your home directory. If you have the variable `PDK_ROOT` set, cielo will use that instead. You can also manually override both values by supplying the `--pdk-root` commandline argument.
|
|
89
|
+
|
|
90
|
+
## Listing All Available PDKs
|
|
91
|
+
To list all available pre-built PDKs hosted in this repository, you can just invoke `cielo ls-remote --pdk <PDK>`. If you omit the `--pdk` argument, `sky130` will be used as a default.
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
$ cielo ls-remote --pdk sky130
|
|
95
|
+
Pre-built sky130 PDK versions
|
|
96
|
+
├── 44a43c23c81b45b8e774ae7a84899a5a778b6b0b (2022.08.16) (enabled)
|
|
97
|
+
├── e8294524e5f67c533c5d0c3afa0bcc5b2a5fa066 (2022.07.29) (installed)
|
|
98
|
+
├── 41c0908b47130d5675ff8484255b43f66463a7d6 (2022.04.14) (installed)
|
|
99
|
+
├── 660c6bdc8715dc7b3db95a1ce85392bbf2a2b195 (2022.04.08)
|
|
100
|
+
├── 5890e791e37699239abedfd2a67e55162e25cd94 (2022.04.06)
|
|
101
|
+
├── 8fe7f760ece2bb49b1c310e60243f0558977dae5 (2022.04.06)
|
|
102
|
+
└── 7519dfb04400f224f140749cda44ee7de6f5e095 (2022.02.10)
|
|
103
|
+
|
|
104
|
+
$ cielo ls-remote --pdk gf180mcu
|
|
105
|
+
Pre-built gf180mcu PDK versions
|
|
106
|
+
└── 120b0bd69c745825a0b8b76f364043a1cd08bb6a (2022.09.22)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
It includes a commit hash, which is the `open_pdks` version used to build this particular PDK, the date that this commit was created, and whether you already installed this PDK and/or if it is the currently enabled PDK.
|
|
110
|
+
|
|
111
|
+
## Listing Installed PDKs
|
|
112
|
+
Typing `cielo ls --pdk <pdk>` in the terminal shows you your PDK Root and the PDKs you currently have installed. Again, if you omit the `--pdk` argument, `sky130` will be used as a default.
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
$ cielo ls --pdk sky130
|
|
116
|
+
/home/test/cielo/sky130/versions
|
|
117
|
+
├── 44a43c23c81b45b8e774ae7a84899a5a778b6b0b (2022.08.16) (enabled)
|
|
118
|
+
├── e8294524e5f67c533c5d0c3afa0bcc5b2a5fa066 (2022.07.29)
|
|
119
|
+
└── 41c0908b47130d5675ff8484255b43f66463a7d6 (2022.04.14)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
(If you're not connected to the Internet, the release date of the commit will not be included.)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
## Downloading and Enabling PDKs
|
|
126
|
+
You can enable a particular sky130 PDK by invoking `cielo enable --pdk <pdk> <open_pdks commit hash>`. This will automatically download that particular version of the PDK, if found, and set it as your currently used PDK.
|
|
127
|
+
|
|
128
|
+
For example, to activate a build of sky130 using open_pdks `7519dfb04400f224f140749cda44ee7de6f5e095`, you invoke `cielo enable --pdk sky130 7519dfb04400f224f140749cda44ee7de6f5e095`, as shown below:
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
$ cielo enable --pdk sky130 7519dfb04400f224f140749cda44ee7de6f5e095
|
|
132
|
+
Downloading pre-built tarball for 7519dfb04400f224f140749cda44ee7de6f5e095… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
|
|
133
|
+
Unpacking… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
|
|
134
|
+
PDK version 7519dfb04400f224f140749cda44ee7de6f5e095 enabled.
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
What's more is: if you're using a repository with a `tool_metadata.yml` file, such as [OpenLane](https://github.com/The-OpenROAD-Project/OpenLane) or [DFFRAM](https://github.com/Cloud-V/DFFRAM), you can just invoke `cielo enable --pdk sky130` without the commit hash and Cielo will automatically extract the version required by the utility. Once again, if you omit the `--pdk` argument, `sky130` will be used as a default.
|
|
138
|
+
|
|
139
|
+
## Building PDKs
|
|
140
|
+
For special cases, you may have to build the PDK yourself, which Cielo does support.
|
|
141
|
+
|
|
142
|
+
You'll need Magic installed and in PATH. You can either do that manually or, if you have [Nix](https://nixos.org), invoke `nix shell github:efabless/openlane2#magic` before building.
|
|
143
|
+
|
|
144
|
+
You can invoke `cielo build --help` for more options. Be aware, the built PDK won't automatically be enabled and you'll have to `cielo enable` the appropriate version.
|
|
145
|
+
|
|
146
|
+
# License
|
|
147
|
+
The Apache License, version 2.0. See 'License'.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
Cielo is based on [Volare](https://github.com/efabless/volare) by Efabless
|
|
151
|
+
Corporation:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
Copyright 2022-2025 Efabless Corporation
|
|
155
|
+
|
|
156
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
157
|
+
you may not use this file except in compliance with the License.
|
|
158
|
+
You may obtain a copy of the License at
|
|
159
|
+
|
|
160
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
161
|
+
|
|
162
|
+
Unless required by applicable law or agreed to in writing, software
|
|
163
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
164
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
165
|
+
See the License for the specific language governing permissions and
|
|
166
|
+
limitations under the License.
|
|
167
|
+
```
|
|
168
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
ciel/__init__.py,sha256=Ds7HveaY6MEuAefOAmZWUGZxlJbWmh0VNlI7iJdbi9U,858
|
|
2
|
+
ciel/__main__.py,sha256=2aVGdjzPJO2O1UjDEeOyWxyAw_nqjvT7BDReu24hJlE,12021
|
|
3
|
+
ciel/__version__.py,sha256=CiYOz2nsxhPOSiHi6nLpq-o6zdzLhvEVAG_58UzG5Xs,1510
|
|
4
|
+
ciel/build/__init__.py,sha256=0a8KRwBcwZRFgcsZcYYLJuUMAjMsIfDF-nGt_1LKr3s,7378
|
|
5
|
+
ciel/build/common.py,sha256=DAOaJVCyfgfBvPzhhLiYorRJoHqS4wQ5080VgGnd7Gg,3283
|
|
6
|
+
ciel/build/gf180mcu.py,sha256=J1c9EPFVJpqhibAzle_hiVYNx3gOduE3x4EUBBMWPZM,8775
|
|
7
|
+
ciel/build/git_multi_clone.py,sha256=lgjfZPN4KE9IJq4ph4xnst35hh4Rup16glhJtE8Srek,6902
|
|
8
|
+
ciel/build/ihp_sg13g2.py,sha256=zDIoSL4rKk4XUqjBUZuMFFcngc7FsjuAti7ibqj3zt4,4940
|
|
9
|
+
ciel/build/sky130.py,sha256=5scYrgKHpoTxkLmvxXEXkzfN8lVB60lI8R0iZaiT2RY,12047
|
|
10
|
+
ciel/click_common.py,sha256=YD7OYskwSWKfis7kndPTK32VgqiPmZ2QvSoZljqc6Fw,3741
|
|
11
|
+
ciel/common.py,sha256=tr-kIYvtjMpi9-spLQvlHm2r2eGJUXJFBDmFUwUpBK0,7913
|
|
12
|
+
ciel/families.py,sha256=4ZNvDUSEknlFJmyyFGE-jgd7hkXnKcA9qnH_6GyIiqk,3525
|
|
13
|
+
ciel/github.py,sha256=pFfmICJoTo188bp-3z7b2TLvKVmJC5PAd--ssC4pHSM,5111
|
|
14
|
+
ciel/manage.py,sha256=S90KZHvUBSpkeeFPq1rwK6YKo4jFcHizdeCri4I9LzM,12371
|
|
15
|
+
ciel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
ciel-0.21.0.dev0.dist-info/METADATA,sha256=ZORoGjY1EgRuYKWu5NgB62rDlhrXCe9R8DE5gkbmoZw,7700
|
|
17
|
+
ciel-0.21.0.dev0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
18
|
+
ciel-0.21.0.dev0.dist-info/entry_points.txt,sha256=XDz2ZqV8nlrFh2qQ3uqZwFl9lw-mm-FRcEyMXMtYTGY,44
|
|
19
|
+
ciel-0.21.0.dev0.dist-info/RECORD,,
|