siliconcompiler 0.29.4__py3-none-any.whl → 0.30.0__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/sc.py +1 -1
- siliconcompiler/apps/sc_install.py +28 -0
- siliconcompiler/core.py +15 -4
- siliconcompiler/schema/schema_cfg.py +149 -92
- siliconcompiler/tools/__init__.py +3 -1
- siliconcompiler/tools/bluespec/__init__.py +35 -0
- siliconcompiler/tools/bluespec/convert.py +44 -5
- siliconcompiler/tools/graphviz/__init__.py +12 -0
- siliconcompiler/tools/graphviz/screenshot.py +48 -0
- siliconcompiler/tools/graphviz/show.py +20 -0
- siliconcompiler/tools/openroad/_apr.py +6 -0
- siliconcompiler/tools/openroad/macro_placement.py +9 -0
- siliconcompiler/tools/openroad/power_grid.py +6 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +15 -5
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +9 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +53 -0
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +26 -5
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +10 -3
- siliconcompiler/toolscripts/_tools.json +4 -4
- siliconcompiler/toolscripts/rhel9/install-openroad.sh +1 -1
- siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +1 -1
- siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +1 -1
- siliconcompiler/utils/__init__.py +11 -0
- siliconcompiler/utils/showtools.py +7 -0
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/METADATA +5 -5
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/RECORD +34 -32
- siliconcompiler/tools/bluespec/bluespec.py +0 -40
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/WHEEL +0 -0
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/entry_points.txt +0 -0
- {siliconcompiler-0.29.4.dist-info → siliconcompiler-0.30.0.dist-info}/top_level.txt +0 -0
siliconcompiler/_metadata.py
CHANGED
siliconcompiler/apps/sc.py
CHANGED
|
@@ -248,6 +248,34 @@ To system debugging information (this should only be used to debug):
|
|
|
248
248
|
if not install_tool(tool, tools[tool], args.build_dir, args.prefix):
|
|
249
249
|
return 1
|
|
250
250
|
|
|
251
|
+
if not args.show:
|
|
252
|
+
msgs = []
|
|
253
|
+
for env, path in (
|
|
254
|
+
("PATH", "bin"),
|
|
255
|
+
("LD_LIBRARY_PATH", "lib")):
|
|
256
|
+
check_path = os.path.join(args.prefix, path)
|
|
257
|
+
envs = [
|
|
258
|
+
os.path.expandvars(os.path.expanduser(p))
|
|
259
|
+
for p in os.getenv(env, "").split(":")
|
|
260
|
+
]
|
|
261
|
+
print(envs)
|
|
262
|
+
if check_path not in envs:
|
|
263
|
+
msgs.extend([
|
|
264
|
+
"",
|
|
265
|
+
f"{check_path} not found in {env}",
|
|
266
|
+
"you may need to add it the following your shell",
|
|
267
|
+
"initialization script:",
|
|
268
|
+
f'export {env}="{check_path}:${env}"'
|
|
269
|
+
])
|
|
270
|
+
if msgs:
|
|
271
|
+
center_len = max(len(msg) for msg in msgs)
|
|
272
|
+
max_len = center_len + 4
|
|
273
|
+
print("#"*max_len)
|
|
274
|
+
for msg in msgs:
|
|
275
|
+
print(f"# {msg:<{center_len}} #")
|
|
276
|
+
print(f"# {' '*center_len} #")
|
|
277
|
+
print("#"*max_len)
|
|
278
|
+
|
|
251
279
|
return 0
|
|
252
280
|
|
|
253
281
|
|
siliconcompiler/core.py
CHANGED
|
@@ -67,7 +67,7 @@ class Chip:
|
|
|
67
67
|
except FileNotFoundError:
|
|
68
68
|
raise SiliconCompilerError(
|
|
69
69
|
"SiliconCompiler must be run from a directory that exists. "
|
|
70
|
-
"If you are sure that your working directory is valid, try running `cd $(pwd)`."
|
|
70
|
+
"If you are sure that your working directory is valid, try running `cd $(pwd)`.")
|
|
71
71
|
|
|
72
72
|
# Initialize custom error handling for codecs. This has to be called
|
|
73
73
|
# by each spawned (as opposed to forked) subprocess
|
|
@@ -3153,7 +3153,7 @@ class Chip:
|
|
|
3153
3153
|
self.add('flowgraph', flow, newstep, index, 'input', (newin, in_index))
|
|
3154
3154
|
|
|
3155
3155
|
###########################################################################
|
|
3156
|
-
def run(self):
|
|
3156
|
+
def run(self, raise_exception=False):
|
|
3157
3157
|
'''
|
|
3158
3158
|
Executes tasks in a flowgraph.
|
|
3159
3159
|
|
|
@@ -3177,12 +3177,23 @@ class Chip:
|
|
|
3177
3177
|
processes to exit before start, returning control to the the main
|
|
3178
3178
|
program which can then exit.
|
|
3179
3179
|
|
|
3180
|
+
Args:
|
|
3181
|
+
raise_exception (bool): if True, will rethrow errors that the flow raises,
|
|
3182
|
+
otherwise will report the error and return False
|
|
3183
|
+
|
|
3180
3184
|
Examples:
|
|
3181
3185
|
>>> run()
|
|
3182
3186
|
Runs the execution flow defined by the flowgraph dictionary.
|
|
3183
3187
|
'''
|
|
3184
3188
|
|
|
3185
|
-
|
|
3189
|
+
try:
|
|
3190
|
+
sc_runner(self)
|
|
3191
|
+
except Exception as e:
|
|
3192
|
+
if raise_exception:
|
|
3193
|
+
raise e
|
|
3194
|
+
self.logger.error(str(e))
|
|
3195
|
+
return False
|
|
3196
|
+
return True
|
|
3186
3197
|
|
|
3187
3198
|
###########################################################################
|
|
3188
3199
|
def show(self, filename=None, screenshot=False, extension=None):
|
|
@@ -3320,7 +3331,7 @@ class Chip:
|
|
|
3320
3331
|
|
|
3321
3332
|
# run show flow
|
|
3322
3333
|
try:
|
|
3323
|
-
self.run()
|
|
3334
|
+
self.run(raise_exception=True)
|
|
3324
3335
|
if screenshot:
|
|
3325
3336
|
step, index = _get_flowgraph_exit_nodes(self, flow='showflow')[0]
|
|
3326
3337
|
success = self.find_result('png', step=step, index=index)
|
|
@@ -10,7 +10,7 @@ try:
|
|
|
10
10
|
except ImportError:
|
|
11
11
|
from siliconcompiler.schema.utils import trim
|
|
12
12
|
|
|
13
|
-
SCHEMA_VERSION = '0.
|
|
13
|
+
SCHEMA_VERSION = '0.49.0'
|
|
14
14
|
|
|
15
15
|
#############################################################################
|
|
16
16
|
# PARAM DEFINITION
|
|
@@ -1260,17 +1260,35 @@ def schema_datasheet(cfg, name='default', mode='default'):
|
|
|
1260
1260
|
example=[
|
|
1261
1261
|
"cli: -datasheet_package_type 'abcd bga'",
|
|
1262
1262
|
"api: chip.set('datasheet', 'package', 'abcd', 'type', 'bga')"],
|
|
1263
|
-
schelp="""Package type
|
|
1263
|
+
schelp="""Package type.""")
|
|
1264
1264
|
|
|
1265
1265
|
scparam(cfg, ['datasheet', 'package', name, 'footprint'],
|
|
1266
|
-
sctype='
|
|
1266
|
+
sctype='[file]',
|
|
1267
1267
|
shorthelp="Datasheet: package footprint",
|
|
1268
|
-
switch="-datasheet_package_footprint 'name <
|
|
1268
|
+
switch="-datasheet_package_footprint 'name <file>'",
|
|
1269
|
+
example=[
|
|
1270
|
+
"cli: -datasheet_package_footprint 'abcd ./soic8.kicad_mod'",
|
|
1271
|
+
"api: chip.set('datasheet', 'package', 'abcd', 'footprint', './soic8.kicad_mod')"],
|
|
1272
|
+
schelp="""Package footprint file. Supported 3D model file formats include:
|
|
1273
|
+
|
|
1274
|
+
* (KICAD_MOD) KiCad Standard Footprint Format
|
|
1275
|
+
|
|
1276
|
+
""")
|
|
1277
|
+
|
|
1278
|
+
scparam(cfg, ['datasheet', 'package', name, '3dmodel'],
|
|
1279
|
+
sctype='[file]',
|
|
1280
|
+
shorthelp="Datasheet: package 3D model",
|
|
1281
|
+
switch="-datasheet_package_3dmodel 'name <file>'",
|
|
1269
1282
|
example=[
|
|
1270
|
-
"cli: -
|
|
1271
|
-
"api: chip.set('datasheet', 'package', 'abcd', '
|
|
1272
|
-
schelp="""Package
|
|
1273
|
-
|
|
1283
|
+
"cli: -datasheet_package_3dmodel 'abcd ./soic8.step'",
|
|
1284
|
+
"api: chip.set('datasheet', 'package', 'abcd', '3dmodel', './soic8.step')"],
|
|
1285
|
+
schelp="""Package 3D model file. Supported 3D model file formats include:
|
|
1286
|
+
|
|
1287
|
+
* (STEP) Standard for the Exchange of Product Data Format
|
|
1288
|
+
* (STL) Stereolithography Format
|
|
1289
|
+
* (WRL) Virtually Reality Modeling Language Format
|
|
1290
|
+
|
|
1291
|
+
""")
|
|
1274
1292
|
|
|
1275
1293
|
scparam(cfg, ['datasheet', 'package', name, 'drawing'],
|
|
1276
1294
|
sctype='[file]',
|
|
@@ -1279,38 +1297,14 @@ def schema_datasheet(cfg, name='default', mode='default'):
|
|
|
1279
1297
|
example=[
|
|
1280
1298
|
"cli: -datasheet_package_drawing 'abcd p484.pdf'",
|
|
1281
1299
|
"api: chip.set('datasheet', 'package', 'abcd', 'drawing', 'p484.pdf')"],
|
|
1282
|
-
schelp="""Mechanical
|
|
1283
|
-
|
|
1300
|
+
schelp="""Mechanical drawing for documentation purposes.
|
|
1301
|
+
Supported file formats include: PDF, DOC, SVG, and PNG.""")
|
|
1284
1302
|
|
|
1285
|
-
|
|
1286
|
-
sctype='int',
|
|
1287
|
-
shorthelp="Datasheet: package total pincount",
|
|
1288
|
-
switch="-datasheet_package_pincount 'name <int>'",
|
|
1289
|
-
example=[
|
|
1290
|
-
"cli: -datasheet_package_pincount 'abcd 484'",
|
|
1291
|
-
"api: chip.set('datasheet', 'package', 'abcd', 'pincount', '484')"],
|
|
1292
|
-
schelp="""Total number package pins of the named package.""")
|
|
1293
|
-
|
|
1294
|
-
scparam(cfg, ['datasheet', 'package', name, 'anchor'],
|
|
1295
|
-
sctype='(float,float)',
|
|
1296
|
-
defvalue=(0.0, 0.0),
|
|
1297
|
-
unit='um',
|
|
1298
|
-
shorthelp="Datasheeet: package anchor",
|
|
1299
|
-
switch="-datasheet_package_anchor 'name <(float,float)>'",
|
|
1300
|
-
example=[
|
|
1301
|
-
"cli: -datasheet_package_anchor 'i0 (3.0,3.0)'",
|
|
1302
|
-
"api: chip.set('datasheet', 'package', 'i0', 'anchor', (3.0, 3.0))"],
|
|
1303
|
-
schelp="""
|
|
1304
|
-
Package anchor point with respect to the lower left corner of the package.
|
|
1305
|
-
When placing a component on a substrate, the placement location specifies
|
|
1306
|
-
the distance from the substrate origin to the anchor point of the placed
|
|
1307
|
-
object.""")
|
|
1308
|
-
|
|
1309
|
-
# critical dimensions
|
|
1303
|
+
# key package metrics
|
|
1310
1304
|
metrics = {'length': ['length', (4000, 4000, 4000), 'um'],
|
|
1311
1305
|
'width': ['width', (4000, 4000, 4000), 'um'],
|
|
1312
1306
|
'thickness': ['thickness', (900, 1000, 1100), 'um'],
|
|
1313
|
-
'
|
|
1307
|
+
'pinpitch': ['pin pitch', (800, 850, 900), 'um']
|
|
1314
1308
|
}
|
|
1315
1309
|
|
|
1316
1310
|
for i, v in metrics.items():
|
|
@@ -1322,63 +1316,46 @@ def schema_datasheet(cfg, name='default', mode='default'):
|
|
|
1322
1316
|
example=[
|
|
1323
1317
|
f"cli: -datasheet_package_{i} 'abcd {v[1]}'",
|
|
1324
1318
|
f"api: chip.set('datasheet', 'package', 'abcd', '{i}', {v[1]}"],
|
|
1325
|
-
schelp=f"""
|
|
1319
|
+
schelp=f"""Package {v[0]}. Values are tuples of
|
|
1326
1320
|
(min, nominal, max).""")
|
|
1327
1321
|
|
|
1328
|
-
#
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
shorthelp="Datasheet: package pin shape",
|
|
1334
|
-
switch="-datasheet_package_pin_shape 'name pinnumber <str>'",
|
|
1322
|
+
# pin
|
|
1323
|
+
scparam(cfg, ['datasheet', 'package', name, 'pincount'],
|
|
1324
|
+
sctype='int',
|
|
1325
|
+
shorthelp="Datasheet: package pin count",
|
|
1326
|
+
switch="-datasheet_package_pincount 'name <int>'",
|
|
1335
1327
|
example=[
|
|
1336
|
-
"cli: -
|
|
1337
|
-
"api: chip.set('datasheet', 'package', 'abcd', '
|
|
1338
|
-
schelp="""
|
|
1339
|
-
and per pin number basis.""")
|
|
1340
|
-
|
|
1341
|
-
metrics = {'width': ['width', (200, 250, 300), 'um'],
|
|
1342
|
-
'length': ['length', (200, 250, 300), 'um']
|
|
1343
|
-
}
|
|
1328
|
+
"cli: -datasheet_package_pincount 'abcd 484'",
|
|
1329
|
+
"api: chip.set('datasheet', 'package', 'abcd', 'pincount', '484')"],
|
|
1330
|
+
schelp="""Total number package pins.""")
|
|
1344
1331
|
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1332
|
+
number = 'default'
|
|
1333
|
+
scparam(cfg, ['datasheet', 'package', name, 'pin', number, 'signal'],
|
|
1334
|
+
sctype='str',
|
|
1335
|
+
shorthelp="Datasheet: package pin signal map",
|
|
1336
|
+
switch="-datasheet_package_pin_signal 'name number <str>'",
|
|
1337
|
+
example=[
|
|
1338
|
+
"cli: -datasheet_package_pin_signal 'abcd B1 clk'",
|
|
1339
|
+
"api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', 'signal', 'clk')"],
|
|
1340
|
+
schelp="""Mapping between the package physical pin name ("1", "2", "A1", "B3", ...)
|
|
1341
|
+
and the corresponding device signal name ("VDD", "CLK", "NRST") found in the
|
|
1342
|
+
:keypath:`datasheet,pin`.""")
|
|
1356
1343
|
|
|
1357
|
-
|
|
1344
|
+
# anchor
|
|
1345
|
+
scparam(cfg, ['datasheet', 'package', name, 'anchor'],
|
|
1358
1346
|
sctype='(float,float)',
|
|
1347
|
+
defvalue=(0.0, 0.0),
|
|
1359
1348
|
unit='um',
|
|
1360
|
-
shorthelp="Datasheet: package
|
|
1361
|
-
switch="-
|
|
1349
|
+
shorthelp="Datasheet: package anchor",
|
|
1350
|
+
switch="-datasheet_package_anchor 'name <(float,float)>'",
|
|
1362
1351
|
example=[
|
|
1363
|
-
"cli: -
|
|
1364
|
-
"api: chip.set('datasheet', 'package', '
|
|
1365
|
-
schelp="""
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
sctype='str',
|
|
1371
|
-
shorthelp="Datasheet: package pin name",
|
|
1372
|
-
switch="-datasheet_package_pin_name 'name pinnumber <str>'",
|
|
1373
|
-
example=[
|
|
1374
|
-
"cli: -datasheet_package_pin_name 'abcd B1 clk'",
|
|
1375
|
-
"api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', 'name', 'clk')"],
|
|
1376
|
-
schelp="""Datsheet: Package pin name specified on a per package and per pin
|
|
1377
|
-
number basis. The pin number is generally an integer starting at '1' in the case of
|
|
1378
|
-
packages like qfn, qfp and an array index ('A1', 'A2') in the case of array packages
|
|
1379
|
-
like bgas. The pin name refers to the logical function assigned to the physical
|
|
1380
|
-
pin number (e.g clk, vss, in). Details regarding the logical pin is stored in
|
|
1381
|
-
the :keypath:`datasheet,pin`.""")
|
|
1352
|
+
"cli: -datasheet_package_anchor 'i0 (3.0, 3.0)'",
|
|
1353
|
+
"api: chip.set('datasheet', 'package', 'i0', 'anchor', (3.0, 3.0))"],
|
|
1354
|
+
schelp="""
|
|
1355
|
+
Package anchor point with respect to the lower left corner of the package.
|
|
1356
|
+
When placing a component on a substrate, the placement location specifies
|
|
1357
|
+
the distance from the substrate origin to the anchor point of the placed
|
|
1358
|
+
object.""")
|
|
1382
1359
|
|
|
1383
1360
|
######################
|
|
1384
1361
|
# Pin Specifications
|
|
@@ -3784,10 +3761,11 @@ def schema_constraint(cfg):
|
|
|
3784
3761
|
"api: chip.set('constraint', 'component', 'i0', 'halo', (1, 1))"],
|
|
3785
3762
|
schelp="""
|
|
3786
3763
|
Placement keepout halo around the named component, specified as a
|
|
3787
|
-
(horizontal, vertical) tuple
|
|
3764
|
+
(horizontal, vertical) tuple.""")
|
|
3788
3765
|
|
|
3789
3766
|
scparam(cfg, ['constraint', 'component', inst, 'rotation'],
|
|
3790
3767
|
sctype='enum',
|
|
3768
|
+
pernode='optional',
|
|
3791
3769
|
defvalue='R0',
|
|
3792
3770
|
enum=['R0', 'R90', 'R180', 'R270',
|
|
3793
3771
|
'MX', 'MX_R90', 'MX_R180', 'MX_R270',
|
|
@@ -3795,7 +3773,6 @@ def schema_constraint(cfg):
|
|
|
3795
3773
|
'MZ', 'MZ_R90', 'MZ_R180', 'MZ_R270',
|
|
3796
3774
|
'MZ_MX', 'MZ_MX_R90', 'MZ_MX_R180', 'MZ_MX_R270',
|
|
3797
3775
|
'MZ_MY', 'MZ_MY_R90', 'MZ_MY_R180', 'MZ_MY_R270'],
|
|
3798
|
-
pernode='optional',
|
|
3799
3776
|
shorthelp="Constraint: component rotation",
|
|
3800
3777
|
switch="-constraint_component_rotation 'inst <str>'",
|
|
3801
3778
|
example=[
|
|
@@ -3829,6 +3806,49 @@ def schema_constraint(cfg):
|
|
|
3829
3806
|
* ``MZ_MX_R270``, ``MZ_MY_R90``: Reverse metal stack, flip on x-axis and rotate 270 deg ccw
|
|
3830
3807
|
""")
|
|
3831
3808
|
|
|
3809
|
+
scparam(cfg, ['constraint', 'component', inst, 'substrate'],
|
|
3810
|
+
sctype='str',
|
|
3811
|
+
pernode='optional',
|
|
3812
|
+
shorthelp="Constraint: component substrate",
|
|
3813
|
+
switch="-constraint_component_substrate 'inst <str>'",
|
|
3814
|
+
example=[
|
|
3815
|
+
"cli: -constraint_component_substrate 'i0 pcb0'",
|
|
3816
|
+
"api: chip.set('constraint', 'component', 'i0', 'substrate', 'pcb0')"],
|
|
3817
|
+
schelp="""
|
|
3818
|
+
Substrates are supporting material that components are placed upon.
|
|
3819
|
+
List of supported substrates includes (but not limited to):
|
|
3820
|
+
wafers, dies, panels, PCBs.""")
|
|
3821
|
+
|
|
3822
|
+
scparam(cfg, ['constraint', 'component', inst, 'side'],
|
|
3823
|
+
sctype='enum',
|
|
3824
|
+
enum=['left', 'right', 'front', 'back', 'top', 'bottom'],
|
|
3825
|
+
pernode='optional',
|
|
3826
|
+
shorthelp="Constraint: component side",
|
|
3827
|
+
switch="-constraint_component_side 'inst <str>'",
|
|
3828
|
+
example=[
|
|
3829
|
+
"cli: -constraint_component_side 'i0 top'",
|
|
3830
|
+
"api: chip.set('constraint', 'component', 'i0', 'side', 'top')"],
|
|
3831
|
+
schelp="""
|
|
3832
|
+
Side of the substrate where the component should be placed. The `side`
|
|
3833
|
+
definitions are with respect to a viewer looking sideways at an object.
|
|
3834
|
+
Top is towards the sky, front is the side closest to the viewer, and
|
|
3835
|
+
right is right. The maximum number of sides per substrate is six""")
|
|
3836
|
+
|
|
3837
|
+
scparam(cfg, ['constraint', 'component', inst, 'zheight'],
|
|
3838
|
+
sctype='float',
|
|
3839
|
+
pernode='optional',
|
|
3840
|
+
unit='um',
|
|
3841
|
+
shorthelp="Constraint: component placement zheight",
|
|
3842
|
+
switch="-constraint_component_zheight 'inst <float>'",
|
|
3843
|
+
example=[
|
|
3844
|
+
"cli: -constraint_component_zheight 'i0 100.0'",
|
|
3845
|
+
"api: chip.set('constraint', 'component', 'i0', 'zheight', 100.0)"],
|
|
3846
|
+
schelp="""
|
|
3847
|
+
Height above the substrate for component placement. The space
|
|
3848
|
+
between the component and substrate is occupied by material,
|
|
3849
|
+
supporting scaffolding, and electrical connections (eg. bumps,
|
|
3850
|
+
vias, pillars).""")
|
|
3851
|
+
|
|
3832
3852
|
# PINS
|
|
3833
3853
|
name = 'default'
|
|
3834
3854
|
scparam(cfg, ['constraint', 'pin', name, 'placement'],
|
|
@@ -3848,6 +3868,44 @@ def schema_constraint(cfg):
|
|
|
3848
3868
|
may adjust sizes to meet competing goals such as manufacturing design
|
|
3849
3869
|
rules and grid placement guidelines.""")
|
|
3850
3870
|
|
|
3871
|
+
metrics = {'width': ['width', 1.0],
|
|
3872
|
+
'length': ['length', 1.0],
|
|
3873
|
+
'height': ['height', 1.0]
|
|
3874
|
+
}
|
|
3875
|
+
|
|
3876
|
+
for i, v in metrics.items():
|
|
3877
|
+
scparam(cfg, ['constraint', 'pin', name, i],
|
|
3878
|
+
sctype='float',
|
|
3879
|
+
unit='um',
|
|
3880
|
+
pernode='optional',
|
|
3881
|
+
shorthelp=f"Constraint: pin {i}",
|
|
3882
|
+
switch=f"-constraint_pin_{i} 'name <float>'",
|
|
3883
|
+
example=[
|
|
3884
|
+
f"cli: -constraint_pin_{i} 'nreset {v[1]}'",
|
|
3885
|
+
f"api: chip.set('constraint', 'pin', 'nreset', {i}, {v[1]})"],
|
|
3886
|
+
schelp=f"""
|
|
3887
|
+
Pin {i} constraint. This parameter represents goal/intent, not an exact
|
|
3888
|
+
specification. The layout system may adjust sizes to meet
|
|
3889
|
+
competing goals such as manufacturing design rules and grid placement
|
|
3890
|
+
guidelines.""")
|
|
3891
|
+
|
|
3892
|
+
scparam(cfg, ['constraint', 'pin', name, 'shape'],
|
|
3893
|
+
sctype='enum',
|
|
3894
|
+
enum=['circle', 'rectangle', 'square',
|
|
3895
|
+
'hexagon', 'octagon', 'oval', 'pill', 'polygon'],
|
|
3896
|
+
pernode='optional',
|
|
3897
|
+
shorthelp="Constraint: pin shape",
|
|
3898
|
+
switch="-constraint_pin_shape 'name <str>'",
|
|
3899
|
+
example=[
|
|
3900
|
+
"cli: -constraint_pin_shape 'nreset circle'",
|
|
3901
|
+
"api: chip.set('constraint', 'pin', 'nreset', 'shape', 'circle')"],
|
|
3902
|
+
schelp="""
|
|
3903
|
+
Pin shape constraint specified on a per pin basis. In 3D design systems,
|
|
3904
|
+
the pin shape represents the cross section of the pin in the direction
|
|
3905
|
+
orthogonal to the signal flow direction. The 'pill' (aka stadium) shape,
|
|
3906
|
+
is rectangle with semicircles at a pair of opposite sides. The other
|
|
3907
|
+
pin shapes represent common geometric shape definitions.""")
|
|
3908
|
+
|
|
3851
3909
|
scparam(cfg, ['constraint', 'pin', name, 'layer'],
|
|
3852
3910
|
sctype='str',
|
|
3853
3911
|
pernode='optional',
|
|
@@ -3903,8 +3961,8 @@ def schema_constraint(cfg):
|
|
|
3903
3961
|
"cli: -constraint_net_maxlength 'nreset 1000'",
|
|
3904
3962
|
"api: chip.set('constraint', 'net', 'nreset', 'maxlength', '1000')"],
|
|
3905
3963
|
schelp="""
|
|
3906
|
-
Maximum total length of a net
|
|
3907
|
-
|
|
3964
|
+
Maximum total length of a net. Wildcards ('*') can be used for
|
|
3965
|
+
net names.""")
|
|
3908
3966
|
|
|
3909
3967
|
scparam(cfg, ['constraint', 'net', name, 'maxresistance'],
|
|
3910
3968
|
sctype='float',
|
|
@@ -3930,9 +3988,8 @@ def schema_constraint(cfg):
|
|
|
3930
3988
|
"api: chip.set('constraint', 'net', 'nreset', 'ndr', (0.4, 0.4))"],
|
|
3931
3989
|
schelp="""
|
|
3932
3990
|
Definitions of non-default routing rule specified on a per
|
|
3933
|
-
net basis. Constraints are entered as a (width, space) tuples
|
|
3934
|
-
|
|
3935
|
-
for net names.""")
|
|
3991
|
+
net basis. Constraints are entered as a (width, space) tuples.
|
|
3992
|
+
Wildcards ('*') can be used for net names.""")
|
|
3936
3993
|
|
|
3937
3994
|
scparam(cfg, ['constraint', 'net', name, 'minlayer'],
|
|
3938
3995
|
sctype='str',
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from siliconcompiler.tools import bambu
|
|
2
|
-
from siliconcompiler.tools
|
|
2
|
+
from siliconcompiler.tools import bluespec
|
|
3
3
|
from siliconcompiler.tools.builtin import builtin
|
|
4
4
|
from siliconcompiler.tools.chisel import chisel
|
|
5
5
|
from siliconcompiler.tools.execute import execute
|
|
6
6
|
from siliconcompiler.tools.genfasm import genfasm
|
|
7
7
|
from siliconcompiler.tools.ghdl import ghdl
|
|
8
8
|
from siliconcompiler.tools import gtkwave
|
|
9
|
+
from siliconcompiler.tools import graphviz
|
|
9
10
|
from siliconcompiler.tools.icarus import icarus
|
|
10
11
|
from siliconcompiler.tools.icepack import icepack
|
|
11
12
|
from siliconcompiler.tools.klayout import klayout
|
|
@@ -39,6 +40,7 @@ def get_tools():
|
|
|
39
40
|
execute,
|
|
40
41
|
genfasm,
|
|
41
42
|
ghdl,
|
|
43
|
+
graphviz,
|
|
42
44
|
gtkwave,
|
|
43
45
|
icarus,
|
|
44
46
|
icepack,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Bluespec is a high-level hardware description language. It has a variety of
|
|
3
|
+
advanced features including a powerful type system that can prevent errors
|
|
4
|
+
prior to synthesis time, and its most distinguishing feature, Guarded Atomic
|
|
5
|
+
Actions, allow you to define hardware components in a modular manner based
|
|
6
|
+
on their invariants, and let the compiler pick a scheduler.
|
|
7
|
+
|
|
8
|
+
Documentation: https://github.com/B-Lang-org/bsc#documentation
|
|
9
|
+
|
|
10
|
+
Sources: https://github.com/B-Lang-org/bsc
|
|
11
|
+
|
|
12
|
+
Installation: https://github.com/B-Lang-org/bsc#download
|
|
13
|
+
'''
|
|
14
|
+
|
|
15
|
+
from siliconcompiler.tools.bluespec import convert
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
####################################################################
|
|
19
|
+
# Make Docs
|
|
20
|
+
####################################################################
|
|
21
|
+
def make_docs(chip):
|
|
22
|
+
convert.setup(chip)
|
|
23
|
+
return chip
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
################################
|
|
27
|
+
# Setup Tool (pre executable)
|
|
28
|
+
################################
|
|
29
|
+
def parse_version(stdout):
|
|
30
|
+
# Examples:
|
|
31
|
+
# Bluespec Compiler, version 2021.12.1-27-g9a7d5e05 (build 9a7d5e05)
|
|
32
|
+
# Bluespec Compiler, version 2021.07 (build 4cac6eba)
|
|
33
|
+
|
|
34
|
+
long_version = stdout.split()[3]
|
|
35
|
+
return long_version.split('-')[0]
|
|
@@ -8,6 +8,7 @@ from siliconcompiler import sc_open
|
|
|
8
8
|
|
|
9
9
|
# Directory inside step/index dir to store bsc intermediate results.
|
|
10
10
|
VLOG_DIR = 'verilog'
|
|
11
|
+
BSC_DIR = 'bluespec'
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def setup(chip):
|
|
@@ -39,6 +40,7 @@ def setup(chip):
|
|
|
39
40
|
|
|
40
41
|
# Input/Output requirements
|
|
41
42
|
chip.add('tool', tool, 'task', task, 'output', chip.top() + '.v', step=step, index=index)
|
|
43
|
+
chip.add('tool', tool, 'task', task, 'output', chip.top() + '.dot', step=step, index=index)
|
|
42
44
|
|
|
43
45
|
# Schema requirements
|
|
44
46
|
add_require_input(chip, 'input', 'hll', 'bsv')
|
|
@@ -50,9 +52,10 @@ def setup(chip):
|
|
|
50
52
|
################################
|
|
51
53
|
def pre_process(chip):
|
|
52
54
|
# bsc requires its output directory exists before being called.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
for path in (VLOG_DIR, BSC_DIR):
|
|
56
|
+
if os.path.isdir(path):
|
|
57
|
+
shutil.rmtree(path)
|
|
58
|
+
os.makedirs(path)
|
|
56
59
|
|
|
57
60
|
|
|
58
61
|
################################
|
|
@@ -68,7 +71,13 @@ def runtime_options(chip):
|
|
|
68
71
|
|
|
69
72
|
cmdlist.append('-verilog')
|
|
70
73
|
cmdlist.append(f'-vdir {VLOG_DIR}')
|
|
74
|
+
cmdlist.append(f'-bdir {BSC_DIR}')
|
|
75
|
+
cmdlist.append('-info-dir reports')
|
|
71
76
|
cmdlist.append('-u')
|
|
77
|
+
cmdlist.append('-v')
|
|
78
|
+
|
|
79
|
+
cmdlist.append('-show-module-use')
|
|
80
|
+
cmdlist.append('-sched-dot')
|
|
72
81
|
|
|
73
82
|
cmdlist.append(f'-g {chip.top(step, index)}')
|
|
74
83
|
|
|
@@ -95,10 +104,40 @@ def post_process(chip):
|
|
|
95
104
|
''' Tool specific function to run after step execution
|
|
96
105
|
'''
|
|
97
106
|
|
|
107
|
+
step = chip.get('arg', 'step')
|
|
108
|
+
index = chip.get('arg', 'index')
|
|
109
|
+
|
|
110
|
+
shutil.copyfile(f"reports/{chip.top(step, index)}_combined_full.dot",
|
|
111
|
+
f"outputs/{chip.top()}.dot")
|
|
112
|
+
|
|
113
|
+
extra_modules = set()
|
|
114
|
+
use_file = os.path.join(VLOG_DIR, f"{chip.top(step, index)}.use")
|
|
115
|
+
if os.path.exists(use_file):
|
|
116
|
+
BSC_BASE = os.path.dirname(
|
|
117
|
+
os.path.dirname(
|
|
118
|
+
chip.get('record', 'toolpath', step=step, index=index)))
|
|
119
|
+
BSC_LIB = os.path.join(BSC_BASE, "lib", "Verilog")
|
|
120
|
+
|
|
121
|
+
with sc_open(use_file) as f:
|
|
122
|
+
for module in f:
|
|
123
|
+
module = module.strip()
|
|
124
|
+
mod_path = os.path.join(BSC_LIB, f"{module}.v")
|
|
125
|
+
if os.path.exists(mod_path):
|
|
126
|
+
extra_modules.add(mod_path)
|
|
127
|
+
else:
|
|
128
|
+
chip.logger.warn(f"Unable to find module {module} source files at: {BSC_LIB}")
|
|
129
|
+
|
|
98
130
|
# bsc outputs each compiled module to its own Verilog file, so we
|
|
99
131
|
# concatenate them all to create a pickled output we can pass along.
|
|
100
132
|
design = chip.top()
|
|
101
133
|
with open(os.path.join('outputs', f'{design}.v'), 'w') as pickled_vlog:
|
|
102
134
|
for src in os.listdir(VLOG_DIR):
|
|
103
|
-
|
|
104
|
-
|
|
135
|
+
if src.endswith(".v"):
|
|
136
|
+
with sc_open(os.path.join(VLOG_DIR, src)) as vlog_mod:
|
|
137
|
+
pickled_vlog.write(vlog_mod.read())
|
|
138
|
+
|
|
139
|
+
pickled_vlog.write("\n")
|
|
140
|
+
pickled_vlog.write("// Bluespec imports\n\n")
|
|
141
|
+
for vfile in extra_modules:
|
|
142
|
+
with sc_open(os.path.join(BSC_LIB, vfile)) as vlog_mod:
|
|
143
|
+
pickled_vlog.write(vlog_mod.read() + "\n")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Graphviz is open source graph visualization software.
|
|
3
|
+
Graph visualization is a way of representing structural information as diagrams
|
|
4
|
+
of abstract graphs and networks.
|
|
5
|
+
It has important applications in networking, bioinformatics, software engineering,
|
|
6
|
+
database and web design, machine learning, and in visual interfaces for other
|
|
7
|
+
technical domains.
|
|
8
|
+
'''
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def make_docs(chip):
|
|
12
|
+
return chip
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import graphviz
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from siliconcompiler import sc_open
|
|
5
|
+
from siliconcompiler.tools._common import get_tool_task
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def setup(chip):
|
|
9
|
+
'''
|
|
10
|
+
Generate a screenshot of a dot file
|
|
11
|
+
'''
|
|
12
|
+
|
|
13
|
+
step = chip.get('arg', 'step')
|
|
14
|
+
index = chip.get('arg', 'index')
|
|
15
|
+
tool, task = get_tool_task(chip, step, index)
|
|
16
|
+
|
|
17
|
+
chip.set('tool', tool, 'task', task, 'threads', 1, step=step, index=index)
|
|
18
|
+
|
|
19
|
+
chip.add('tool', tool, 'task', task, 'output', chip.top() + '.png', step=step, index=index)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run(chip):
|
|
23
|
+
step = chip.get('arg', 'step')
|
|
24
|
+
index = chip.get('arg', 'index')
|
|
25
|
+
tool, task = get_tool_task(chip, step, index)
|
|
26
|
+
|
|
27
|
+
if os.path.exists(f'inputs/{chip.top()}.dot'):
|
|
28
|
+
file = f'inputs/{chip.top()}.dot'
|
|
29
|
+
elif os.path.exists(f'inputs/{chip.top()}.xdot'):
|
|
30
|
+
file = f'inputs/{chip.top()}.xdot'
|
|
31
|
+
elif chip.valid('tool', tool, 'task', task, 'var', 'show_filepath') and \
|
|
32
|
+
chip.get('tool', tool, 'task', task, 'var', 'show_filepath', step=step, index=index):
|
|
33
|
+
file = chip.get('tool', tool, 'task', task, 'var', 'show_filepath',
|
|
34
|
+
step=step, index=index)[0]
|
|
35
|
+
else:
|
|
36
|
+
file = chip.find_files('input', 'image', 'dot', step=step, index=index)[0]
|
|
37
|
+
|
|
38
|
+
with sc_open(file) as dot:
|
|
39
|
+
dot_content = dot.read()
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
dot = graphviz.Source(dot_content, format="png")
|
|
43
|
+
dot.render(filename=f"outputs/{chip.top()}", cleanup=True)
|
|
44
|
+
pass
|
|
45
|
+
except graphviz.ExecutableNotFound:
|
|
46
|
+
return 1
|
|
47
|
+
|
|
48
|
+
return 0
|