siliconcompiler 0.35.0__py3-none-any.whl → 0.35.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/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +3 -2
- siliconcompiler/apps/sc_dashboard.py +3 -1
- siliconcompiler/apps/sc_install.py +149 -37
- siliconcompiler/apps/smake.py +9 -3
- siliconcompiler/checklist.py +3 -3
- siliconcompiler/data/demo_fpga/z1000_yosys_config.json +24 -0
- siliconcompiler/design.py +51 -45
- siliconcompiler/flowgraph.py +2 -2
- siliconcompiler/library.py +23 -12
- siliconcompiler/package/__init__.py +77 -49
- siliconcompiler/package/git.py +11 -6
- siliconcompiler/package/github.py +11 -6
- siliconcompiler/package/https.py +6 -4
- siliconcompiler/pdk.py +23 -16
- siliconcompiler/scheduler/scheduler.py +30 -22
- siliconcompiler/scheduler/schedulernode.py +60 -50
- siliconcompiler/scheduler/taskscheduler.py +52 -32
- siliconcompiler/schema/baseschema.py +88 -69
- siliconcompiler/schema/docs/schemagen.py +4 -3
- siliconcompiler/schema/editableschema.py +5 -5
- siliconcompiler/schema/journal.py +19 -13
- siliconcompiler/schema/namedschema.py +16 -10
- siliconcompiler/schema/parameter.py +64 -37
- siliconcompiler/schema/parametervalue.py +126 -80
- siliconcompiler/schema/safeschema.py +16 -7
- siliconcompiler/schema/utils.py +3 -1
- siliconcompiler/schema_support/cmdlineschema.py +9 -9
- siliconcompiler/schema_support/dependencyschema.py +12 -7
- siliconcompiler/schema_support/filesetschema.py +15 -10
- siliconcompiler/schema_support/metric.py +29 -17
- siliconcompiler/schema_support/packageschema.py +2 -2
- siliconcompiler/schema_support/pathschema.py +30 -18
- siliconcompiler/schema_support/record.py +30 -23
- siliconcompiler/tool.py +265 -210
- siliconcompiler/tools/opensta/timing.py +13 -0
- siliconcompiler/tools/yosys/syn_fpga.py +3 -2
- siliconcompiler/toolscripts/_tools.json +3 -3
- siliconcompiler/utils/__init__.py +23 -16
- siliconcompiler/utils/curation.py +11 -5
- siliconcompiler/utils/multiprocessing.py +16 -14
- siliconcompiler/utils/paths.py +24 -12
- siliconcompiler/utils/units.py +16 -12
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/METADATA +3 -4
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/RECORD +49 -48
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/entry_points.txt +4 -3
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/licenses/LICENSE +0 -0
- {siliconcompiler-0.35.0.dist-info → siliconcompiler-0.35.1.dist-info}/top_level.txt +0 -0
|
@@ -6,6 +6,8 @@ from siliconcompiler import sc_open
|
|
|
6
6
|
|
|
7
7
|
from siliconcompiler.tools.opensta import OpenSTATask
|
|
8
8
|
|
|
9
|
+
from siliconcompiler import TaskSkip
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
class TimingTaskBase(OpenSTATask):
|
|
11
13
|
'''
|
|
@@ -251,3 +253,14 @@ class FPGATimingTask(TimingTaskBase):
|
|
|
251
253
|
|
|
252
254
|
self.add_input_file(ext="sdc")
|
|
253
255
|
self.add_input_file(ext="typical.sdf")
|
|
256
|
+
|
|
257
|
+
def pre_process(self):
|
|
258
|
+
"""
|
|
259
|
+
Skip this node if no non-empty sdc files in inputs
|
|
260
|
+
"""
|
|
261
|
+
file_path = f"inputs/{self.design_topmodule}.sdc"
|
|
262
|
+
|
|
263
|
+
if os.path.getsize(file_path) == 0:
|
|
264
|
+
raise TaskSkip(f"an empty {self.design_topmodule}.sdc file")
|
|
265
|
+
|
|
266
|
+
super().pre_process()
|
|
@@ -17,12 +17,13 @@ class FPGASynthesis(YosysTask):
|
|
|
17
17
|
self.add_parameter(
|
|
18
18
|
"synth_opt_mode",
|
|
19
19
|
"<none,delay,area>",
|
|
20
|
-
"
|
|
20
|
+
"optimization mode: 'none' for a balanced optimization, 'delay' to"
|
|
21
|
+
" prioritize path delay, 'area' to prioritize utilization",
|
|
21
22
|
"none")
|
|
22
23
|
self.add_parameter(
|
|
23
24
|
"synth_insert_buffers",
|
|
24
25
|
"bool",
|
|
25
|
-
"
|
|
26
|
+
"perform buffer insertion",
|
|
26
27
|
True)
|
|
27
28
|
|
|
28
29
|
def task(self):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"openroad": {
|
|
3
3
|
"git-url": "https://github.com/The-OpenROAD-Project/OpenROAD.git",
|
|
4
|
-
"git-commit": "
|
|
4
|
+
"git-commit": "dee927a657e719812a07799b87934328d1e31657",
|
|
5
5
|
"docker-cmds": [
|
|
6
6
|
"# Remove OR-Tools files",
|
|
7
7
|
"RUN rm -f $SC_PREFIX/Makefile $SC_PREFIX/README.md",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"opensta": {
|
|
19
19
|
"git-url": "https://github.com/parallaxsw/OpenSTA.git",
|
|
20
|
-
"git-commit": "
|
|
20
|
+
"git-commit": "8f8f397610cebc9e647531914a6c071bcccd2757",
|
|
21
21
|
"auto-update": true
|
|
22
22
|
},
|
|
23
23
|
"netgen": {
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
},
|
|
158
158
|
"yosys-wildebeest": {
|
|
159
159
|
"git-url": "https://github.com/zeroasiccorp/wildebeest.git",
|
|
160
|
-
"git-commit": "
|
|
160
|
+
"git-commit": "d79f06403b500b95b4cb33288f520e4e24fb9c47",
|
|
161
161
|
"docker-depends": "yosys",
|
|
162
162
|
"auto-update": true
|
|
163
163
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import contextlib
|
|
2
|
+
import logging
|
|
2
3
|
import re
|
|
3
4
|
import pathlib
|
|
4
5
|
import psutil
|
|
@@ -10,9 +11,9 @@ import os.path
|
|
|
10
11
|
|
|
11
12
|
from io import StringIO
|
|
12
13
|
from pathlib import Path
|
|
13
|
-
from jinja2 import Environment, FileSystemLoader
|
|
14
|
+
from jinja2 import Environment, FileSystemLoader, Template
|
|
14
15
|
|
|
15
|
-
from typing import Dict
|
|
16
|
+
from typing import Dict, Optional, Union, Callable, List, TYPE_CHECKING
|
|
16
17
|
|
|
17
18
|
import sys
|
|
18
19
|
if sys.version_info < (3, 10):
|
|
@@ -22,6 +23,9 @@ else:
|
|
|
22
23
|
|
|
23
24
|
from siliconcompiler.utils.paths import builddir
|
|
24
25
|
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from siliconcompiler.project import Project
|
|
28
|
+
|
|
25
29
|
|
|
26
30
|
def link_symlink_copy(srcfile, dstfile):
|
|
27
31
|
# first try hard linking, then symbolic linking,
|
|
@@ -191,7 +195,7 @@ def default_email_credentials_file() -> str:
|
|
|
191
195
|
|
|
192
196
|
|
|
193
197
|
@contextlib.contextmanager
|
|
194
|
-
def sc_open(path, *args, **kwargs):
|
|
198
|
+
def sc_open(path: str, *args, **kwargs):
|
|
195
199
|
if 'errors' not in kwargs:
|
|
196
200
|
kwargs['errors'] = 'ignore'
|
|
197
201
|
kwargs["newline"] = "\n"
|
|
@@ -203,12 +207,12 @@ def sc_open(path, *args, **kwargs):
|
|
|
203
207
|
pass
|
|
204
208
|
|
|
205
209
|
|
|
206
|
-
def get_file_template(path,
|
|
207
|
-
root=os.path.join(
|
|
210
|
+
def get_file_template(path: str,
|
|
211
|
+
root: str = os.path.join(
|
|
208
212
|
os.path.dirname(
|
|
209
213
|
os.path.dirname(os.path.abspath(__file__))),
|
|
210
214
|
'data',
|
|
211
|
-
'templates')):
|
|
215
|
+
'templates')) -> Template:
|
|
212
216
|
if os.path.isabs(path):
|
|
213
217
|
root = os.path.dirname(path)
|
|
214
218
|
path = os.path.basename(path)
|
|
@@ -221,7 +225,7 @@ def get_file_template(path,
|
|
|
221
225
|
|
|
222
226
|
|
|
223
227
|
#######################################
|
|
224
|
-
def safecompare(value, op, goal):
|
|
228
|
+
def safecompare(value: Union[int, float], op: str, goal: Union[int, float]) -> bool:
|
|
225
229
|
# supported relational operations
|
|
226
230
|
# >, >=, <=, <. ==, !=
|
|
227
231
|
if op == ">":
|
|
@@ -241,7 +245,7 @@ def safecompare(value, op, goal):
|
|
|
241
245
|
|
|
242
246
|
|
|
243
247
|
###########################################################################
|
|
244
|
-
def grep(project, args, line):
|
|
248
|
+
def grep(project: "Project", args: str, line: str) -> Union[None, str]:
|
|
245
249
|
"""
|
|
246
250
|
Emulates the Unix grep command on a string.
|
|
247
251
|
|
|
@@ -275,6 +279,9 @@ def grep(project, args, line):
|
|
|
275
279
|
# Split into repeating switches and everything else
|
|
276
280
|
match = re.match(r'\s*((?:\-\w\s)*)(.*)', args)
|
|
277
281
|
|
|
282
|
+
if not match:
|
|
283
|
+
return None
|
|
284
|
+
|
|
278
285
|
pattern = match.group(2)
|
|
279
286
|
|
|
280
287
|
# Split space separated switch string into list
|
|
@@ -302,7 +309,7 @@ def grep(project, args, line):
|
|
|
302
309
|
return line
|
|
303
310
|
|
|
304
311
|
|
|
305
|
-
def get_plugins(system, name=None):
|
|
312
|
+
def get_plugins(system: str, name: Optional[str] = None) -> List[Callable]:
|
|
306
313
|
'''
|
|
307
314
|
Search for python modules with a specific function
|
|
308
315
|
'''
|
|
@@ -319,7 +326,7 @@ def get_plugins(system, name=None):
|
|
|
319
326
|
return plugins
|
|
320
327
|
|
|
321
328
|
|
|
322
|
-
def truncate_text(text, width):
|
|
329
|
+
def truncate_text(text: str, width: int) -> str:
|
|
323
330
|
width = max(width, 5)
|
|
324
331
|
|
|
325
332
|
if len(text) <= width:
|
|
@@ -338,7 +345,7 @@ def truncate_text(text, width):
|
|
|
338
345
|
return text
|
|
339
346
|
|
|
340
347
|
|
|
341
|
-
def get_cores(physical=False):
|
|
348
|
+
def get_cores(physical: bool = False) -> int:
|
|
342
349
|
'''
|
|
343
350
|
Get max number of cores for this machine.
|
|
344
351
|
|
|
@@ -360,7 +367,7 @@ def get_cores(physical=False):
|
|
|
360
367
|
return cores
|
|
361
368
|
|
|
362
369
|
|
|
363
|
-
def print_traceback(logger, exception):
|
|
370
|
+
def print_traceback(logger: logging.Logger, exception: Exception):
|
|
364
371
|
logger.error(f'{exception}')
|
|
365
372
|
trace = StringIO()
|
|
366
373
|
traceback.print_tb(exception.__traceback__, file=trace)
|
|
@@ -370,21 +377,21 @@ def print_traceback(logger, exception):
|
|
|
370
377
|
|
|
371
378
|
|
|
372
379
|
class FilterDirectories:
|
|
373
|
-
def __init__(self, project):
|
|
380
|
+
def __init__(self, project: "Project"):
|
|
374
381
|
self.file_count = 0
|
|
375
382
|
self.directory_file_limit = None
|
|
376
383
|
self.abspath = None
|
|
377
384
|
self.project = project
|
|
378
385
|
|
|
379
386
|
@property
|
|
380
|
-
def logger(self):
|
|
387
|
+
def logger(self) -> logging.Logger:
|
|
381
388
|
return self.project.logger
|
|
382
389
|
|
|
383
390
|
@property
|
|
384
|
-
def builddir(self):
|
|
391
|
+
def builddir(self) -> str:
|
|
385
392
|
return builddir(self.project)
|
|
386
393
|
|
|
387
|
-
def filter(self, path, files):
|
|
394
|
+
def filter(self, path: str, files: List[str]) -> List[str]:
|
|
388
395
|
if pathlib.Path(path) == pathlib.Path.home():
|
|
389
396
|
# refuse to collect home directory
|
|
390
397
|
self.logger.error(f'Cannot collect user home directory: {path}')
|
|
@@ -3,7 +3,7 @@ import tarfile
|
|
|
3
3
|
|
|
4
4
|
import os.path
|
|
5
5
|
|
|
6
|
-
from typing import List
|
|
6
|
+
from typing import List, Optional, TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from siliconcompiler.schema.parametervalue import NodeListValue, NodeSetValue
|
|
9
9
|
from siliconcompiler.utils import FilterDirectories
|
|
@@ -11,11 +11,14 @@ from siliconcompiler.utils.paths import collectiondir
|
|
|
11
11
|
from siliconcompiler.scheduler import SchedulerNode
|
|
12
12
|
from siliconcompiler.flowgraph import RuntimeFlowgraph
|
|
13
13
|
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from siliconcompiler.project import Project
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
def collect(project: "Project",
|
|
19
|
+
directory: Optional[str] = None,
|
|
17
20
|
verbose: bool = True,
|
|
18
|
-
whitelist: List[str] = None):
|
|
21
|
+
whitelist: Optional[List[str]] = None) -> None:
|
|
19
22
|
'''
|
|
20
23
|
Collects files and directories specified in the schema and places
|
|
21
24
|
them in a collection directory. The function only copies items that have
|
|
@@ -165,7 +168,10 @@ def collect(project,
|
|
|
165
168
|
shutil.copy2(abs_path, import_path)
|
|
166
169
|
|
|
167
170
|
|
|
168
|
-
def archive(project
|
|
171
|
+
def archive(project: "Project",
|
|
172
|
+
jobname: Optional[str] = None,
|
|
173
|
+
include: Optional[List[str]] = None,
|
|
174
|
+
archive_name: Optional[str] = None) -> None:
|
|
169
175
|
'''Archive a job directory into a compressed tarball.
|
|
170
176
|
|
|
171
177
|
Creates a single compressed archive (.tgz) based on the specified job.
|
|
@@ -5,6 +5,8 @@ import tempfile
|
|
|
5
5
|
|
|
6
6
|
import os.path
|
|
7
7
|
|
|
8
|
+
from typing import Union, Optional
|
|
9
|
+
|
|
8
10
|
from datetime import datetime
|
|
9
11
|
from multiprocessing.managers import SyncManager
|
|
10
12
|
|
|
@@ -29,7 +31,7 @@ class _ManagerSingleton(type):
|
|
|
29
31
|
_lock = multiprocessing.Lock()
|
|
30
32
|
|
|
31
33
|
@staticmethod
|
|
32
|
-
def has_cls(
|
|
34
|
+
def has_cls(mcls):
|
|
33
35
|
"""
|
|
34
36
|
Checks if a singleton instance exists for the given class.
|
|
35
37
|
|
|
@@ -39,10 +41,10 @@ class _ManagerSingleton(type):
|
|
|
39
41
|
Returns:
|
|
40
42
|
bool: True if an instance exists, False otherwise.
|
|
41
43
|
"""
|
|
42
|
-
return
|
|
44
|
+
return mcls in _ManagerSingleton._instances
|
|
43
45
|
|
|
44
46
|
@staticmethod
|
|
45
|
-
def remove_cls(
|
|
47
|
+
def remove_cls(mcls):
|
|
46
48
|
"""
|
|
47
49
|
Removes a class's singleton instance from the registry.
|
|
48
50
|
|
|
@@ -52,12 +54,12 @@ class _ManagerSingleton(type):
|
|
|
52
54
|
Args:
|
|
53
55
|
cls (type): The class whose instance should be removed.
|
|
54
56
|
"""
|
|
55
|
-
if not _ManagerSingleton.has_cls(
|
|
57
|
+
if not _ManagerSingleton.has_cls(mcls):
|
|
56
58
|
return
|
|
57
59
|
|
|
58
60
|
with _ManagerSingleton._lock:
|
|
59
|
-
if
|
|
60
|
-
del _ManagerSingleton._instances[
|
|
61
|
+
if mcls in _ManagerSingleton._instances:
|
|
62
|
+
del _ManagerSingleton._instances[mcls]
|
|
61
63
|
|
|
62
64
|
def __call__(cls, *args, **kwargs):
|
|
63
65
|
"""
|
|
@@ -86,7 +88,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
86
88
|
It is designed to be instantiated once and accessed globally.
|
|
87
89
|
"""
|
|
88
90
|
__ENABLE_LOGGER: bool = True
|
|
89
|
-
__address: str = None
|
|
91
|
+
__address: Union[None, str] = None
|
|
90
92
|
__authkey: bytes = b'siliconcompiler-manager-authkey' # arbitrary authkey value
|
|
91
93
|
|
|
92
94
|
def __init__(self):
|
|
@@ -98,7 +100,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
98
100
|
"""
|
|
99
101
|
pass
|
|
100
102
|
|
|
101
|
-
def _init_singleton(self):
|
|
103
|
+
def _init_singleton(self) -> None:
|
|
102
104
|
"""
|
|
103
105
|
Performs the one-time initialization of the singleton instance.
|
|
104
106
|
|
|
@@ -140,7 +142,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
140
142
|
# Register cleanup function to run at exit
|
|
141
143
|
atexit.register(MPManager.stop)
|
|
142
144
|
|
|
143
|
-
def _init_logger(self):
|
|
145
|
+
def _init_logger(self) -> None:
|
|
144
146
|
"""
|
|
145
147
|
Initializes the logging configuration for SiliconCompiler.
|
|
146
148
|
|
|
@@ -175,7 +177,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
175
177
|
pass
|
|
176
178
|
|
|
177
179
|
@staticmethod
|
|
178
|
-
def stop():
|
|
180
|
+
def stop() -> None:
|
|
179
181
|
"""
|
|
180
182
|
Cleans up all managed resources as a static method.
|
|
181
183
|
|
|
@@ -220,7 +222,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
220
222
|
_ManagerSingleton.remove_cls(MPManager)
|
|
221
223
|
|
|
222
224
|
@staticmethod
|
|
223
|
-
def error(msg: str = None):
|
|
225
|
+
def error(msg: Optional[str] = None):
|
|
224
226
|
"""
|
|
225
227
|
Logs an error and flags the session as having an error.
|
|
226
228
|
|
|
@@ -238,7 +240,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
238
240
|
manager.__error = True
|
|
239
241
|
|
|
240
242
|
@staticmethod
|
|
241
|
-
def get_manager():
|
|
243
|
+
def get_manager() -> SyncManager:
|
|
242
244
|
"""
|
|
243
245
|
Provides access to the shared multiprocessing.Manager instance.
|
|
244
246
|
|
|
@@ -277,7 +279,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
277
279
|
return MPManager().__logger
|
|
278
280
|
|
|
279
281
|
@staticmethod
|
|
280
|
-
def _set_manager_address(address: str):
|
|
282
|
+
def _set_manager_address(address: str) -> None:
|
|
281
283
|
"""
|
|
282
284
|
Set the address of the manager
|
|
283
285
|
"""
|
|
@@ -285,7 +287,7 @@ class MPManager(metaclass=_ManagerSingleton):
|
|
|
285
287
|
MPManager.__address = address
|
|
286
288
|
|
|
287
289
|
@staticmethod
|
|
288
|
-
def _get_manager_address() -> str:
|
|
290
|
+
def _get_manager_address() -> Union[None, str]:
|
|
289
291
|
"""
|
|
290
292
|
Get the address of the manager
|
|
291
293
|
"""
|
siliconcompiler/utils/paths.py
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import os.path
|
|
2
2
|
|
|
3
|
-
from typing import Union
|
|
3
|
+
from typing import Union, Optional, TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from siliconcompiler.project import Project
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
def cwdir(project: "Project") -> str:
|
|
10
|
+
from siliconcompiler import Project
|
|
11
|
+
if not isinstance(project, Project):
|
|
12
|
+
raise TypeError("project must be a Project type")
|
|
13
|
+
return project._Project__cwd
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def builddir(project: "Project") -> str:
|
|
7
17
|
"""
|
|
8
18
|
Returns the absolute path to the project's build directory.
|
|
9
19
|
|
|
@@ -24,14 +34,14 @@ def builddir(project) -> str:
|
|
|
24
34
|
if not isinstance(project, Project):
|
|
25
35
|
raise TypeError("project must be a Project type")
|
|
26
36
|
|
|
27
|
-
builddir = project.get('option', 'builddir')
|
|
37
|
+
builddir: str = project.get('option', 'builddir')
|
|
28
38
|
if os.path.isabs(builddir):
|
|
29
39
|
return builddir
|
|
30
40
|
|
|
31
|
-
return os.path.join(project
|
|
41
|
+
return os.path.join(cwdir(project), builddir)
|
|
32
42
|
|
|
33
43
|
|
|
34
|
-
def jobdir(project) -> str:
|
|
44
|
+
def jobdir(project: "Project") -> str:
|
|
35
45
|
"""
|
|
36
46
|
Returns the absolute path to the current job directory.
|
|
37
47
|
|
|
@@ -55,13 +65,15 @@ def jobdir(project) -> str:
|
|
|
55
65
|
if not project.name:
|
|
56
66
|
raise ValueError("name has not been set")
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
project.get('option', 'jobname'))
|
|
68
|
+
jobname: str = project.get('option', 'jobname')
|
|
69
|
+
|
|
70
|
+
return os.path.join(builddir(project), project.name, jobname)
|
|
62
71
|
|
|
63
72
|
|
|
64
|
-
def workdir(project
|
|
73
|
+
def workdir(project: "Project",
|
|
74
|
+
step: Optional[str] = None,
|
|
75
|
+
index: Optional[Union[int, str]] = None,
|
|
76
|
+
relpath: Optional[bool] = False) -> str:
|
|
65
77
|
"""
|
|
66
78
|
Returns path to the working directory for a given step and index.
|
|
67
79
|
|
|
@@ -100,12 +112,12 @@ def workdir(project, step: str = None, index: Union[int, str] = None, relpath: b
|
|
|
100
112
|
|
|
101
113
|
path = os.path.join(jobdir(project), *dirlist)
|
|
102
114
|
if relpath:
|
|
103
|
-
return os.path.relpath(path, project
|
|
115
|
+
return os.path.relpath(path, cwdir(project))
|
|
104
116
|
|
|
105
117
|
return path
|
|
106
118
|
|
|
107
119
|
|
|
108
|
-
def collectiondir(project) -> str:
|
|
120
|
+
def collectiondir(project: "Project") -> Union[None, str]:
|
|
109
121
|
"""
|
|
110
122
|
Returns the absolute path to the file collection directory.
|
|
111
123
|
|
siliconcompiler/utils/units.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import math
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
|
+
from typing import Optional, Tuple
|
|
5
|
+
|
|
4
6
|
SI_UNITS = (
|
|
5
7
|
('y', -24),
|
|
6
8
|
('z', -21),
|
|
@@ -51,7 +53,7 @@ BINARY_TYPES = (
|
|
|
51
53
|
)
|
|
52
54
|
|
|
53
55
|
|
|
54
|
-
def convert(value, from_unit=None, to_unit=None):
|
|
56
|
+
def convert(value: float, from_unit: Optional[str] = None, to_unit: Optional[str] = None) -> float:
|
|
55
57
|
'''
|
|
56
58
|
Convert a value to from one SI power to another SI power
|
|
57
59
|
|
|
@@ -80,7 +82,7 @@ def convert(value, from_unit=None, to_unit=None):
|
|
|
80
82
|
return value * scale
|
|
81
83
|
|
|
82
84
|
|
|
83
|
-
def _get_scale(unit):
|
|
85
|
+
def _get_scale(unit: Optional[str]) -> int:
|
|
84
86
|
if not unit:
|
|
85
87
|
unit = ''
|
|
86
88
|
unit_prefix = get_si_prefix(unit)
|
|
@@ -91,7 +93,7 @@ def _get_scale(unit):
|
|
|
91
93
|
return 1
|
|
92
94
|
|
|
93
95
|
|
|
94
|
-
def get_si_prefix(unit):
|
|
96
|
+
def get_si_prefix(unit: Optional[str]) -> str:
|
|
95
97
|
'''
|
|
96
98
|
Get the SI prefix of the specific unit.
|
|
97
99
|
|
|
@@ -107,8 +109,10 @@ def get_si_prefix(unit):
|
|
|
107
109
|
if matches:
|
|
108
110
|
return matches[0][0]
|
|
109
111
|
|
|
112
|
+
return ''
|
|
113
|
+
|
|
110
114
|
|
|
111
|
-
def get_si_power(unit):
|
|
115
|
+
def get_si_power(unit: Optional[str]) -> int:
|
|
112
116
|
'''
|
|
113
117
|
Get the SI power of the specific unit.
|
|
114
118
|
This is mainly needed for area units.
|
|
@@ -129,28 +133,28 @@ def get_si_power(unit):
|
|
|
129
133
|
return 1
|
|
130
134
|
|
|
131
135
|
|
|
132
|
-
def is_base_si_unit(unit):
|
|
136
|
+
def is_base_si_unit(unit: Optional[str]) -> bool:
|
|
133
137
|
'''
|
|
134
138
|
Check if a unit has no magnitude
|
|
135
139
|
'''
|
|
136
140
|
return unit in SI_TYPES
|
|
137
141
|
|
|
138
142
|
|
|
139
|
-
def is_base_si_unit_power(unit):
|
|
143
|
+
def is_base_si_unit_power(unit: Optional[str]) -> bool:
|
|
140
144
|
'''
|
|
141
145
|
Check if a unit has a power associated with it
|
|
142
146
|
'''
|
|
143
147
|
return get_si_power(unit) > 1
|
|
144
148
|
|
|
145
149
|
|
|
146
|
-
def is_base_binary_unit(unit):
|
|
150
|
+
def is_base_binary_unit(unit: Optional[str]) -> bool:
|
|
147
151
|
'''
|
|
148
152
|
Check if a unit is binary
|
|
149
153
|
'''
|
|
150
154
|
return unit in BINARY_TYPES
|
|
151
155
|
|
|
152
156
|
|
|
153
|
-
def format_si(value, unit, margin=3, digits=3):
|
|
157
|
+
def format_si(value: float, unit: str, margin: int = 3, digits: int = 3) -> str:
|
|
154
158
|
'''
|
|
155
159
|
Format a number as an SI number. Returns a string.
|
|
156
160
|
|
|
@@ -171,7 +175,7 @@ def format_si(value, unit, margin=3, digits=3):
|
|
|
171
175
|
return f'{scaled_value:.{digits}f}{prefix}'
|
|
172
176
|
|
|
173
177
|
|
|
174
|
-
def scale_si(value, unit, margin=3, digits=3):
|
|
178
|
+
def scale_si(value: float, unit: str, margin: int = 3, digits: int = 3) -> Tuple[float, str]:
|
|
175
179
|
'''
|
|
176
180
|
Format a number as an SI number. Returns a float.
|
|
177
181
|
|
|
@@ -200,7 +204,7 @@ def scale_si(value, unit, margin=3, digits=3):
|
|
|
200
204
|
return (float(f'{value:.{digits}f}'), '')
|
|
201
205
|
|
|
202
206
|
|
|
203
|
-
def format_binary(value, unit, digits=3):
|
|
207
|
+
def format_binary(value: float, unit: Optional[str], digits: int = 3) -> str:
|
|
204
208
|
'''
|
|
205
209
|
Format a number as a binary number. Returns a string.
|
|
206
210
|
|
|
@@ -214,7 +218,7 @@ def format_binary(value, unit, digits=3):
|
|
|
214
218
|
return f'{scaled_value:.{digits}f}{prefix}'
|
|
215
219
|
|
|
216
220
|
|
|
217
|
-
def scale_binary(value, unit, digits=3):
|
|
221
|
+
def scale_binary(value: float, unit: Optional[str], digits: int = 3) -> Tuple[float, str]:
|
|
218
222
|
'''
|
|
219
223
|
Format a number as a binary number. Returns a float.
|
|
220
224
|
|
|
@@ -239,7 +243,7 @@ def scale_binary(value, unit, digits=3):
|
|
|
239
243
|
return (float(f'{value:.{digits}f}'), '')
|
|
240
244
|
|
|
241
245
|
|
|
242
|
-
def format_time(value):
|
|
246
|
+
def format_time(value: float) -> str:
|
|
243
247
|
'''
|
|
244
248
|
Format a number as time.
|
|
245
249
|
Prints as hh:mm:ss.ms (hours:minutes:seconds.milliseconds)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: siliconcompiler
|
|
3
|
-
Version: 0.35.
|
|
3
|
+
Version: 0.35.1
|
|
4
4
|
Summary: A compiler framework that automates translation from source code to silicon.
|
|
5
5
|
Author: Zero ASIC
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -24,7 +24,7 @@ Classifier: Topic :: Software Development :: Build Tools
|
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
|
-
Requires-Dist: aiohttp<3.
|
|
27
|
+
Requires-Dist: aiohttp<3.14.0,>=3.10.11
|
|
28
28
|
Requires-Dist: distro<2.0.0,>=1.9.0
|
|
29
29
|
Requires-Dist: docker<8.0.0,>=7.1.0
|
|
30
30
|
Requires-Dist: fastjsonschema<2.22.0,>=2.20.0
|
|
@@ -37,7 +37,7 @@ Requires-Dist: PyYAML<7.0.0,>=6.0.0
|
|
|
37
37
|
Requires-Dist: GitPython<3.2,>=3.1.44
|
|
38
38
|
Requires-Dist: PyGithub<2.9.0,>=2.8.0
|
|
39
39
|
Requires-Dist: urllib3>=1.26.0
|
|
40
|
-
Requires-Dist: lambdapdk>=0.2.
|
|
40
|
+
Requires-Dist: lambdapdk>=0.2.1
|
|
41
41
|
Requires-Dist: fasteners>=0.20
|
|
42
42
|
Requires-Dist: pandas>=1.1.5
|
|
43
43
|
Requires-Dist: psutil>=5.8.0
|
|
@@ -58,7 +58,6 @@ Requires-Dist: pytest-asyncio==1.2.0; extra == "test"
|
|
|
58
58
|
Requires-Dist: pytest-cov==7.0.0; extra == "test"
|
|
59
59
|
Requires-Dist: responses==0.25.8; extra == "test"
|
|
60
60
|
Requires-Dist: PyVirtualDisplay==3.0; extra == "test"
|
|
61
|
-
Requires-Dist: logiklib==0.1.0; extra == "test"
|
|
62
61
|
Provides-Extra: lint
|
|
63
62
|
Requires-Dist: flake8==7.3.0; extra == "lint"
|
|
64
63
|
Requires-Dist: tclint==0.6.1; extra == "lint"
|