siliconcompiler 0.29.3__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.
Files changed (60) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc.py +1 -1
  3. siliconcompiler/apps/sc_install.py +46 -3
  4. siliconcompiler/core.py +15 -4
  5. siliconcompiler/remote/client.py +3 -0
  6. siliconcompiler/scheduler/__init__.py +9 -3
  7. siliconcompiler/schema/schema_cfg.py +149 -92
  8. siliconcompiler/tools/__init__.py +4 -2
  9. siliconcompiler/tools/_common/asic.py +3 -0
  10. siliconcompiler/tools/_common/asic_clock.py +101 -0
  11. siliconcompiler/tools/bambu/__init__.py +32 -0
  12. siliconcompiler/tools/bambu/convert.py +93 -12
  13. siliconcompiler/tools/bluespec/__init__.py +35 -0
  14. siliconcompiler/tools/bluespec/convert.py +44 -5
  15. siliconcompiler/tools/graphviz/__init__.py +12 -0
  16. siliconcompiler/tools/graphviz/screenshot.py +48 -0
  17. siliconcompiler/tools/graphviz/show.py +20 -0
  18. siliconcompiler/tools/openroad/_apr.py +17 -0
  19. siliconcompiler/tools/openroad/fillmetal_insertion.py +0 -1
  20. siliconcompiler/tools/openroad/init_floorplan.py +7 -1
  21. siliconcompiler/tools/openroad/macro_placement.py +10 -2
  22. siliconcompiler/tools/openroad/pin_placement.py +0 -1
  23. siliconcompiler/tools/openroad/power_grid.py +6 -0
  24. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -2
  25. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +2 -0
  26. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +2 -0
  27. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +15 -5
  28. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +1 -0
  29. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +9 -1
  30. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +54 -0
  31. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +24 -0
  32. siliconcompiler/tools/openroad/scripts/common/procs.tcl +28 -6
  33. siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +1 -0
  34. siliconcompiler/tools/openroad/scripts/common/reports.tcl +10 -16
  35. siliconcompiler/tools/slang/__init__.py +1 -0
  36. siliconcompiler/tools/verilator/verilator.py +1 -0
  37. siliconcompiler/tools/yosys/__init__.py +26 -23
  38. siliconcompiler/tools/yosys/procs.tcl +17 -0
  39. siliconcompiler/tools/yosys/syn_asic.py +12 -65
  40. siliconcompiler/tools/yosys/syn_asic.tcl +6 -51
  41. siliconcompiler/toolscripts/_tools.json +5 -5
  42. siliconcompiler/toolscripts/rhel8/install-yosys.sh +1 -1
  43. siliconcompiler/toolscripts/rhel9/install-openroad.sh +34 -0
  44. siliconcompiler/toolscripts/rhel9/install-yosys.sh +1 -1
  45. siliconcompiler/toolscripts/ubuntu20/install-openroad.sh +1 -1
  46. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +1 -1
  47. siliconcompiler/toolscripts/ubuntu22/install-openroad.sh +1 -1
  48. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +1 -1
  49. siliconcompiler/toolscripts/ubuntu24/install-openroad.sh +1 -1
  50. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +1 -1
  51. siliconcompiler/utils/__init__.py +13 -0
  52. siliconcompiler/utils/showtools.py +7 -0
  53. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/METADATA +9 -9
  54. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/RECORD +58 -55
  55. siliconcompiler/tools/bambu/bambu.py +0 -32
  56. siliconcompiler/tools/bluespec/bluespec.py +0 -40
  57. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/LICENSE +0 -0
  58. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/WHEEL +0 -0
  59. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/entry_points.txt +0 -0
  60. {siliconcompiler-0.29.3.dist-info → siliconcompiler-0.30.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # Version number following semver standard.
2
- version = '0.29.3'
2
+ version = '0.30.0'
3
3
 
4
4
  # Default server address for remote runs, if unspecified.
5
5
  default_server = 'https://server.siliconcompiler.com'
@@ -95,7 +95,7 @@ def main():
95
95
 
96
96
  try:
97
97
  # Run flow
98
- chip.run()
98
+ chip.run(raise_exception=True)
99
99
 
100
100
  # Print Job Summary
101
101
  chip.summary()
@@ -73,16 +73,18 @@ def show_tool(tool, script):
73
73
  def _get_os_name():
74
74
  machine_info = _get_machine_info()
75
75
  system = machine_info.get('system', "").lower()
76
- distro = machine_info.get('distro', "").lower()
77
- osversion = machine_info.get('osversion', "").lower()
78
76
  if system == 'linux':
77
+ distro = machine_info.get('distro', "").lower()
79
78
  if distro == 'ubuntu':
79
+ osversion = machine_info.get('osversion', "").lower()
80
80
  version, _ = osversion.split('.')
81
81
  return f"{distro}{version}"
82
82
  elif distro == 'rocky':
83
+ osversion = machine_info.get('osversion', "").lower()
83
84
  version, _ = osversion.split('.')
84
85
  return f"rhel{version}"
85
86
  elif distro == 'rhel':
87
+ osversion = machine_info.get('osversion', "").lower()
86
88
  version, _ = osversion.split('.')
87
89
  return f"rhel{version}"
88
90
  return None
@@ -134,6 +136,10 @@ def _recommended_tool_groups(tools):
134
136
  for group, group_tools in groups.items():
135
137
  if all([tool in tools for tool in group_tools]):
136
138
  filter_groups[group] = group_tools
139
+ else:
140
+ missing = sorted([tool for tool in group_tools if tool not in tools])
141
+ filter_groups[group] = f"{group} group is not available for {_get_os_name()} " \
142
+ f"due to lack of support for the following tools: {', '.join(missing)}"
137
143
  return filter_groups
138
144
 
139
145
 
@@ -172,6 +178,11 @@ To system debugging information (this should only be used to debug):
172
178
 
173
179
  tools = _get_tools_list()
174
180
 
181
+ if _get_os_name() is None:
182
+ print("Unsupported operating system", file=sys.stderr)
183
+ print_machine_info()
184
+ return 1
185
+
175
186
  tool_choices = ChoiceOptional(tools.keys())
176
187
  parser.add_argument(
177
188
  "tool",
@@ -220,7 +231,11 @@ To system debugging information (this should only be used to debug):
220
231
  args.tool = list(args.tool)
221
232
  if args.group:
222
233
  for group in args.group:
223
- args.tool.extend(tool_groups[group])
234
+ if isinstance(tool_groups[group], str):
235
+ print(tool_groups[group], file=sys.stderr)
236
+ return 1
237
+ else:
238
+ args.tool.extend(tool_groups[group])
224
239
 
225
240
  tools_handled = set()
226
241
  for tool in args.tool:
@@ -233,6 +248,34 @@ To system debugging information (this should only be used to debug):
233
248
  if not install_tool(tool, tools[tool], args.build_dir, args.prefix):
234
249
  return 1
235
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
+
236
279
  return 0
237
280
 
238
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
- sc_runner(self)
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)
@@ -477,6 +477,9 @@ service, provided by SiliconCompiler, is not intended to process proprietary IP.
477
477
  # Flush file to ensure everything is written
478
478
  upload_file.flush()
479
479
 
480
+ # We no longer need the collected files
481
+ shutil.rmtree(self.__chip._getcollectdir(jobname=self.__chip.get('option', 'jobname')))
482
+
480
483
  if 'pre_upload' in remote_status:
481
484
  self.__logger.info(remote_status['pre_upload']['message'])
482
485
  time.sleep(remote_status['pre_upload']['delay'])
@@ -1628,8 +1628,14 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
1628
1628
  # Update dashboard if the manifest changed
1629
1629
  chip._dash.update_manifest()
1630
1630
 
1631
- # TODO: exponential back-off with max?
1632
- time.sleep(0.1)
1631
+ if len(running_nodes) == 1:
1632
+ # if there is only one node running, just join the thread
1633
+ running_node = list(running_nodes.keys())[0]
1634
+ processes[running_node]["proc"].join()
1635
+ elif len(running_nodes) > 1:
1636
+ # if there are more than 1, join the first with a timeout
1637
+ running_node = list(running_nodes.keys())[0]
1638
+ processes[running_node]["proc"].join(timeout=0.1)
1633
1639
 
1634
1640
 
1635
1641
  def _process_completed_nodes(chip, processes, running_nodes):
@@ -1949,7 +1955,7 @@ def check_node_inputs(chip, step, index):
1949
1955
  step=check_step, index=check_index)
1950
1956
 
1951
1957
  if check_hash != prev_hash:
1952
- print_warning(key)
1958
+ print_warning(key, "file hash")
1953
1959
  return False
1954
1960
  else:
1955
1961
  # check timestamps on current files
@@ -10,7 +10,7 @@ try:
10
10
  except ImportError:
11
11
  from siliconcompiler.schema.utils import trim
12
12
 
13
- SCHEMA_VERSION = '0.48.6'
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 specified on a named package basis.""")
1263
+ schelp="""Package type.""")
1264
1264
 
1265
1265
  scparam(cfg, ['datasheet', 'package', name, 'footprint'],
1266
- sctype='str',
1266
+ sctype='[file]',
1267
1267
  shorthelp="Datasheet: package footprint",
1268
- switch="-datasheet_package_footprint 'name <str>'",
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: -datasheet_package_footprint 'abcd soic8'",
1271
- "api: chip.set('datasheet', 'package', 'abcd', 'footprint', 'soic8')"],
1272
- schelp="""Package footprint name. The name of the footprint can be a standard
1273
- footprint name or a reference designator from a footprint library.""")
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 package outline for documentation purposes.
1283
- Common file formats include PDF, DOC, SVG, and PNG.""")
1300
+ schelp="""Mechanical drawing for documentation purposes.
1301
+ Supported file formats include: PDF, DOC, SVG, and PNG.""")
1284
1302
 
1285
- scparam(cfg, ['datasheet', 'package', name, 'pincount'],
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
- 'pitch': ['pitch', (800, 850, 900), 'um']
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"""Datasheet: package {v[0]}. Values are tuples of
1319
+ schelp=f"""Package {v[0]}. Values are tuples of
1326
1320
  (min, nominal, max).""")
1327
1321
 
1328
- # pinout diagram
1329
- pinnumber = 'default'
1330
- scparam(cfg, ['datasheet', 'package', name, 'pin', pinnumber, 'shape'],
1331
- sctype='enum',
1332
- enum=['circle', 'rectangle', 'square', 'octagon'],
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: -datasheet_package_pin_shape 'abcd B1 circle'",
1337
- "api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', 'shape', 'circle')"],
1338
- schelp="""Datasheet: package pin shape specified on a per package
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
- for i, v in metrics.items():
1346
- scparam(cfg, ['datasheet', 'package', name, 'pin', pinnumber, i],
1347
- unit=v[2],
1348
- sctype='(float,float,float)',
1349
- shorthelp=f"Datasheet: package pin {v[0]}",
1350
- switch=f"-datasheet_package_pin_{i} 'name pinnumber <(float,float,float)>'",
1351
- example=[
1352
- f"cli: -datasheet_package_pin_{i} 'abcd B1 {v[1]}'",
1353
- f"api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', '{i}', {v[1]}"],
1354
- schelp=f"""Datsheet: {v[0]} specified on a per package and per pin number
1355
- basis. Values are tuples of (min, nominal, max).""")
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
- scparam(cfg, ['datasheet', 'package', name, 'pin', pinnumber, 'loc'],
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 pin location",
1361
- switch="-datasheet_package_pin_loc 'name pinnumber <(float,float)>'",
1349
+ shorthelp="Datasheet: package anchor",
1350
+ switch="-datasheet_package_anchor 'name <(float,float)>'",
1362
1351
  example=[
1363
- "cli: -datasheet_package_pin_loc 'abcd B1 (500,500)'",
1364
- "api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', 'loc', (500,500)"],
1365
- schelp="""Datsheet: Package pin location specified as an (x,y) tuple on a per
1366
- package and per pin number basis. Locations specify the center of the pin with
1367
- respect to the center of the package.""")
1368
-
1369
- scparam(cfg, ['datasheet', 'package', name, 'pin', pinnumber, 'name'],
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 represented in microns.""")
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, specified in microns.
3907
- Wildcards ('*') can be used for net names.""")
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
- specified in microns. Wildcards ('*') can be used
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
- from siliconcompiler.tools.bambu import bambu
2
- from siliconcompiler.tools.bluespec import bluespec
1
+ from siliconcompiler.tools import bambu
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,
@@ -194,6 +194,9 @@ def set_tool_task_lib_var(chip,
194
194
 
195
195
  values.update(chip.get(*lib_key, step=get_step, index=get_index))
196
196
 
197
+ if default_value and not check_value(values):
198
+ values = default_value
199
+
197
200
  if check_value(values):
198
201
  chip.set('tool', tool, 'task', task, 'var', param_key, values,
199
202
  step=step, index=index, clobber=False)