siliconcompiler 0.30.0__py3-none-any.whl → 0.31.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 (69) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/sc_install.py +7 -3
  3. siliconcompiler/apps/sc_remote.py +1 -3
  4. siliconcompiler/core.py +23 -8
  5. siliconcompiler/flowgraph.py +11 -23
  6. siliconcompiler/package.py +1 -1
  7. siliconcompiler/remote/schema.py +9 -8
  8. siliconcompiler/report/report.py +4 -3
  9. siliconcompiler/scheduler/__init__.py +109 -104
  10. siliconcompiler/scheduler/docker_runner.py +1 -1
  11. siliconcompiler/scheduler/send_messages.py +1 -1
  12. siliconcompiler/schema/schema_cfg.py +367 -357
  13. siliconcompiler/schema/schema_obj.py +32 -18
  14. siliconcompiler/schema/utils.py +19 -0
  15. siliconcompiler/sphinx_ext/schemagen.py +3 -1
  16. siliconcompiler/templates/replay/replay.sh.j2 +92 -0
  17. siliconcompiler/tools/_common/__init__.py +8 -2
  18. siliconcompiler/tools/_common/asic.py +1 -1
  19. siliconcompiler/tools/klayout/export.py +5 -0
  20. siliconcompiler/tools/klayout/klayout.py +18 -1
  21. siliconcompiler/tools/klayout/klayout_export.py +4 -1
  22. siliconcompiler/tools/klayout/klayout_operations.py +5 -2
  23. siliconcompiler/tools/klayout/klayout_utils.py +23 -0
  24. siliconcompiler/tools/klayout/operations.py +5 -0
  25. siliconcompiler/tools/magic/magic.py +1 -1
  26. siliconcompiler/tools/openroad/_apr.py +14 -3
  27. siliconcompiler/tools/openroad/antenna_repair.py +2 -1
  28. siliconcompiler/tools/openroad/clock_tree_synthesis.py +2 -1
  29. siliconcompiler/tools/openroad/detailed_placement.py +2 -1
  30. siliconcompiler/tools/openroad/detailed_route.py +8 -0
  31. siliconcompiler/tools/openroad/fillercell_insertion.py +2 -1
  32. siliconcompiler/tools/openroad/global_placement.py +2 -1
  33. siliconcompiler/tools/openroad/pin_placement.py +2 -1
  34. siliconcompiler/tools/openroad/repair_design.py +2 -1
  35. siliconcompiler/tools/openroad/repair_timing.py +2 -1
  36. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +6 -0
  37. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +1 -0
  38. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +8 -0
  39. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +1 -0
  40. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +2 -0
  41. siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +5 -0
  42. siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +1 -0
  43. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +1 -0
  44. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +3 -0
  45. siliconcompiler/tools/openroad/scripts/common/procs.tcl +29 -12
  46. siliconcompiler/tools/openroad/scripts/common/reports.tcl +15 -0
  47. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +28 -0
  48. siliconcompiler/tools/yosys/__init__.py +7 -0
  49. siliconcompiler/tools/yosys/sc_syn.tcl +33 -24
  50. siliconcompiler/tools/yosys/syn_asic.py +27 -0
  51. siliconcompiler/tools/yosys/syn_asic.tcl +27 -0
  52. siliconcompiler/toolscripts/_tools.json +14 -2
  53. siliconcompiler/toolscripts/rhel8/install-yosys-moosic.sh +17 -0
  54. siliconcompiler/toolscripts/rhel8/install-yosys-slang.sh +22 -0
  55. siliconcompiler/toolscripts/rhel9/install-yosys-moosic.sh +17 -0
  56. siliconcompiler/toolscripts/rhel9/install-yosys-slang.sh +22 -0
  57. siliconcompiler/toolscripts/ubuntu20/install-yosys-moosic.sh +17 -0
  58. siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +22 -0
  59. siliconcompiler/toolscripts/ubuntu22/install-yosys-moosic.sh +17 -0
  60. siliconcompiler/toolscripts/ubuntu22/install-yosys-slang.sh +22 -0
  61. siliconcompiler/toolscripts/ubuntu24/install-yosys-moosic.sh +17 -0
  62. siliconcompiler/toolscripts/ubuntu24/install-yosys-slang.sh +22 -0
  63. siliconcompiler/utils/__init__.py +33 -5
  64. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/METADATA +7 -7
  65. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/RECORD +69 -58
  66. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/WHEEL +1 -1
  67. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/LICENSE +0 -0
  68. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/entry_points.txt +0 -0
  69. {siliconcompiler-0.30.0.dist-info → siliconcompiler-0.31.0.dist-info}/top_level.txt +0 -0
@@ -6,23 +6,22 @@ import json
6
6
  # (such as KLayout) directly importing the schema package. However, the fallback
7
7
  # allows running this script directly to generate defaults.json.
8
8
  try:
9
- from .utils import trim
9
+ from .utils import trim, Scope, PerNode
10
10
  except ImportError:
11
- from siliconcompiler.schema.utils import trim
11
+ from siliconcompiler.schema.utils import trim, Scope, PerNode
12
+
13
+ SCHEMA_VERSION = '0.50.0'
12
14
 
13
- SCHEMA_VERSION = '0.49.0'
14
15
 
15
16
  #############################################################################
16
17
  # PARAM DEFINITION
17
18
  #############################################################################
18
-
19
-
20
19
  def scparam(cfg,
21
20
  keypath,
22
21
  sctype=None,
23
22
  require=False,
24
23
  defvalue=None,
25
- scope='job',
24
+ scope=Scope.JOB,
26
25
  copy=False,
27
26
  lock=False,
28
27
  hashalgo='sha256',
@@ -34,7 +33,7 @@ def scparam(cfg,
34
33
  example=None,
35
34
  schelp=None,
36
35
  enum=None,
37
- pernode='never'):
36
+ pernode=PerNode.NEVER):
38
37
 
39
38
  # 1. descend keypath until done
40
39
  # 2. create key if missing
@@ -79,19 +78,19 @@ def scparam(cfg,
79
78
  defvalue = []
80
79
 
81
80
  # mandatory for all
82
- cfg['type'] = sctype
83
- cfg['scope'] = scope
84
- cfg['require'] = require
85
- cfg['lock'] = lock
81
+ cfg['type'] = str(sctype)
82
+ cfg['scope'] = Scope(scope).value
83
+ cfg['require'] = bool(require)
84
+ cfg['lock'] = bool(lock)
86
85
  if switch and not isinstance(switch, list):
87
86
  switch = [switch]
88
- cfg['switch'] = switch
89
- cfg['shorthelp'] = shorthelp
90
- cfg['example'] = example
91
- cfg['help'] = schelp
92
- cfg['notes'] = notes
87
+ cfg['switch'] = [str(s) for s in switch] if switch else None
88
+ cfg['shorthelp'] = str(shorthelp) if shorthelp else None
89
+ cfg['example'] = [str(e) for e in example] if example else None
90
+ cfg['help'] = str(schelp) if schelp else None
91
+ cfg['notes'] = str(notes) if notes else None
93
92
  # never, optional, required
94
- cfg['pernode'] = pernode
93
+ cfg['pernode'] = PerNode(pernode).value
95
94
  cfg['node'] = {}
96
95
  cfg['node']['default'] = {}
97
96
  cfg['node']['default']['default'] = {}
@@ -99,26 +98,22 @@ def scparam(cfg,
99
98
  cfg['node']['default']['default']['signature'] = signature
100
99
 
101
100
  if enum is not None:
102
- cfg['enum'] = enum
101
+ cfg['enum'] = [str(e) for e in enum]
103
102
 
104
103
  # unit for floats/ints
105
104
  if unit is not None:
106
- cfg['unit'] = unit
105
+ cfg['unit'] = str(unit)
106
+
107
+ if 'dir' in sctype or 'file' in sctype:
108
+ cfg['hashalgo'] = str(hashalgo)
109
+ cfg['copy'] = bool(copy)
110
+ cfg['node']['default']['default']['filehash'] = []
111
+ cfg['node']['default']['default']['package'] = []
107
112
 
108
113
  # file only values
109
114
  if 'file' in sctype:
110
- cfg['hashalgo'] = hashalgo
111
- cfg['copy'] = copy
112
115
  cfg['node']['default']['default']['date'] = []
113
116
  cfg['node']['default']['default']['author'] = []
114
- cfg['node']['default']['default']['filehash'] = []
115
- cfg['node']['default']['default']['package'] = []
116
-
117
- if 'dir' in sctype:
118
- cfg['hashalgo'] = hashalgo
119
- cfg['copy'] = copy
120
- cfg['node']['default']['default']['filehash'] = []
121
- cfg['node']['default']['default']['package'] = []
122
117
 
123
118
 
124
119
  #############################################################################
@@ -142,7 +137,7 @@ def schema_cfg():
142
137
 
143
138
  scparam(cfg, ['schemaversion'],
144
139
  sctype='str',
145
- scope='global',
140
+ scope=Scope.GLOBAL,
146
141
  defvalue=SCHEMA_VERSION,
147
142
  require=True,
148
143
  shorthelp="Schema version number",
@@ -154,7 +149,7 @@ def schema_cfg():
154
149
  # Design topmodule/entrypoint
155
150
  scparam(cfg, ['design'],
156
151
  sctype='str',
157
- scope='global',
152
+ scope=Scope.GLOBAL,
158
153
  require=True,
159
154
  shorthelp="Design top module name",
160
155
  switch="-design <str>",
@@ -173,7 +168,7 @@ def schema_cfg():
173
168
  for item, val in io.items():
174
169
  scparam(cfg, [item, fileset, filetype],
175
170
  sctype='[file]',
176
- pernode='optional',
171
+ pernode=PerNode.OPTIONAL,
177
172
  copy=val[1],
178
173
  shorthelp=f"{val[0]} files",
179
174
  switch=f"-{item} 'fileset filetype <file>'",
@@ -228,13 +223,13 @@ def schema_schematic(cfg, name='default'):
228
223
  ''' Schematic
229
224
  '''
230
225
 
231
- scparam(cfg, ['schematic', 'component', name, 'model'],
226
+ scparam(cfg, ['schematic', 'component', name, 'partname'],
232
227
  sctype='str',
233
228
  shorthelp="Schematic: component model",
234
- switch="-schematic_component_model 'name <str>'",
235
- example=["cli: -schematic_component_model 'B0 NAND2X1'",
236
- "api: chip.set('schematic', 'component', 'B0, 'model', 'NAND2X1')"],
237
- schelp="""Model of a component, specified on a per instance basis.""")
229
+ switch="-schematic_component_partname 'name <str>'",
230
+ example=["cli: -schematic_component_partname 'B0 NAND2X1'",
231
+ "api: chip.set('schematic', 'component', 'B0, 'partname', 'NAND2X1')"],
232
+ schelp="""Component part-name ("aka cell-name") specified on a per instance basis.""")
238
233
 
239
234
  scparam(cfg, ['schematic', 'pin', name, 'dir'],
240
235
  sctype='enum',
@@ -326,7 +321,7 @@ def schema_fpga(cfg):
326
321
 
327
322
  scparam(cfg, ['fpga', partname, 'file', key],
328
323
  sctype='[file]',
329
- scope='global',
324
+ scope=Scope.GLOBAL,
330
325
  shorthelp="FPGA: file",
331
326
  switch="-fpga_file 'partname key <file>'",
332
327
  example=["cli: -fpga_file 'fpga64k file archfile my_arch.xml'",
@@ -359,7 +354,7 @@ def schema_pdk(cfg, stackup='default'):
359
354
 
360
355
  scparam(cfg, ['pdk', pdkname, 'foundry'],
361
356
  sctype='str',
362
- scope='global',
357
+ scope=Scope.GLOBAL,
363
358
  shorthelp="PDK: foundry name",
364
359
  switch="-pdk_foundry 'pdkname <str>'",
365
360
  example=["cli: -pdk_foundry 'asap7 virtual'",
@@ -371,7 +366,7 @@ def schema_pdk(cfg, stackup='default'):
371
366
 
372
367
  scparam(cfg, ['pdk', pdkname, 'node'],
373
368
  sctype='float',
374
- scope='global',
369
+ scope=Scope.GLOBAL,
375
370
  unit='nm',
376
371
  shorthelp="PDK: process node",
377
372
  switch="-pdk_node 'pdkname <float>'",
@@ -386,7 +381,7 @@ def schema_pdk(cfg, stackup='default'):
386
381
 
387
382
  scparam(cfg, ['pdk', pdkname, 'version'],
388
383
  sctype='str',
389
- scope='global',
384
+ scope=Scope.GLOBAL,
390
385
  shorthelp="PDK: version",
391
386
  switch="-pdk_version 'pdkname <str>'",
392
387
  example=["cli: -pdk_version 'asap7 1.0'",
@@ -399,7 +394,7 @@ def schema_pdk(cfg, stackup='default'):
399
394
 
400
395
  scparam(cfg, ['pdk', pdkname, 'stackup'],
401
396
  sctype='[str]',
402
- scope='global',
397
+ scope=Scope.GLOBAL,
403
398
  shorthelp="PDK: metal stackups",
404
399
  switch="-pdk_stackup 'pdkname <str>'",
405
400
  example=["cli: -pdk_stackup 'asap7 2MA4MB2MC'",
@@ -419,7 +414,7 @@ def schema_pdk(cfg, stackup='default'):
419
414
 
420
415
  scparam(cfg, ['pdk', pdkname, 'minlayer', stackup],
421
416
  sctype='str',
422
- scope='global',
417
+ scope=Scope.GLOBAL,
423
418
  shorthelp="PDK: minimum routing layer",
424
419
  switch="-pdk_minlayer 'pdk stackup <str>'",
425
420
  example=[
@@ -431,7 +426,7 @@ def schema_pdk(cfg, stackup='default'):
431
426
 
432
427
  scparam(cfg, ['pdk', pdkname, 'maxlayer', stackup],
433
428
  sctype='str',
434
- scope='global',
429
+ scope=Scope.GLOBAL,
435
430
  shorthelp="PDK: maximum routing layer",
436
431
  switch="-pdk_maxlayer 'pdk stackup <str>'",
437
432
  example=[
@@ -443,7 +438,7 @@ def schema_pdk(cfg, stackup='default'):
443
438
 
444
439
  scparam(cfg, ['pdk', pdkname, 'wafersize'],
445
440
  sctype='float',
446
- scope='global',
441
+ scope=Scope.GLOBAL,
447
442
  unit='mm',
448
443
  shorthelp="PDK: wafer size",
449
444
  switch="-pdk_wafersize 'pdkname <float>'",
@@ -458,7 +453,7 @@ def schema_pdk(cfg, stackup='default'):
458
453
 
459
454
  scparam(cfg, ['pdk', pdkname, 'panelsize'],
460
455
  sctype='[(float,float)]',
461
- scope='global',
456
+ scope=Scope.GLOBAL,
462
457
  unit='mm',
463
458
  shorthelp="PDK: panel size",
464
459
  switch="-pdk_panelsize 'pdkname <(float,float)>'",
@@ -471,7 +466,7 @@ def schema_pdk(cfg, stackup='default'):
471
466
 
472
467
  scparam(cfg, ['pdk', pdkname, 'unitcost'],
473
468
  sctype='float',
474
- scope='global',
469
+ scope=Scope.GLOBAL,
475
470
  unit='USD',
476
471
  shorthelp="PDK: unit cost",
477
472
  switch="-pdk_unitcost 'pdkname <float>'",
@@ -483,7 +478,7 @@ def schema_pdk(cfg, stackup='default'):
483
478
 
484
479
  scparam(cfg, ['pdk', pdkname, 'd0'],
485
480
  sctype='float',
486
- scope='global',
481
+ scope=Scope.GLOBAL,
487
482
  shorthelp="PDK: process defect density",
488
483
  switch="-pdk_d0 'pdkname <float>'",
489
484
  example=["cli: -pdk_d0 'asap7 0.1'",
@@ -498,7 +493,7 @@ def schema_pdk(cfg, stackup='default'):
498
493
 
499
494
  scparam(cfg, ['pdk', pdkname, 'scribe'],
500
495
  sctype='(float,float)',
501
- scope='global',
496
+ scope=Scope.GLOBAL,
502
497
  unit='mm',
503
498
  shorthelp="PDK: horizontal scribe line width",
504
499
  switch="-pdk_scribe 'pdkname <(float,float)>'",
@@ -513,7 +508,7 @@ def schema_pdk(cfg, stackup='default'):
513
508
 
514
509
  scparam(cfg, ['pdk', pdkname, 'edgemargin'],
515
510
  sctype='float',
516
- scope='global',
511
+ scope=Scope.GLOBAL,
517
512
  unit='mm',
518
513
  shorthelp="PDK: wafer edge keep-out margin",
519
514
  switch="-pdk_edgemargin 'pdkname <float>'",
@@ -529,7 +524,7 @@ def schema_pdk(cfg, stackup='default'):
529
524
  simtype = 'default'
530
525
  scparam(cfg, ['pdk', pdkname, 'devmodel', tool, simtype, stackup],
531
526
  sctype='[file]',
532
- scope='global',
527
+ scope=Scope.GLOBAL,
533
528
  shorthelp="PDK: device models",
534
529
  switch="-pdk_devmodel 'pdkname tool simtype stackup <file>'",
535
530
  example=[
@@ -549,7 +544,7 @@ def schema_pdk(cfg, stackup='default'):
549
544
  corner = 'default'
550
545
  scparam(cfg, ['pdk', pdkname, 'pexmodel', tool, stackup, corner],
551
546
  sctype='[file]',
552
- scope='global',
547
+ scope=Scope.GLOBAL,
553
548
  shorthelp="PDK: parasitic TCAD models",
554
549
  switch="-pdk_pexmodel 'pdkname tool stackup corner <file>'",
555
550
  example=[
@@ -568,7 +563,7 @@ def schema_pdk(cfg, stackup='default'):
568
563
  dst = 'default'
569
564
  scparam(cfg, ['pdk', pdkname, 'layermap', tool, src, dst, stackup],
570
565
  sctype='[file]',
571
- scope='global',
566
+ scope=Scope.GLOBAL,
572
567
  shorthelp="PDK: layer map file",
573
568
  switch="-pdk_layermap 'pdkname tool src dst stackup <file>'",
574
569
  example=[
@@ -589,7 +584,7 @@ def schema_pdk(cfg, stackup='default'):
589
584
 
590
585
  scparam(cfg, ['pdk', pdkname, 'display', tool, stackup],
591
586
  sctype='[file]',
592
- scope='global',
587
+ scope=Scope.GLOBAL,
593
588
  shorthelp="PDK: display file",
594
589
  switch="-pdk_display 'pdkname tool stackup <file>'",
595
590
  example=[
@@ -604,7 +599,7 @@ def schema_pdk(cfg, stackup='default'):
604
599
  libarch = 'default'
605
600
  scparam(cfg, ['pdk', pdkname, 'aprtech', tool, stackup, libarch, filetype],
606
601
  sctype='[file]',
607
- scope='global',
602
+ scope=Scope.GLOBAL,
608
603
  shorthelp="PDK: APR technology files",
609
604
  switch="-pdk_aprtech 'pdkname tool stackup libarch filetype <file>'",
610
605
  example=[
@@ -628,7 +623,7 @@ def schema_pdk(cfg, stackup='default'):
628
623
  for item in checks:
629
624
  scparam(cfg, ['pdk', pdkname, item, 'runset', tool, stackup, name],
630
625
  sctype='[file]',
631
- scope='global',
626
+ scope=Scope.GLOBAL,
632
627
  shorthelp=f"PDK: {item.upper()} runset files",
633
628
  switch=f"-pdk_{item}_runset 'pdkname tool stackup name <file>'",
634
629
  example=[
@@ -639,7 +634,7 @@ def schema_pdk(cfg, stackup='default'):
639
634
 
640
635
  scparam(cfg, ['pdk', pdkname, item, 'waiver', tool, stackup, name],
641
636
  sctype='[file]',
642
- scope='global',
637
+ scope=Scope.GLOBAL,
643
638
  shorthelp=f"PDK: {item.upper()} waiver files",
644
639
  switch=f"-pdk_{item}_waiver 'pdkname tool stackup name <file>'",
645
640
  example=[
@@ -655,7 +650,7 @@ def schema_pdk(cfg, stackup='default'):
655
650
  key = 'default'
656
651
  scparam(cfg, ['pdk', pdkname, 'file', tool, key, stackup],
657
652
  sctype='[file]',
658
- scope='global',
653
+ scope=Scope.GLOBAL,
659
654
  shorthelp="PDK: custom file",
660
655
  switch="-pdk_file 'pdkname tool key stackup <file>'",
661
656
  example=[
@@ -668,7 +663,7 @@ def schema_pdk(cfg, stackup='default'):
668
663
 
669
664
  scparam(cfg, ['pdk', pdkname, 'dir', tool, key, stackup],
670
665
  sctype='[dir]',
671
- scope='global',
666
+ scope=Scope.GLOBAL,
672
667
  shorthelp="PDK: custom directory",
673
668
  switch="-pdk_dir 'pdkname tool key stackup <dir>'",
674
669
  example=[
@@ -682,7 +677,7 @@ def schema_pdk(cfg, stackup='default'):
682
677
 
683
678
  scparam(cfg, ['pdk', pdkname, 'var', tool, key, stackup],
684
679
  sctype='[str]',
685
- scope='global',
680
+ scope=Scope.GLOBAL,
686
681
  shorthelp="PDK: custom, variable",
687
682
  switch="-pdk_var 'pdkname tool stackup key <str>'",
688
683
  example=[
@@ -700,7 +695,7 @@ def schema_pdk(cfg, stackup='default'):
700
695
  doctype = 'default'
701
696
  scparam(cfg, ['pdk', pdkname, 'doc', doctype],
702
697
  sctype='[file]',
703
- scope='global',
698
+ scope=Scope.GLOBAL,
704
699
  shorthelp="PDK: documentation",
705
700
  switch="-pdk_doc 'pdkname doctype <file>'",
706
701
  example=["cli: -pdk_doc 'asap7 reference reference.pdf'",
@@ -713,7 +708,7 @@ def schema_pdk(cfg, stackup='default'):
713
708
  ###############################################################################
714
709
  # Datasheet ("specification/contract")
715
710
  ###############################################################################
716
- def schema_datasheet(cfg, name='default', mode='default'):
711
+ def schema_datasheet(cfg, partname='default', mode='default'):
717
712
 
718
713
  # Part type
719
714
  scparam(cfg, ['datasheet', 'type'],
@@ -901,7 +896,7 @@ def schema_datasheet(cfg, name='default', mode='default'):
901
896
  # IO
902
897
  ######################
903
898
 
904
- scparam(cfg, ['datasheet', 'io', name, 'arch'],
899
+ scparam(cfg, ['datasheet', 'io', partname, 'arch'],
905
900
  sctype='enum',
906
901
  enum=['spi', 'uart', 'i2c', 'pwm', 'qspi', 'sdio', 'can', 'jtag',
907
902
  'spdif', 'i2s',
@@ -919,7 +914,7 @@ def schema_datasheet(cfg, name='default', mode='default'):
919
914
  '10gbase-kr', '25gbase-kr', 'xfi', 'cei28g',
920
915
  'jesd204', 'cpri'],
921
916
  shorthelp="Datasheet: io standard",
922
- switch="-datasheet_io_arch 'name <str>'",
917
+ switch="-datasheet_io_arch 'partname <str>'",
923
918
  example=[
924
919
  "cli: -datasheet_io_arch 'pio spi'",
925
920
  "api: chip.set('datasheet', 'io', 'pio', 'arch', 'spi')"],
@@ -932,14 +927,14 @@ def schema_datasheet(cfg, name='default', mode='default'):
932
927
  }
933
928
 
934
929
  for i, v in metrics.items():
935
- scparam(cfg, ['datasheet', 'io', name, i],
930
+ scparam(cfg, ['datasheet', 'io', partname, i],
936
931
  unit=v[3],
937
932
  sctype=v[2],
938
933
  shorthelp=f"Datasheet: io {v[0]}",
939
- switch=f"-datasheet_io_{i} 'name <{v[2]}>'",
934
+ switch=f"-datasheet_io_{i} 'partname <{v[2]}>'",
940
935
  example=[
941
- f"cli: -datasheet_io_{i} 'name {v[1]}'",
942
- f"api: chip.set('datasheet', 'io', name, '{i}', {v[1]})"],
936
+ f"cli: -datasheet_io_{i} 'partname {v[1]}'",
937
+ f"api: chip.set('datasheet', 'io', partname, '{i}', {v[1]})"],
943
938
  schelp=f"""Datasheet: IO {v[1]} metrics specified on a per IO port basis.
944
939
  """)
945
940
 
@@ -947,31 +942,31 @@ def schema_datasheet(cfg, name='default', mode='default'):
947
942
  # Processor
948
943
  ######################
949
944
 
950
- scparam(cfg, ['datasheet', 'proc', name, 'arch'],
945
+ scparam(cfg, ['datasheet', 'proc', partname, 'arch'],
951
946
  sctype='str',
952
947
  shorthelp="Datasheet: processor architecture",
953
- switch="-datasheet_proc_arch 'name <str>'",
948
+ switch="-datasheet_proc_arch 'partname <str>'",
954
949
  example=[
955
950
  "cli: -datasheet_proc_arch '0 RV64GC'",
956
- "api: chip.set('datasheet', 'proc', name, 'arch', 'openfpga')"],
951
+ "api: chip.set('datasheet', 'proc', partname, 'arch', 'openfpga')"],
957
952
  schelp="""Processor architecture specified on a per core basis.""")
958
953
 
959
- scparam(cfg, ['datasheet', 'proc', name, 'features'],
954
+ scparam(cfg, ['datasheet', 'proc', partname, 'features'],
960
955
  sctype='[str]',
961
956
  shorthelp="Datasheet: processor features",
962
- switch="-datasheet_proc_features 'name <str>'",
957
+ switch="-datasheet_proc_features 'partname <str>'",
963
958
  example=[
964
959
  "cli: -datasheet_proc_features '0 SIMD'",
965
960
  "api: chip.set('datasheet','proc','cpu','features', 'SIMD')"],
966
961
  schelp="""List of maker specified processor features specified on a per core basis.""")
967
962
 
968
- scparam(cfg, ['datasheet', 'proc', name, 'datatypes'],
963
+ scparam(cfg, ['datasheet', 'proc', partname, 'datatypes'],
969
964
  sctype='[enum]',
970
965
  enum=['int4', 'int8', 'int16', 'int32', 'int64', 'int128',
971
966
  'uint4', 'uint8', 'uint16', 'uint32', 'uint64', 'uint128',
972
967
  'bfloat16', 'fp16', 'fp32', 'fp64', 'fp128'],
973
968
  shorthelp="Datasheet: processor datatypes",
974
- switch="-datasheet_proc_datatypes 'name <str>'",
969
+ switch="-datasheet_proc_datatypes 'partname <str>'",
975
970
  example=[
976
971
  "cli: -datasheet_proc_datatypes '0 int8'",
977
972
  "api: chip.set('datasheet', 'proc', 'cpu', 'datatypes', 'int8')"],
@@ -991,11 +986,11 @@ def schema_datasheet(cfg, name='default', mode='default'):
991
986
  'nvm': ['local non-volatile memory', 128, 'KB']}
992
987
 
993
988
  for i, v in metrics.items():
994
- scparam(cfg, ['datasheet', 'proc', name, i],
989
+ scparam(cfg, ['datasheet', 'proc', partname, i],
995
990
  unit=v[2],
996
991
  sctype='int',
997
992
  shorthelp=f"Datasheet: processor {v[0]}",
998
- switch=f"-datasheet_proc_{i} 'name <int>'",
993
+ switch=f"-datasheet_proc_{i} 'partname <int>'",
999
994
  example=[
1000
995
  f"cli: -datasheet_proc_{i} 'cpu {v[1]}'",
1001
996
  f"api: chip.set('datasheet', 'proc', 'cpu', '{i}', {v[1]})"],
@@ -1005,37 +1000,37 @@ def schema_datasheet(cfg, name='default', mode='default'):
1005
1000
  # Memory
1006
1001
  ######################
1007
1002
 
1008
- scparam(cfg, ['datasheet', 'memory', name, 'bits'],
1003
+ scparam(cfg, ['datasheet', 'memory', partname, 'bits'],
1009
1004
  sctype='int',
1010
1005
  shorthelp="Datasheet: memory total bits",
1011
- switch="-datasheet_memory_bits 'name <int>'",
1006
+ switch="-datasheet_memory_bits 'partname <int>'",
1012
1007
  example=[
1013
1008
  "cli: -datasheet_memory_bits 'm0 1024'",
1014
1009
  "api: chip.set('datasheet', 'memory', 'm0', 'bits', 1024)"],
1015
1010
  schelp="""Memory total number of bits specified on a per memory basis.""")
1016
1011
 
1017
- scparam(cfg, ['datasheet', 'memory', name, 'width'],
1012
+ scparam(cfg, ['datasheet', 'memory', partname, 'width'],
1018
1013
  sctype='int',
1019
1014
  shorthelp="Datasheet: memory width",
1020
- switch="-datasheet_memory_width 'name <int>'",
1015
+ switch="-datasheet_memory_width 'partname <int>'",
1021
1016
  example=[
1022
1017
  "cli: -datasheet_memory_width 'm0 16'",
1023
1018
  "api: chip.set('datasheet', 'memory', 'm0', 'width', 16)"],
1024
1019
  schelp="""Memory width specified on a per memory basis.""")
1025
1020
 
1026
- scparam(cfg, ['datasheet', 'memory', name, 'depth'],
1021
+ scparam(cfg, ['datasheet', 'memory', partname, 'depth'],
1027
1022
  sctype='int',
1028
1023
  shorthelp="Datasheet: memory depth",
1029
- switch="-datasheet_memory_depth 'name <int>'",
1024
+ switch="-datasheet_memory_depth 'partname <int>'",
1030
1025
  example=[
1031
1026
  "cli: -datasheet_memory_depth 'm0 128'",
1032
1027
  "api: chip.set('datasheet', 'memory', 'm0', 'depth', 128)"],
1033
1028
  schelp="""Memory depth specified on a per memory basis.""")
1034
1029
 
1035
- scparam(cfg, ['datasheet', 'memory', name, 'banks'],
1030
+ scparam(cfg, ['datasheet', 'memory', partname, 'banks'],
1036
1031
  sctype='int',
1037
1032
  shorthelp="Datasheet: memory banks",
1038
- switch="-datasheet_memory_banks 'name <int>'",
1033
+ switch="-datasheet_memory_banks 'partname <int>'",
1039
1034
  example=[
1040
1035
  "cli: -datasheet_memory_banks 'm0 4'",
1041
1036
  "api: chip.set('datasheet', 'memory', 'm0', 'banks', 4)"],
@@ -1056,14 +1051,14 @@ def schema_datasheet(cfg, name='default', mode='default'):
1056
1051
  }
1057
1052
 
1058
1053
  for i, v in metrics.items():
1059
- scparam(cfg, ['datasheet', 'memory', name, i],
1054
+ scparam(cfg, ['datasheet', 'memory', partname, i],
1060
1055
  unit=v[2],
1061
1056
  sctype='(float,float,float)',
1062
1057
  shorthelp=f"Datasheet: memory {v[0]}",
1063
- switch=f"-datasheet_memory_{i} 'name <(float,float,float)>'",
1058
+ switch=f"-datasheet_memory_{i} 'partname <(float,float,float)>'",
1064
1059
  example=[
1065
- f"cli: -datasheet_memory_{i} 'name {v[1]}'",
1066
- f"api: chip.set('datasheet', 'memory', name, '{i}', {v[1]})"],
1060
+ f"cli: -datasheet_memory_{i} 'partname {v[1]}'",
1061
+ f"api: chip.set('datasheet', 'memory', partname, '{i}', {v[1]})"],
1067
1062
  schelp=f"""Memory {v[1]} specified on a per memory basis.""")
1068
1063
 
1069
1064
  # Latency (cycles)
@@ -1074,24 +1069,24 @@ def schema_datasheet(cfg, name='default', mode='default'):
1074
1069
  }
1075
1070
 
1076
1071
  for i, v in metrics.items():
1077
- scparam(cfg, ['datasheet', 'memory', name, i],
1072
+ scparam(cfg, ['datasheet', 'memory', partname, i],
1078
1073
  unit=v[2],
1079
1074
  sctype='(int,int,int)',
1080
1075
  shorthelp=f"Datasheet: memory {v[0]}",
1081
- switch=f"-datasheet_memory_{i} 'name <(int,int,int)>'",
1076
+ switch=f"-datasheet_memory_{i} 'partname <(int,int,int)>'",
1082
1077
  example=[
1083
- f"cli: -datasheet_memory_{i} 'name {v[1]}'",
1084
- f"api: chip.set('datasheet', 'memory', name, '{i}', {v[1]})"],
1078
+ f"cli: -datasheet_memory_{i} 'partname {v[1]}'",
1079
+ f"api: chip.set('datasheet', 'memory', partname, '{i}', {v[1]})"],
1085
1080
  schelp=f"""Memory {v[1]} specified on a per memory basis.""")
1086
1081
 
1087
1082
  ######################
1088
1083
  # FPGA
1089
1084
  ######################
1090
1085
 
1091
- scparam(cfg, ['datasheet', 'fpga', name, 'arch'],
1086
+ scparam(cfg, ['datasheet', 'fpga', partname, 'arch'],
1092
1087
  sctype='str',
1093
1088
  shorthelp="Datasheet: fpga architecture",
1094
- switch="-datasheet_fpga_arch 'name <str>'",
1089
+ switch="-datasheet_fpga_arch 'partname <str>'",
1095
1090
  example=[
1096
1091
  "cli: -datasheet_fpga_arch 'i0 openfpga'",
1097
1092
  "api: chip.set('datasheet', 'fpga', 'i0', 'arch', 'openfpga')"],
@@ -1107,11 +1102,11 @@ def schema_datasheet(cfg, name='default', mode='default'):
1107
1102
  'blockram': ['block ram', 128, 'Kb']}
1108
1103
 
1109
1104
  for i, v in metrics.items():
1110
- scparam(cfg, ['datasheet', 'fpga', name, i],
1105
+ scparam(cfg, ['datasheet', 'fpga', partname, i],
1111
1106
  unit=v[2],
1112
1107
  sctype='int',
1113
1108
  shorthelp=f"Datasheet: fpga {v[0]}",
1114
- switch=f"-datasheet_fpga_{i} 'name <int>'",
1109
+ switch=f"-datasheet_fpga_{i} 'partname <int>'",
1115
1110
  example=[
1116
1111
  f"cli: -datasheet_fpga_{i} 'i0 {v[1]}'",
1117
1112
  f"api: chip.set('datasheet', 'fpga', 'i0', '{i}', {v[1]})"],
@@ -1121,19 +1116,19 @@ def schema_datasheet(cfg, name='default', mode='default'):
1121
1116
  # Analog
1122
1117
  ######################
1123
1118
 
1124
- scparam(cfg, ['datasheet', 'analog', name, 'arch'],
1119
+ scparam(cfg, ['datasheet', 'analog', partname, 'arch'],
1125
1120
  sctype='str',
1126
1121
  shorthelp="Datasheet: analog architecture",
1127
- switch="-datasheet_analog_arch 'name <str>'",
1122
+ switch="-datasheet_analog_arch 'partname <str>'",
1128
1123
  example=[
1129
1124
  "cli: -datasheet_analog_arch 'adc0 pipelined'",
1130
1125
  "api: chip.set('datasheet', 'analog', 'adc0', 'arch', 'pipelined')"],
1131
1126
  schelp="""Analog component architecture.""")
1132
1127
 
1133
- scparam(cfg, ['datasheet', 'analog', name, 'features'],
1128
+ scparam(cfg, ['datasheet', 'analog', partname, 'features'],
1134
1129
  sctype='[str]',
1135
1130
  shorthelp="Datasheet: analog features",
1136
- switch="-datasheet_analog_features 'name <str>'",
1131
+ switch="-datasheet_analog_features 'partname <str>'",
1137
1132
  example=[
1138
1133
  "cli: -datasheet_analog_features '0 differential input'",
1139
1134
  "api: chip.set('datasheet','analog','adc0','features', 'differential input')"],
@@ -1143,10 +1138,10 @@ def schema_datasheet(cfg, name='default', mode='default'):
1143
1138
  'channels': ['parallel channels', 8]}
1144
1139
 
1145
1140
  for i, v in metrics.items():
1146
- scparam(cfg, ['datasheet', 'analog', name, i],
1141
+ scparam(cfg, ['datasheet', 'analog', partname, i],
1147
1142
  sctype='int',
1148
1143
  shorthelp=f"Datasheet: analog {v[0]}",
1149
- switch=f"-datasheet_analog_{i} 'name <int>'",
1144
+ switch=f"-datasheet_analog_{i} 'partname <int>'",
1150
1145
  example=[
1151
1146
  f"cli: -datasheet_analog_{i} 'i0 {v[1]}'",
1152
1147
  f"api: chip.set('datasheet', 'analog', 'abc123', '{i}', {v[1]})"],
@@ -1185,11 +1180,11 @@ def schema_datasheet(cfg, name='default', mode='default'):
1185
1180
  }
1186
1181
 
1187
1182
  for i, v in metrics.items():
1188
- scparam(cfg, ['datasheet', 'analog', name, i],
1183
+ scparam(cfg, ['datasheet', 'analog', partname, i],
1189
1184
  unit=v[2],
1190
1185
  sctype='(float,float,float)',
1191
1186
  shorthelp=f"Datasheet: analog {v[0]}",
1192
- switch=f"-datasheet_analog_{i} 'name <(float,float,float)>'",
1187
+ switch=f"-datasheet_analog_{i} 'partname <(float,float,float)>'",
1193
1188
  example=[
1194
1189
  f"cli: -datasheet_analog_{i} 'i0 {v[1]}'",
1195
1190
  f"api: chip.set('datasheet', 'analog', 'abc123', '{i}', {v[1]})"],
@@ -1252,20 +1247,20 @@ def schema_datasheet(cfg, name='default', mode='default'):
1252
1247
  # Package Description
1253
1248
  #########################
1254
1249
 
1255
- scparam(cfg, ['datasheet', 'package', name, 'type'],
1250
+ scparam(cfg, ['datasheet', 'package', partname, 'type'],
1256
1251
  sctype='enum',
1257
1252
  enum=['bga', 'lga', 'csp', 'qfn', 'qfp', 'sop', 'die', 'wafer'],
1258
1253
  shorthelp="Datasheet: package type",
1259
- switch="-datasheet_package_type 'name <str>'",
1254
+ switch="-datasheet_package_type 'partname <str>'",
1260
1255
  example=[
1261
1256
  "cli: -datasheet_package_type 'abcd bga'",
1262
1257
  "api: chip.set('datasheet', 'package', 'abcd', 'type', 'bga')"],
1263
1258
  schelp="""Package type.""")
1264
1259
 
1265
- scparam(cfg, ['datasheet', 'package', name, 'footprint'],
1260
+ scparam(cfg, ['datasheet', 'package', partname, 'footprint'],
1266
1261
  sctype='[file]',
1267
1262
  shorthelp="Datasheet: package footprint",
1268
- switch="-datasheet_package_footprint 'name <file>'",
1263
+ switch="-datasheet_package_footprint 'partname <file>'",
1269
1264
  example=[
1270
1265
  "cli: -datasheet_package_footprint 'abcd ./soic8.kicad_mod'",
1271
1266
  "api: chip.set('datasheet', 'package', 'abcd', 'footprint', './soic8.kicad_mod')"],
@@ -1275,10 +1270,10 @@ def schema_datasheet(cfg, name='default', mode='default'):
1275
1270
 
1276
1271
  """)
1277
1272
 
1278
- scparam(cfg, ['datasheet', 'package', name, '3dmodel'],
1273
+ scparam(cfg, ['datasheet', 'package', partname, '3dmodel'],
1279
1274
  sctype='[file]',
1280
1275
  shorthelp="Datasheet: package 3D model",
1281
- switch="-datasheet_package_3dmodel 'name <file>'",
1276
+ switch="-datasheet_package_3dmodel 'partname <file>'",
1282
1277
  example=[
1283
1278
  "cli: -datasheet_package_3dmodel 'abcd ./soic8.step'",
1284
1279
  "api: chip.set('datasheet', 'package', 'abcd', '3dmodel', './soic8.step')"],
@@ -1290,10 +1285,10 @@ def schema_datasheet(cfg, name='default', mode='default'):
1290
1285
 
1291
1286
  """)
1292
1287
 
1293
- scparam(cfg, ['datasheet', 'package', name, 'drawing'],
1288
+ scparam(cfg, ['datasheet', 'package', partname, 'drawing'],
1294
1289
  sctype='[file]',
1295
1290
  shorthelp="Datasheet: package drawing",
1296
- switch="-datasheet_package_drawing 'name <file>'",
1291
+ switch="-datasheet_package_drawing 'partname <file>'",
1297
1292
  example=[
1298
1293
  "cli: -datasheet_package_drawing 'abcd p484.pdf'",
1299
1294
  "api: chip.set('datasheet', 'package', 'abcd', 'drawing', 'p484.pdf')"],
@@ -1308,11 +1303,11 @@ def schema_datasheet(cfg, name='default', mode='default'):
1308
1303
  }
1309
1304
 
1310
1305
  for i, v in metrics.items():
1311
- scparam(cfg, ['datasheet', 'package', name, i],
1306
+ scparam(cfg, ['datasheet', 'package', partname, i],
1312
1307
  unit=v[2],
1313
1308
  sctype='(float,float,float)',
1314
1309
  shorthelp=f"Datasheet: package {v[0]}",
1315
- switch=f"-datasheet_package_{i} 'name <(float,float,float)>'",
1310
+ switch=f"-datasheet_package_{i} 'partname <(float,float,float)>'",
1316
1311
  example=[
1317
1312
  f"cli: -datasheet_package_{i} 'abcd {v[1]}'",
1318
1313
  f"api: chip.set('datasheet', 'package', 'abcd', '{i}', {v[1]}"],
@@ -1320,20 +1315,20 @@ def schema_datasheet(cfg, name='default', mode='default'):
1320
1315
  (min, nominal, max).""")
1321
1316
 
1322
1317
  # pin
1323
- scparam(cfg, ['datasheet', 'package', name, 'pincount'],
1318
+ scparam(cfg, ['datasheet', 'package', partname, 'pincount'],
1324
1319
  sctype='int',
1325
1320
  shorthelp="Datasheet: package pin count",
1326
- switch="-datasheet_package_pincount 'name <int>'",
1321
+ switch="-datasheet_package_pincount 'partname <int>'",
1327
1322
  example=[
1328
1323
  "cli: -datasheet_package_pincount 'abcd 484'",
1329
1324
  "api: chip.set('datasheet', 'package', 'abcd', 'pincount', '484')"],
1330
1325
  schelp="""Total number package pins.""")
1331
1326
 
1332
1327
  number = 'default'
1333
- scparam(cfg, ['datasheet', 'package', name, 'pin', number, 'signal'],
1328
+ scparam(cfg, ['datasheet', 'package', partname, 'pin', number, 'signal'],
1334
1329
  sctype='str',
1335
1330
  shorthelp="Datasheet: package pin signal map",
1336
- switch="-datasheet_package_pin_signal 'name number <str>'",
1331
+ switch="-datasheet_package_pin_signal 'partname number <str>'",
1337
1332
  example=[
1338
1333
  "cli: -datasheet_package_pin_signal 'abcd B1 clk'",
1339
1334
  "api: chip.set('datasheet', 'package', 'abcd', 'pin', 'B1', 'signal', 'clk')"],
@@ -1342,12 +1337,12 @@ def schema_datasheet(cfg, name='default', mode='default'):
1342
1337
  :keypath:`datasheet,pin`.""")
1343
1338
 
1344
1339
  # anchor
1345
- scparam(cfg, ['datasheet', 'package', name, 'anchor'],
1340
+ scparam(cfg, ['datasheet', 'package', partname, 'anchor'],
1346
1341
  sctype='(float,float)',
1347
1342
  defvalue=(0.0, 0.0),
1348
1343
  unit='um',
1349
1344
  shorthelp="Datasheet: package anchor",
1350
- switch="-datasheet_package_anchor 'name <(float,float)>'",
1345
+ switch="-datasheet_package_anchor 'partname <(float,float)>'",
1351
1346
  example=[
1352
1347
  "cli: -datasheet_package_anchor 'i0 (3.0, 3.0)'",
1353
1348
  "api: chip.set('datasheet', 'package', 'i0', 'anchor', (3.0, 3.0))"],
@@ -1362,32 +1357,32 @@ def schema_datasheet(cfg, name='default', mode='default'):
1362
1357
  ######################
1363
1358
 
1364
1359
  # Pin type
1365
- scparam(cfg, ['datasheet', 'pin', name, 'type', mode],
1360
+ scparam(cfg, ['datasheet', 'pin', partname, 'type', mode],
1366
1361
  sctype='enum',
1367
1362
  enum=['digital', 'analog', 'clock', 'supply', 'ground'],
1368
1363
  shorthelp="Datasheet: pin type",
1369
- switch="-datasheet_pin_type 'name mode <str>'",
1364
+ switch="-datasheet_pin_type 'partname mode <str>'",
1370
1365
  example=[
1371
1366
  "cli: -datasheet_pin_type 'vdd global supply'",
1372
1367
  "api: chip.set('datasheet', 'pin', 'vdd', 'type', 'global', 'supply')"],
1373
1368
  schelp="""Pin type specified on a per mode basis.""")
1374
1369
 
1375
1370
  # Pin direction
1376
- scparam(cfg, ['datasheet', 'pin', name, 'dir', mode],
1371
+ scparam(cfg, ['datasheet', 'pin', partname, 'dir', mode],
1377
1372
  sctype='enum',
1378
1373
  enum=['input', 'output', 'inout'],
1379
1374
  shorthelp="Datasheet: pin direction",
1380
- switch="-datasheet_pin_dir 'name mode <str>'",
1375
+ switch="-datasheet_pin_dir 'partname mode <str>'",
1381
1376
  example=[
1382
1377
  "cli: -datasheet_pin_dir 'clk global input'",
1383
1378
  "api: chip.set('datasheet', 'pin', 'clk', 'dir', 'global', 'input')"],
1384
1379
  schelp="""Pin direction specified on a per mode basis.""")
1385
1380
 
1386
1381
  # Pin complement (for differential pair)
1387
- scparam(cfg, ['datasheet', 'pin', name, 'complement', mode],
1382
+ scparam(cfg, ['datasheet', 'pin', partname, 'complement', mode],
1388
1383
  sctype='str',
1389
1384
  shorthelp="Datasheet: pin complement",
1390
- switch="-datasheet_pin_complement 'name mode <str>'",
1385
+ switch="-datasheet_pin_complement 'partname mode <str>'",
1391
1386
  example=[
1392
1387
  "cli: -datasheet_pin_complement 'ina global inb'",
1393
1388
  "api: chip.set('datasheet', 'pin', 'ina', 'complement', 'global', 'inb')"],
@@ -1395,31 +1390,31 @@ def schema_datasheet(cfg, name='default', mode='default'):
1395
1390
  signals.""")
1396
1391
 
1397
1392
  # Pin standard
1398
- scparam(cfg, ['datasheet', 'pin', name, 'standard', mode],
1393
+ scparam(cfg, ['datasheet', 'pin', partname, 'standard', mode],
1399
1394
  sctype='[str]',
1400
1395
  shorthelp="Datasheet: pin standard",
1401
- switch="-datasheet_pin_standard 'name mode <str>'",
1396
+ switch="-datasheet_pin_standard 'partname mode <str>'",
1402
1397
  example=[
1403
1398
  "cli: -datasheet_pin_standard 'clk def LVCMOS'",
1404
1399
  "api: chip.set('datasheet', 'pin', 'clk', 'standard', 'def', 'LVCMOS')"],
1405
1400
  schelp="""Pin electrical signaling standard (LVDS, LVCMOS, TTL, ...).""")
1406
1401
 
1407
1402
  # Pin interface map
1408
- scparam(cfg, ['datasheet', 'pin', name, 'interface', mode],
1403
+ scparam(cfg, ['datasheet', 'pin', partname, 'interface', mode],
1409
1404
  sctype='[str]',
1410
1405
  shorthelp="Datasheet: pin interface map",
1411
- switch="-datasheet_pin_interface 'name mode <str>'",
1406
+ switch="-datasheet_pin_interface 'partname mode <str>'",
1412
1407
  example=[
1413
1408
  "cli: -datasheet_pin_interface 'clk0 ddr4 CLKN'",
1414
1409
  "api: chip.set('datasheet', 'pin', 'clk0', 'interface', 'ddr4', 'CLKN')"],
1415
1410
  schelp="""Pin mapping to standardized interface names.""")
1416
1411
 
1417
1412
  # Pin reset value
1418
- scparam(cfg, ['datasheet', 'pin', name, 'resetvalue', mode],
1413
+ scparam(cfg, ['datasheet', 'pin', partname, 'resetvalue', mode],
1419
1414
  sctype='enum',
1420
1415
  enum=['weak1', 'weak0', 'strong0', 'strong1', 'highz'],
1421
1416
  shorthelp="Datasheet: pin reset value",
1422
- switch="-datasheet_pin_resetvalue 'name mode <str>'",
1417
+ switch="-datasheet_pin_resetvalue 'partname mode <str>'",
1423
1418
  example=[
1424
1419
  "cli: -datasheet_pin_resetvalue 'clk global weak1'",
1425
1420
  "api: chip.set('datasheet', 'pin', 'clk', 'resetvalue', 'global', 'weak1')"],
@@ -1470,7 +1465,7 @@ def schema_datasheet(cfg, name='default', mode='default'):
1470
1465
  }
1471
1466
 
1472
1467
  for item, val in metrics.items():
1473
- scparam(cfg, ['datasheet', 'pin', name, item, mode],
1468
+ scparam(cfg, ['datasheet', 'pin', partname, item, mode],
1474
1469
  unit=val[2],
1475
1470
  sctype='(float,float,float)',
1476
1471
  shorthelp=f"Datasheet: pin {val[0]}",
@@ -1493,7 +1488,7 @@ def schema_datasheet(cfg, name='default', mode='default'):
1493
1488
  relpin = 'default'
1494
1489
 
1495
1490
  for i, v in metrics.items():
1496
- scparam(cfg, ['datasheet', 'pin', name, i, mode, relpin],
1491
+ scparam(cfg, ['datasheet', 'pin', partname, i, mode, relpin],
1497
1492
  unit=v[2],
1498
1493
  sctype='(float,float,float)',
1499
1494
  shorthelp=f"Datasheet: pin {v[0]}",
@@ -1614,7 +1609,7 @@ def schema_tool(cfg, tool='default'):
1614
1609
 
1615
1610
  scparam(cfg, ['tool', tool, 'sbom', version],
1616
1611
  sctype='[file]',
1617
- pernode='optional',
1612
+ pernode=PerNode.OPTIONAL,
1618
1613
  shorthelp="Tool: software BOM",
1619
1614
  switch="-tool_sbom 'tool version <file>'",
1620
1615
  example=[
@@ -1629,7 +1624,7 @@ def schema_tool(cfg, tool='default'):
1629
1624
 
1630
1625
  scparam(cfg, ['tool', tool, 'path'],
1631
1626
  sctype='dir',
1632
- pernode='optional',
1627
+ pernode=PerNode.OPTIONAL,
1633
1628
  shorthelp="Tool: executable path",
1634
1629
  switch="-tool_path 'tool <dir>'",
1635
1630
  example=[
@@ -1666,7 +1661,7 @@ def schema_tool(cfg, tool='default'):
1666
1661
 
1667
1662
  scparam(cfg, ['tool', tool, 'version'],
1668
1663
  sctype='[str]',
1669
- pernode='optional',
1664
+ pernode=PerNode.OPTIONAL,
1670
1665
  shorthelp="Tool: version",
1671
1666
  switch="-tool_version 'tool <str>'",
1672
1667
  example=["cli: -tool_version 'openroad >=v2.0'",
@@ -1696,7 +1691,7 @@ def schema_tool(cfg, tool='default'):
1696
1691
  key = 'default'
1697
1692
  scparam(cfg, ['tool', tool, 'licenseserver', key],
1698
1693
  sctype='[str]',
1699
- pernode='optional',
1694
+ pernode=PerNode.OPTIONAL,
1700
1695
  shorthelp="Tool: license servers",
1701
1696
  switch="-tool_licenseserver 'name key <str>'",
1702
1697
  example=[
@@ -1719,7 +1714,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1719
1714
 
1720
1715
  scparam(cfg, ['tool', tool, 'task', task, 'warningoff'],
1721
1716
  sctype='[str]',
1722
- pernode='optional',
1717
+ pernode=PerNode.OPTIONAL,
1723
1718
  shorthelp="Task: warning filter",
1724
1719
  switch="-tool_task_warningoff 'tool task <str>'",
1725
1720
  example=[
@@ -1734,7 +1729,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1734
1729
 
1735
1730
  scparam(cfg, ['tool', tool, 'task', task, 'regex', suffix],
1736
1731
  sctype='[str]',
1737
- pernode='optional',
1732
+ pernode=PerNode.OPTIONAL,
1738
1733
  shorthelp="Task: regex filter",
1739
1734
  switch="-tool_task_regex 'tool task suffix <str>'",
1740
1735
  example=[
@@ -1770,7 +1765,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1770
1765
  # Configuration: cli-option, tcl var, env var, file
1771
1766
  scparam(cfg, ['tool', tool, 'task', task, 'option'],
1772
1767
  sctype='[str]',
1773
- pernode='optional',
1768
+ pernode=PerNode.OPTIONAL,
1774
1769
  shorthelp="Task: executable options",
1775
1770
  switch="-tool_task_option 'tool task <str>'",
1776
1771
  example=[
@@ -1784,7 +1779,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1784
1779
 
1785
1780
  scparam(cfg, ['tool', tool, 'task', task, 'var', key],
1786
1781
  sctype='[str]',
1787
- pernode='optional',
1782
+ pernode=PerNode.OPTIONAL,
1788
1783
  shorthelp="Task: script variables",
1789
1784
  switch="-tool_task_var 'tool task key <str>'",
1790
1785
  example=[
@@ -1797,7 +1792,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1797
1792
 
1798
1793
  scparam(cfg, ['tool', tool, 'task', task, 'env', key],
1799
1794
  sctype='str',
1800
- pernode='optional',
1795
+ pernode=PerNode.OPTIONAL,
1801
1796
  shorthelp="Task: environment variables",
1802
1797
  switch="-tool_task_env 'tool task env <str>'",
1803
1798
  example=[
@@ -1810,14 +1805,14 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1810
1805
 
1811
1806
  scparam(cfg, ['tool', tool, 'task', task, 'file', key],
1812
1807
  sctype='[file]',
1813
- pernode='optional',
1808
+ pernode=PerNode.OPTIONAL,
1814
1809
  copy=True,
1815
1810
  shorthelp="Task: custom setup files",
1816
1811
  switch="-tool_task_file 'tool task key <file>'",
1817
1812
  example=[
1818
1813
  "cli: -tool_task_file 'openroad floorplan macroplace macroplace.tcl'",
1819
1814
  "api: chip.set('tool', 'openroad', 'task', 'floorplan', 'file', 'macroplace', "
1820
- "'macroplace.tcl')"],
1815
+ "'macroplace.tcl')"],
1821
1816
  schelp="""
1822
1817
  Paths to user supplied files mapped to keys. Keys and filetypes must
1823
1818
  match what's expected by the task/reference script consuming the
@@ -1826,14 +1821,14 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1826
1821
 
1827
1822
  scparam(cfg, ['tool', tool, 'task', task, 'dir', key],
1828
1823
  sctype='[dir]',
1829
- pernode='optional',
1824
+ pernode=PerNode.OPTIONAL,
1830
1825
  copy=True,
1831
1826
  shorthelp="Task: custom setup directories",
1832
1827
  switch="-tool_task_dir 'tool task key <dir>'",
1833
1828
  example=[
1834
1829
  "cli: -tool_task_dir 'verilator compile cincludes include'",
1835
1830
  "api: chip.set('tool', 'verilator', 'task', 'compile', 'dir', 'cincludes', "
1836
- "'include')"],
1831
+ "'include')"],
1837
1832
  schelp="""
1838
1833
  Paths to user supplied directories mapped to keys. Keys must match
1839
1834
  what's expected by the task/reference script consuming the
@@ -1843,13 +1838,13 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1843
1838
  # Definitions of inputs, outputs, requirements
1844
1839
  scparam(cfg, ['tool', tool, 'task', task, 'input'],
1845
1840
  sctype='[file]',
1846
- pernode='required',
1841
+ pernode=PerNode.REQUIRED,
1847
1842
  shorthelp="Task: input files",
1848
1843
  switch="-tool_task_input 'tool task <file>'",
1849
1844
  example=[
1850
1845
  "cli: -tool_task_input 'openroad place place 0 oh_add.def'",
1851
1846
  "api: chip.set('tool', 'openroad', 'task', 'place', 'input', 'oh_add.def', "
1852
- "step='place', index='0')"],
1847
+ "step='place', index='0')"],
1853
1848
  schelp="""
1854
1849
  List of data files to be copied from previous flowgraph steps 'output'
1855
1850
  directory. The list of steps to copy files from is defined by the
@@ -1859,13 +1854,13 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1859
1854
 
1860
1855
  scparam(cfg, ['tool', tool, 'task', task, 'output'],
1861
1856
  sctype='[file]',
1862
- pernode='required',
1857
+ pernode=PerNode.REQUIRED,
1863
1858
  shorthelp="Task: output files",
1864
1859
  switch="-tool_task_output 'tool task <file>'",
1865
1860
  example=[
1866
1861
  "cli: -tool_task_output 'openroad place place 0 oh_add.def'",
1867
1862
  "api: chip.set('tool', 'openroad', 'task', 'place', 'output', 'oh_add.def', "
1868
- "step='place', index='0')"],
1863
+ "step='place', index='0')"],
1869
1864
  schelp="""
1870
1865
  List of data files written to the 'output' directory of the
1871
1866
  tool/task/step/index used in the keypath. All files must be available
@@ -1876,8 +1871,8 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1876
1871
  sctype='enum',
1877
1872
  enum=dest_enum,
1878
1873
  defvalue='log',
1879
- scope='job',
1880
- pernode='optional',
1874
+ scope=Scope.JOB,
1875
+ pernode=PerNode.OPTIONAL,
1881
1876
  shorthelp="Task: destination for stdout",
1882
1877
  switch="-tool_task_stdout_destination 'tool task <str>'",
1883
1878
  example=["cli: -tool_task_stdout_destination 'ghdl import log'",
@@ -1894,8 +1889,8 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1894
1889
  scparam(cfg, ['tool', tool, 'task', task, 'stdout', 'suffix'],
1895
1890
  sctype='str',
1896
1891
  defvalue='log',
1897
- scope='job',
1898
- pernode='optional',
1892
+ scope=Scope.JOB,
1893
+ pernode=PerNode.OPTIONAL,
1899
1894
  shorthelp="Task: file suffix for redirected stdout",
1900
1895
  switch="-tool_task_stdout_suffix 'tool task <str>'",
1901
1896
  example=["cli: -tool_task_stdout_suffix 'ghdl import log'",
@@ -1907,8 +1902,8 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1907
1902
  sctype='enum',
1908
1903
  enum=dest_enum,
1909
1904
  defvalue='log',
1910
- scope='job',
1911
- pernode='optional',
1905
+ scope=Scope.JOB,
1906
+ pernode=PerNode.OPTIONAL,
1912
1907
  shorthelp="Task: destination for stderr",
1913
1908
  switch="-tool_task_stderr_destination 'tool task <str>'",
1914
1909
  example=["cli: -tool_task_stderr_destination 'ghdl import log'",
@@ -1925,8 +1920,8 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1925
1920
  scparam(cfg, ['tool', tool, 'task', task, 'stderr', 'suffix'],
1926
1921
  sctype='str',
1927
1922
  defvalue='log',
1928
- scope='job',
1929
- pernode='optional',
1923
+ scope=Scope.JOB,
1924
+ pernode=PerNode.OPTIONAL,
1930
1925
  shorthelp="Task: file suffix for redirected stderr",
1931
1926
  switch="-tool_task_stderr_suffix 'tool task <str>'",
1932
1927
  example=["cli: -tool_task_stderr_suffix 'ghdl import log'",
@@ -1936,7 +1931,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1936
1931
 
1937
1932
  scparam(cfg, ['tool', tool, 'task', task, 'require'],
1938
1933
  sctype='[str]',
1939
- pernode='optional',
1934
+ pernode=PerNode.OPTIONAL,
1940
1935
  shorthelp="Task: parameter requirements",
1941
1936
  switch="-tool_task_require 'tool task <str>'",
1942
1937
  example=[
@@ -1950,20 +1945,20 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1950
1945
  metric = 'default'
1951
1946
  scparam(cfg, ['tool', tool, 'task', task, 'report', metric],
1952
1947
  sctype='[file]',
1953
- pernode='required',
1948
+ pernode=PerNode.REQUIRED,
1954
1949
  shorthelp="Task: metric report files",
1955
1950
  switch="-tool_task_report 'tool task metric <file>'",
1956
1951
  example=[
1957
1952
  "cli: -tool_task_report 'openroad place holdtns place 0 place.log'",
1958
1953
  "api: chip.set('tool', 'openroad', 'task', 'place', 'report', 'holdtns', "
1959
- "'place.log', step='place', index='0')"],
1954
+ "'place.log', step='place', index='0')"],
1960
1955
  schelp="""
1961
1956
  List of report files associated with a specific 'metric'. The file path
1962
1957
  specified is relative to the run directory of the current task.""")
1963
1958
 
1964
1959
  scparam(cfg, ['tool', tool, 'task', task, 'refdir'],
1965
1960
  sctype='[dir]',
1966
- pernode='optional',
1961
+ pernode=PerNode.OPTIONAL,
1967
1962
  shorthelp="Task: script directory",
1968
1963
  switch="-tool_task_refdir 'tool task <dir>'",
1969
1964
  example=[
@@ -1975,7 +1970,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1975
1970
 
1976
1971
  scparam(cfg, ['tool', tool, 'task', task, 'script'],
1977
1972
  sctype='[file]',
1978
- pernode='optional',
1973
+ pernode=PerNode.OPTIONAL,
1979
1974
  shorthelp="Task: entry script",
1980
1975
  switch="-tool_task_script 'tool task <file>'",
1981
1976
  example=[
@@ -1987,7 +1982,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
1987
1982
 
1988
1983
  scparam(cfg, ['tool', tool, 'task', task, 'prescript'],
1989
1984
  sctype='[file]',
1990
- pernode='optional',
1985
+ pernode=PerNode.OPTIONAL,
1991
1986
  copy=True,
1992
1987
  shorthelp="Task: pre-step script",
1993
1988
  switch="-tool_task_prescript 'tool task <file>'",
@@ -2003,7 +1998,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
2003
1998
 
2004
1999
  scparam(cfg, ['tool', tool, 'task', task, 'postscript'],
2005
2000
  sctype='[file]',
2006
- pernode='optional',
2001
+ pernode=PerNode.OPTIONAL,
2007
2002
  copy=True,
2008
2003
  shorthelp="Task: post-step script",
2009
2004
  switch="-tool_task_postscript 'tool task <file>'",
@@ -2019,7 +2014,7 @@ def schema_task(cfg, tool='default', task='default', step='default', index='defa
2019
2014
 
2020
2015
  scparam(cfg, ['tool', tool, 'task', task, 'threads'],
2021
2016
  sctype='int',
2022
- pernode='optional',
2017
+ pernode=PerNode.OPTIONAL,
2023
2018
  shorthelp="Task: thread parallelism",
2024
2019
  switch="-tool_task_threads 'tool task <int>'",
2025
2020
  example=["cli: -tool_task_threads 'magic drc 64'",
@@ -2040,7 +2035,7 @@ def schema_arg(cfg):
2040
2035
 
2041
2036
  scparam(cfg, ['arg', 'step'],
2042
2037
  sctype='str',
2043
- scope='scratch',
2038
+ scope=Scope.SCRATCH,
2044
2039
  shorthelp="ARG: step argument",
2045
2040
  switch="-arg_step <str>",
2046
2041
  example=["cli: -arg_step 'route'",
@@ -2054,7 +2049,7 @@ def schema_arg(cfg):
2054
2049
 
2055
2050
  scparam(cfg, ['arg', 'index'],
2056
2051
  sctype='str',
2057
- scope='scratch',
2052
+ scope=Scope.SCRATCH,
2058
2053
  shorthelp="ARG: index argument",
2059
2054
  switch="-arg_index <str>",
2060
2055
  example=["cli: -arg_index 0",
@@ -2088,7 +2083,7 @@ def schema_metric(cfg, step='default', index='default'):
2088
2083
  example=[
2089
2084
  f"cli: -metric_{item} 'dfm 0 0'",
2090
2085
  f"api: chip.set('metric', '{item}', 0, step='dfm', index=0)"],
2091
- pernode='required',
2086
+ pernode=PerNode.REQUIRED,
2092
2087
  schelp=f"""Metric tracking the total number of {val} on a
2093
2088
  per step and index basis.""")
2094
2089
 
@@ -2100,7 +2095,7 @@ def schema_metric(cfg, step='default', index='default'):
2100
2095
  example=[
2101
2096
  "cli: -metric_coverage 'place 0 99.9'",
2102
2097
  "api: chip.set('metric', 'coverage', 99.9, step='place', index=0)"],
2103
- pernode='required',
2098
+ pernode=PerNode.REQUIRED,
2104
2099
  schelp="""
2105
2100
  Metric tracking the test coverage in the design expressed as a percentage
2106
2101
  with 100 meaning full coverage. The meaning of the metric depends on the
@@ -2115,7 +2110,7 @@ def schema_metric(cfg, step='default', index='default'):
2115
2110
  example=[
2116
2111
  "cli: -metric_security 'place 0 100'",
2117
2112
  "api: chip.set('metric', 'security', 100, step='place', index=0)"],
2118
- pernode='required',
2113
+ pernode=PerNode.REQUIRED,
2119
2114
  schelp="""
2120
2115
  Metric tracking the level of security (1/vulnerability) of the design.
2121
2116
  A completely secure design would have a score of 100. There is no
@@ -2135,7 +2130,7 @@ def schema_metric(cfg, step='default', index='default'):
2135
2130
  example=[
2136
2131
  f"cli: -metric_{item} 'place 0 100'",
2137
2132
  f"api: chip.set('metric', '{item}', 100, step='place', index=0)"],
2138
- pernode='required',
2133
+ pernode=PerNode.REQUIRED,
2139
2134
  schelp=f"""
2140
2135
  Metric tracking the total {val} used by the design as reported
2141
2136
  by the implementation tool. There is no standardized definition
@@ -2158,7 +2153,7 @@ def schema_metric(cfg, step='default', index='default'):
2158
2153
  example=[
2159
2154
  f"cli: -metric_{item} 'place 0 100.00'",
2160
2155
  f"api: chip.set('metric', '{item}', 100.00, step='place', index=0)"],
2161
- pernode='required',
2156
+ pernode=PerNode.REQUIRED,
2162
2157
  schelp=f"""
2163
2158
  Metric tracking the total {val} occupied by the design.""")
2164
2159
 
@@ -2170,7 +2165,7 @@ def schema_metric(cfg, step='default', index='default'):
2170
2165
  example=[
2171
2166
  "cli: -metric_utilization 'place 0 50.00'",
2172
2167
  "api: chip.set('metric', 'utilization', 50.00, step='place', index=0)"],
2173
- pernode='required',
2168
+ pernode=PerNode.REQUIRED,
2174
2169
  schelp="""
2175
2170
  Metric tracking the area utilization of the design calculated as
2176
2171
  100 * (cellarea/totalarea).""")
@@ -2182,7 +2177,7 @@ def schema_metric(cfg, step='default', index='default'):
2182
2177
  example=[
2183
2178
  "cli: -metric_logicdepth 'place 0 8'",
2184
2179
  "api: chip.set('metric', 'logicdepth', 8, step='place', index=0)"],
2185
- pernode='required',
2180
+ pernode=PerNode.REQUIRED,
2186
2181
  schelp="""
2187
2182
  Metric tracking the logic depth of the design. This is determined
2188
2183
  by the number of logic gates between the start of the critital timing
@@ -2202,7 +2197,7 @@ def schema_metric(cfg, step='default', index='default'):
2202
2197
  example=[
2203
2198
  f"cli: -metric_{item} 'place 0 0.01'",
2204
2199
  f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
2205
- pernode='required',
2200
+ pernode=PerNode.REQUIRED,
2206
2201
  schelp=f"""
2207
2202
  Metric tracking the {val} of the design specified on a per step
2208
2203
  and index basis. Power metric depend heavily on the method
@@ -2220,7 +2215,7 @@ def schema_metric(cfg, step='default', index='default'):
2220
2215
  example=[
2221
2216
  "cli: -metric_irdrop 'place 0 0.05'",
2222
2217
  "api: chip.set('metric', 'irdrop', 0.05, step='place', index=0)"],
2223
- pernode='required',
2218
+ pernode=PerNode.REQUIRED,
2224
2219
  schelp="""
2225
2220
  Metric tracking the peak IR drop in the design based on extracted
2226
2221
  power and ground rail parasitics, library power models, and
@@ -2239,7 +2234,7 @@ def schema_metric(cfg, step='default', index='default'):
2239
2234
  example=[
2240
2235
  f"cli: -metric_{item} 'place 0 10'",
2241
2236
  f"api: chip.set('metric', '{item}', 10, step='place', index=0)"],
2242
- pernode='required',
2237
+ pernode=PerNode.REQUIRED,
2243
2238
  schelp=f"""
2244
2239
  Metric tracking the total number of timing paths violating {val}
2245
2240
  constraints.""")
@@ -2262,7 +2257,7 @@ def schema_metric(cfg, step='default', index='default'):
2262
2257
  example=[
2263
2258
  f"cli: -metric_{item} 'place 0 0.01'",
2264
2259
  f"api: chip.set('metric', '{item}', 0.01, step='place', index=0)"],
2265
- pernode='required',
2260
+ pernode=PerNode.REQUIRED,
2266
2261
  schelp=f"""
2267
2262
  Metric tracking the {val} on a per step and index basis.""")
2268
2263
 
@@ -2277,7 +2272,7 @@ def schema_metric(cfg, step='default', index='default'):
2277
2272
  example=[
2278
2273
  f"cli: -metric_{item} 'place 0 100e6'",
2279
2274
  f"api: chip.set('metric', '{item}', 100e6, step='place', index=0)"],
2280
- pernode='required',
2275
+ pernode=PerNode.REQUIRED,
2281
2276
  schelp=f"""
2282
2277
  Metric tracking the {val} on a per step and index basis.""")
2283
2278
 
@@ -2299,7 +2294,7 @@ def schema_metric(cfg, step='default', index='default'):
2299
2294
  example=[
2300
2295
  f"cli: -metric_{item} 'place 0 100'",
2301
2296
  f"api: chip.set('metric', '{item}', 50, step='place', index=0)"],
2302
- pernode='required',
2297
+ pernode=PerNode.REQUIRED,
2303
2298
  schelp=f"""
2304
2299
  Metric tracking the total number of {val} in the design
2305
2300
  on a per step and index basis.""")
@@ -2313,7 +2308,7 @@ def schema_metric(cfg, step='default', index='default'):
2313
2308
  example=[
2314
2309
  f"cli: -metric_{item} 'place 0 100.0'",
2315
2310
  f"api: chip.set('metric', '{item}', 50.0, step='place', index=0)"],
2316
- pernode='required',
2311
+ pernode=PerNode.REQUIRED,
2317
2312
  schelp=f"""
2318
2313
  Metric tracking the total {item} of the design on a per step
2319
2314
  and index basis.""")
@@ -2326,7 +2321,7 @@ def schema_metric(cfg, step='default', index='default'):
2326
2321
  example=[
2327
2322
  f"cli: -metric_{item} 'place 0 0'",
2328
2323
  f"api: chip.set('metric', '{item}', 50, step='place', index=0)"],
2329
- pernode='required',
2324
+ pernode=PerNode.REQUIRED,
2330
2325
  schelp="""
2331
2326
  Metric tracking the total number of overflow tracks for the routing
2332
2327
  on per step and index basis. Any non-zero number suggests an over
@@ -2338,13 +2333,13 @@ def schema_metric(cfg, step='default', index='default'):
2338
2333
  scparam(cfg, ['metric', item],
2339
2334
  sctype='float',
2340
2335
  unit='B',
2341
- scope='job',
2336
+ scope=Scope.JOB,
2342
2337
  shorthelp=f"Metric: {item}",
2343
2338
  switch=f"-metric_{item} 'step index <float>'",
2344
2339
  example=[
2345
2340
  f"cli: -metric_{item} 'dfm 0 10e9'",
2346
2341
  f"api: chip.set('metric', '{item}', 10e9, step='dfm', index=0)"],
2347
- pernode='required',
2342
+ pernode=PerNode.REQUIRED,
2348
2343
  schelp="""
2349
2344
  Metric tracking total peak program memory footprint on a per
2350
2345
  step and index basis.""")
@@ -2358,7 +2353,7 @@ def schema_metric(cfg, step='default', index='default'):
2358
2353
  example=[
2359
2354
  f"cli: -metric_{item} 'dfm 0 10.0'",
2360
2355
  f"api: chip.set('metric', '{item}', 10.0, step='dfm', index=0)"],
2361
- pernode='required',
2356
+ pernode=PerNode.REQUIRED,
2362
2357
  schelp="""
2363
2358
  Metric tracking time spent by the EDA executable :keypath:`tool,<tool>,exe` on a
2364
2359
  per step and index basis. It does not include the SiliconCompiler
@@ -2374,7 +2369,7 @@ def schema_metric(cfg, step='default', index='default'):
2374
2369
  example=[
2375
2370
  f"cli: -metric_{item} 'dfm 0 10.0'",
2376
2371
  f"api: chip.set('metric', '{item}', 10.0, step='dfm', index=0)"],
2377
- pernode='required',
2372
+ pernode=PerNode.REQUIRED,
2378
2373
  schelp="""
2379
2374
  Metric tracking the total amount of time spent on a task from
2380
2375
  beginning to end, including data transfers and pre/post
@@ -2389,7 +2384,7 @@ def schema_metric(cfg, step='default', index='default'):
2389
2384
  example=[
2390
2385
  f"cli: -metric_{item} 'dfm 0 10.0'",
2391
2386
  f"api: chip.set('metric', '{item}', 10.0, step='dfm', index=0)"],
2392
- pernode='required',
2387
+ pernode=PerNode.REQUIRED,
2393
2388
  schelp="""
2394
2389
  Metric tracking the total amount of time spent from the beginning
2395
2390
  of the run up to and including the current step and index.""")
@@ -2482,7 +2477,7 @@ def schema_record(cfg, step='default', index='default'):
2482
2477
  example=[
2483
2478
  f"cli: -record_{item} 'dfm 0 {val[1]}'",
2484
2479
  f"api: chip.set('record', '{item}', '{val[1]}', step='dfm', index=0)"],
2485
- pernode='required',
2480
+ pernode=PerNode.REQUIRED,
2486
2481
  schelp=f'Record tracking the {val[0]} per step and index basis. {helpext}')
2487
2482
 
2488
2483
  scparam(cfg, ['record', 'toolexitcode'],
@@ -2492,7 +2487,7 @@ def schema_record(cfg, step='default', index='default'):
2492
2487
  example=[
2493
2488
  "cli: -record_toolexitcode 'dfm 0 0'",
2494
2489
  "api: chip.set('record', 'toolexitcode', 0, step='dfm', index=0)"],
2495
- pernode='required',
2490
+ pernode=PerNode.REQUIRED,
2496
2491
  schelp='Record tracking the tool exit code per step and index basis.')
2497
2492
 
2498
2493
  # Non-per-node records.
@@ -2517,7 +2512,7 @@ def schema_record(cfg, step='default', index='default'):
2517
2512
  # flowgraph status
2518
2513
  scparam(cfg, ['record', 'status'],
2519
2514
  sctype='enum',
2520
- pernode='required',
2515
+ pernode=PerNode.REQUIRED,
2521
2516
  enum=[ # keep in sync with NodeStatus
2522
2517
  "pending",
2523
2518
  "queued",
@@ -2536,7 +2531,7 @@ def schema_record(cfg, step='default', index='default'):
2536
2531
  # flowgraph select
2537
2532
  scparam(cfg, ['record', 'inputnode'],
2538
2533
  sctype='[(str,str)]',
2539
- pernode='required',
2534
+ pernode=PerNode.REQUIRED,
2540
2535
  shorthelp="Record: node inputs",
2541
2536
  switch="-record_inputnode 'step index <(str,str)>'",
2542
2537
  example=[
@@ -2558,7 +2553,7 @@ def schema_option(cfg):
2558
2553
 
2559
2554
  scparam(cfg, ['option', 'remote'],
2560
2555
  sctype='bool',
2561
- scope='job',
2556
+ scope=Scope.JOB,
2562
2557
  shorthelp="Option: enable remote processing",
2563
2558
  switch="-remote <bool>",
2564
2559
  example=[
@@ -2572,7 +2567,7 @@ def schema_option(cfg):
2572
2567
 
2573
2568
  scparam(cfg, ['option', 'credentials'],
2574
2569
  sctype='file',
2575
- scope='job',
2570
+ scope=Scope.JOB,
2576
2571
  shorthelp="Option: user credentials file",
2577
2572
  switch="-credentials <file>",
2578
2573
  example=[
@@ -2594,7 +2589,7 @@ def schema_option(cfg):
2594
2589
 
2595
2590
  scparam(cfg, ['option', 'cachedir'],
2596
2591
  sctype='file',
2597
- scope='job',
2592
+ scope=Scope.JOB,
2598
2593
  shorthelp="Option: user cache directory",
2599
2594
  switch="-cachedir <file>",
2600
2595
  example=[
@@ -2607,8 +2602,8 @@ def schema_option(cfg):
2607
2602
 
2608
2603
  scparam(cfg, ['option', 'nice'],
2609
2604
  sctype='int',
2610
- scope='job',
2611
- pernode='optional',
2605
+ scope=Scope.JOB,
2606
+ pernode=PerNode.OPTIONAL,
2612
2607
  shorthelp="Option: tool scheduling priority",
2613
2608
  switch="-nice <int>",
2614
2609
  example=[
@@ -2622,7 +2617,7 @@ def schema_option(cfg):
2622
2617
  # Compilation
2623
2618
  scparam(cfg, ['option', 'pdk'],
2624
2619
  sctype='str',
2625
- scope='job',
2620
+ scope=Scope.JOB,
2626
2621
  shorthelp="Option: PDK target",
2627
2622
  switch="-pdk <str>",
2628
2623
  example=["cli: -pdk freepdk45",
@@ -2632,7 +2627,7 @@ def schema_option(cfg):
2632
2627
 
2633
2628
  scparam(cfg, ['option', 'stackup'],
2634
2629
  sctype='str',
2635
- scope='job',
2630
+ scope=Scope.JOB,
2636
2631
  shorthelp="Option: stackup target",
2637
2632
  switch="-stackup <str>",
2638
2633
  example=["cli: -stackup 2MA4MB2MC",
@@ -2643,7 +2638,7 @@ def schema_option(cfg):
2643
2638
 
2644
2639
  scparam(cfg, ['option', 'flow'],
2645
2640
  sctype='str',
2646
- scope='job',
2641
+ scope=Scope.JOB,
2647
2642
  shorthelp="Option: flow target",
2648
2643
  switch="-flow <str>",
2649
2644
  example=["cli: -flow asicflow",
@@ -2654,8 +2649,8 @@ def schema_option(cfg):
2654
2649
 
2655
2650
  scparam(cfg, ['option', 'optmode'],
2656
2651
  sctype='str',
2657
- pernode='optional',
2658
- scope='job',
2652
+ pernode=PerNode.OPTIONAL,
2653
+ scope=Scope.JOB,
2659
2654
  defvalue='O0',
2660
2655
  shorthelp="Option: optimization mode",
2661
2656
  switch=["-O<str>",
@@ -2677,7 +2672,7 @@ def schema_option(cfg):
2677
2672
 
2678
2673
  scparam(cfg, ['option', 'cfg'],
2679
2674
  sctype='[file]',
2680
- scope='job',
2675
+ scope=Scope.JOB,
2681
2676
  shorthelp="Option: configuration manifest",
2682
2677
  switch="-cfg <file>",
2683
2678
  example=["cli: -cfg mypdk.json",
@@ -2692,7 +2687,7 @@ def schema_option(cfg):
2692
2687
  key = 'default'
2693
2688
  scparam(cfg, ['option', 'env', key],
2694
2689
  sctype='str',
2695
- scope='job',
2690
+ scope=Scope.JOB,
2696
2691
  shorthelp="Option: environment variables",
2697
2692
  switch="-env 'key <str>'",
2698
2693
  example=[
@@ -2705,7 +2700,7 @@ def schema_option(cfg):
2705
2700
 
2706
2701
  scparam(cfg, ['option', 'var', key],
2707
2702
  sctype='[str]',
2708
- scope='job',
2703
+ scope=Scope.JOB,
2709
2704
  shorthelp="Option: custom variables",
2710
2705
  switch="-var 'key <str>'",
2711
2706
  example=[
@@ -2719,7 +2714,7 @@ def schema_option(cfg):
2719
2714
 
2720
2715
  scparam(cfg, ['option', 'file', key],
2721
2716
  sctype='[file]',
2722
- scope='job',
2717
+ scope=Scope.JOB,
2723
2718
  copy=True,
2724
2719
  shorthelp="Option: custom files",
2725
2720
  switch="-file 'key <file>'",
@@ -2734,7 +2729,7 @@ def schema_option(cfg):
2734
2729
 
2735
2730
  scparam(cfg, ['option', 'dir', key],
2736
2731
  sctype='[dir]',
2737
- scope='job',
2732
+ scope=Scope.JOB,
2738
2733
  copy=True,
2739
2734
  shorthelp="Option: custom directories",
2740
2735
  switch="-dir 'key <dir>'",
@@ -2750,8 +2745,8 @@ def schema_option(cfg):
2750
2745
  scparam(cfg, ['option', 'loglevel'],
2751
2746
  sctype='enum',
2752
2747
  enum=["info", "warning", "error", "critical", "debug", "quiet"],
2753
- pernode='optional',
2754
- scope='job',
2748
+ pernode=PerNode.OPTIONAL,
2749
+ scope=Scope.JOB,
2755
2750
  defvalue='info',
2756
2751
  shorthelp="Option: logging level",
2757
2752
  switch="-loglevel <str>",
@@ -2763,7 +2758,7 @@ def schema_option(cfg):
2763
2758
 
2764
2759
  scparam(cfg, ['option', 'builddir'],
2765
2760
  sctype='dir',
2766
- scope='job',
2761
+ scope=Scope.JOB,
2767
2762
  defvalue='build',
2768
2763
  shorthelp="Option: build directory",
2769
2764
  switch="-builddir <dir>",
@@ -2777,7 +2772,7 @@ def schema_option(cfg):
2777
2772
 
2778
2773
  scparam(cfg, ['option', 'jobname'],
2779
2774
  sctype='str',
2780
- scope='job',
2775
+ scope=Scope.JOB,
2781
2776
  defvalue='job0',
2782
2777
  shorthelp="Option: job name",
2783
2778
  switch="-jobname <str>",
@@ -2792,7 +2787,7 @@ def schema_option(cfg):
2792
2787
 
2793
2788
  scparam(cfg, ['option', 'from'],
2794
2789
  sctype='[str]',
2795
- scope='job',
2790
+ scope=Scope.JOB,
2796
2791
  shorthelp="Option: starting step",
2797
2792
  switch="-from <str>",
2798
2793
  example=[
@@ -2804,7 +2799,7 @@ def schema_option(cfg):
2804
2799
 
2805
2800
  scparam(cfg, ['option', 'to'],
2806
2801
  sctype='[str]',
2807
- scope='job',
2802
+ scope=Scope.JOB,
2808
2803
  shorthelp="Option: ending step",
2809
2804
  switch="-to <str>",
2810
2805
  example=[
@@ -2816,7 +2811,7 @@ def schema_option(cfg):
2816
2811
 
2817
2812
  scparam(cfg, ['option', 'prune'],
2818
2813
  sctype='[(str,str)]',
2819
- scope='job',
2814
+ scope=Scope.JOB,
2820
2815
  shorthelp="Option: flowgraph pruning",
2821
2816
  switch="-prune 'node <(str,str)>'",
2822
2817
  example=[
@@ -2828,8 +2823,8 @@ def schema_option(cfg):
2828
2823
 
2829
2824
  scparam(cfg, ['option', 'breakpoint'],
2830
2825
  sctype='bool',
2831
- scope='job',
2832
- pernode='optional',
2826
+ scope=Scope.JOB,
2827
+ pernode=PerNode.OPTIONAL,
2833
2828
  shorthelp="Option: breakpoint list",
2834
2829
  switch="-breakpoint <bool>",
2835
2830
  example=[
@@ -2843,8 +2838,8 @@ def schema_option(cfg):
2843
2838
 
2844
2839
  scparam(cfg, ['option', 'library'],
2845
2840
  sctype='[str]',
2846
- scope='job',
2847
- pernode='optional',
2841
+ scope=Scope.JOB,
2842
+ pernode=PerNode.OPTIONAL,
2848
2843
  shorthelp="Option: library list",
2849
2844
  switch="-library <str>",
2850
2845
  example=["cli: -library lambdalib_asap7",
@@ -2855,7 +2850,7 @@ def schema_option(cfg):
2855
2850
  # Booleans
2856
2851
  scparam(cfg, ['option', 'clean'],
2857
2852
  sctype='bool',
2858
- scope='job',
2853
+ scope=Scope.JOB,
2859
2854
  shorthelp="Option: cleanup previous job",
2860
2855
  switch="-clean <bool>",
2861
2856
  example=["cli: -clean",
@@ -2868,7 +2863,7 @@ def schema_option(cfg):
2868
2863
 
2869
2864
  scparam(cfg, ['option', 'hash'],
2870
2865
  sctype='bool',
2871
- scope='job',
2866
+ scope=Scope.JOB,
2872
2867
  shorthelp="Option: file hashing",
2873
2868
  switch="-hash <bool>",
2874
2869
  example=["cli: -hash",
@@ -2880,7 +2875,7 @@ def schema_option(cfg):
2880
2875
 
2881
2876
  scparam(cfg, ['option', 'nodisplay'],
2882
2877
  sctype='bool',
2883
- scope='job',
2878
+ scope=Scope.JOB,
2884
2879
  shorthelp="Option: headless execution",
2885
2880
  switch="-nodisplay <bool>",
2886
2881
  example=["cli: -nodisplay",
@@ -2891,8 +2886,8 @@ def schema_option(cfg):
2891
2886
 
2892
2887
  scparam(cfg, ['option', 'quiet'],
2893
2888
  sctype='bool',
2894
- pernode='optional',
2895
- scope='job',
2889
+ pernode=PerNode.OPTIONAL,
2890
+ scope=Scope.JOB,
2896
2891
  shorthelp="Option: quiet execution",
2897
2892
  switch="-quiet <bool>",
2898
2893
  example=["cli: -quiet",
@@ -2904,7 +2899,7 @@ def schema_option(cfg):
2904
2899
 
2905
2900
  scparam(cfg, ['option', 'jobincr'],
2906
2901
  sctype='bool',
2907
- scope='job',
2902
+ scope=Scope.JOB,
2908
2903
  shorthelp="Option: autoincrement jobname",
2909
2904
  switch="-jobincr <bool>",
2910
2905
  example=["cli: -jobincr",
@@ -2918,9 +2913,9 @@ def schema_option(cfg):
2918
2913
 
2919
2914
  scparam(cfg, ['option', 'novercheck'],
2920
2915
  sctype='bool',
2921
- pernode='optional',
2916
+ pernode=PerNode.OPTIONAL,
2922
2917
  defvalue=False,
2923
- scope='job',
2918
+ scope=Scope.JOB,
2924
2919
  shorthelp="Option: disable version checking",
2925
2920
  switch="-novercheck <bool>",
2926
2921
  example=["cli: -novercheck",
@@ -2932,8 +2927,8 @@ def schema_option(cfg):
2932
2927
 
2933
2928
  scparam(cfg, ['option', 'track'],
2934
2929
  sctype='bool',
2935
- pernode='optional',
2936
- scope='job',
2930
+ pernode=PerNode.OPTIONAL,
2931
+ scope=Scope.JOB,
2937
2932
  shorthelp="Option: enable provenance tracking",
2938
2933
  switch="-track <bool>",
2939
2934
  example=["cli: -track",
@@ -2947,7 +2942,7 @@ def schema_option(cfg):
2947
2942
 
2948
2943
  scparam(cfg, ['option', 'entrypoint'],
2949
2944
  sctype='str',
2950
- pernode='optional',
2945
+ pernode=PerNode.OPTIONAL,
2951
2946
  shorthelp="Option: program entry point",
2952
2947
  switch="-entrypoint <str>",
2953
2948
  example=["cli: -entrypoint top",
@@ -3041,7 +3036,7 @@ def schema_option(cfg):
3041
3036
 
3042
3037
  scparam(cfg, ['option', 'continue'],
3043
3038
  sctype='bool',
3044
- pernode='optional',
3039
+ pernode=PerNode.OPTIONAL,
3045
3040
  shorthelp='Option: continue-on-error',
3046
3041
  switch='-continue <bool>',
3047
3042
  example=["cli: -continue",
@@ -3056,8 +3051,8 @@ def schema_option(cfg):
3056
3051
 
3057
3052
  scparam(cfg, ['option', 'timeout'],
3058
3053
  sctype='float',
3059
- pernode='optional',
3060
- scope='job',
3054
+ pernode=PerNode.OPTIONAL,
3055
+ scope=Scope.JOB,
3061
3056
  unit='s',
3062
3057
  shorthelp="Option: timeout value",
3063
3058
  switch="-timeout <float>",
@@ -3084,8 +3079,8 @@ def schema_option(cfg):
3084
3079
  scparam(cfg, ['option', 'scheduler', 'name'],
3085
3080
  sctype='enum',
3086
3081
  enum=["slurm", "lsf", "sge", "docker"],
3087
- scope='job',
3088
- pernode='optional',
3082
+ scope=Scope.JOB,
3083
+ pernode=PerNode.OPTIONAL,
3089
3084
  shorthelp="Option: scheduler platform",
3090
3085
  switch="-scheduler <str>",
3091
3086
  example=[
@@ -3096,14 +3091,14 @@ def schema_option(cfg):
3096
3091
  flowgraph steps. If the parameter is undefined, the steps are executed
3097
3092
  on the same machine that the SC was launched on. If 'slurm' is used,
3098
3093
  the host running the 'sc' command must be running a 'slurmctld' daemon
3099
- managing a Slurm cluster. Additionally, the build directory ('-dir')
3100
- must be located in shared storage which can be accessed by all hosts
3101
- in the cluster.""")
3094
+ managing a Slurm cluster. Additionally, the build directory
3095
+ (:keypath:`option,builddir`) must be located in shared storage which
3096
+ can be accessed by all hosts in the cluster.""")
3102
3097
 
3103
3098
  scparam(cfg, ['option', 'scheduler', 'cores'],
3104
3099
  sctype='int',
3105
- scope='job',
3106
- pernode='optional',
3100
+ scope=Scope.JOB,
3101
+ pernode=PerNode.OPTIONAL,
3107
3102
  shorthelp="Option: Scheduler core constraint",
3108
3103
  switch="-cores <int>",
3109
3104
  example=["cli: -cores 48",
@@ -3117,8 +3112,8 @@ def schema_option(cfg):
3117
3112
  scparam(cfg, ['option', 'scheduler', 'memory'],
3118
3113
  sctype='int',
3119
3114
  unit='MB',
3120
- scope='job',
3121
- pernode='optional',
3115
+ scope=Scope.JOB,
3116
+ pernode=PerNode.OPTIONAL,
3122
3117
  shorthelp="Option: scheduler memory constraint",
3123
3118
  switch="-memory <int>",
3124
3119
  example=["cli: -memory 8000",
@@ -3131,8 +3126,8 @@ def schema_option(cfg):
3131
3126
 
3132
3127
  scparam(cfg, ['option', 'scheduler', 'queue'],
3133
3128
  sctype='str',
3134
- scope='job',
3135
- pernode='optional',
3129
+ scope=Scope.JOB,
3130
+ pernode=PerNode.OPTIONAL,
3136
3131
  shorthelp="Option: scheduler queue",
3137
3132
  switch="-queue <str>",
3138
3133
  example=["cli: -queue nightrun",
@@ -3145,8 +3140,8 @@ def schema_option(cfg):
3145
3140
 
3146
3141
  scparam(cfg, ['option', 'scheduler', 'defer'],
3147
3142
  sctype='str',
3148
- scope='job',
3149
- pernode='optional',
3143
+ scope=Scope.JOB,
3144
+ pernode=PerNode.OPTIONAL,
3150
3145
  shorthelp="Option: scheduler start time",
3151
3146
  switch="-defer <str>",
3152
3147
  example=["cli: -defer 16:00",
@@ -3161,7 +3156,7 @@ def schema_option(cfg):
3161
3156
 
3162
3157
  scparam(cfg, ['option', 'scheduler', 'options'],
3163
3158
  sctype='[str]',
3164
- pernode='optional',
3159
+ pernode=PerNode.OPTIONAL,
3165
3160
  shorthelp="Option: scheduler arguments",
3166
3161
  switch="-scheduler_options <str>",
3167
3162
  example=[
@@ -3176,8 +3171,8 @@ def schema_option(cfg):
3176
3171
  scparam(cfg, ['option', 'scheduler', 'msgevent'],
3177
3172
  sctype='[enum]',
3178
3173
  enum=['all', 'summary', 'begin', 'end', 'timeout', 'fail'],
3179
- scope='job',
3180
- pernode='optional',
3174
+ scope=Scope.JOB,
3175
+ pernode=PerNode.OPTIONAL,
3181
3176
  shorthelp="Option: message event trigger",
3182
3177
  switch="-msgevent <str>",
3183
3178
  example=[
@@ -3198,8 +3193,8 @@ def schema_option(cfg):
3198
3193
 
3199
3194
  scparam(cfg, ['option', 'scheduler', 'msgcontact'],
3200
3195
  sctype='[str]',
3201
- scope='job',
3202
- pernode='optional',
3196
+ scope=Scope.JOB,
3197
+ pernode=PerNode.OPTIONAL,
3203
3198
  shorthelp="Option: message contact",
3204
3199
  switch="-msgcontact <str>",
3205
3200
  example=[
@@ -3232,7 +3227,7 @@ def schema_package(cfg):
3232
3227
 
3233
3228
  scparam(cfg, ['package', 'version'],
3234
3229
  sctype='str',
3235
- scope='global',
3230
+ scope=Scope.GLOBAL,
3236
3231
  shorthelp="Package: version",
3237
3232
  switch="-package_version <str>",
3238
3233
  example=[
@@ -3243,7 +3238,7 @@ def schema_package(cfg):
3243
3238
 
3244
3239
  scparam(cfg, ['package', 'description'],
3245
3240
  sctype='str',
3246
- scope='global',
3241
+ scope=Scope.GLOBAL,
3247
3242
  shorthelp="Package: description",
3248
3243
  switch="-package_description <str>",
3249
3244
  example=[
@@ -3254,7 +3249,7 @@ def schema_package(cfg):
3254
3249
 
3255
3250
  scparam(cfg, ['package', 'keyword'],
3256
3251
  sctype='str',
3257
- scope='global',
3252
+ scope=Scope.GLOBAL,
3258
3253
  shorthelp="Package: keyword",
3259
3254
  switch="-package_keyword <str>",
3260
3255
  example=[
@@ -3263,7 +3258,7 @@ def schema_package(cfg):
3263
3258
  schelp="""Package keyword(s) used to characterize package.""")
3264
3259
  scparam(cfg, ['package', 'doc', 'homepage'],
3265
3260
  sctype='str',
3266
- scope='global',
3261
+ scope=Scope.GLOBAL,
3267
3262
  shorthelp="Package: documentation homepage",
3268
3263
  switch="-package_doc_homepage <str>",
3269
3264
  example=[
@@ -3287,7 +3282,7 @@ def schema_package(cfg):
3287
3282
  for item in doctypes:
3288
3283
  scparam(cfg, ['package', 'doc', item],
3289
3284
  sctype='[file]',
3290
- scope='global',
3285
+ scope=Scope.GLOBAL,
3291
3286
  shorthelp=f"Package: {item} document",
3292
3287
  switch=f"-package_doc_{item} <file>",
3293
3288
  example=[
@@ -3297,7 +3292,7 @@ def schema_package(cfg):
3297
3292
 
3298
3293
  scparam(cfg, ['package', 'license'],
3299
3294
  sctype='[str]',
3300
- scope='global',
3295
+ scope=Scope.GLOBAL,
3301
3296
  shorthelp="Package: license identifiers",
3302
3297
  switch="-package_license <str>",
3303
3298
  example=[
@@ -3307,7 +3302,7 @@ def schema_package(cfg):
3307
3302
 
3308
3303
  scparam(cfg, ['package', 'licensefile'],
3309
3304
  sctype='[file]',
3310
- scope='global',
3305
+ scope=Scope.GLOBAL,
3311
3306
  shorthelp="Package: license files",
3312
3307
  switch="-package_licensefile <file>",
3313
3308
  example=[
@@ -3319,7 +3314,7 @@ def schema_package(cfg):
3319
3314
 
3320
3315
  scparam(cfg, ['package', 'organization'],
3321
3316
  sctype='[str]',
3322
- scope='global',
3317
+ scope=Scope.GLOBAL,
3323
3318
  shorthelp="Package: sponsoring organization",
3324
3319
  switch="-package_organization <str>",
3325
3320
  example=[
@@ -3338,7 +3333,7 @@ def schema_package(cfg):
3338
3333
  for item in record:
3339
3334
  scparam(cfg, ['package', 'author', userid, item],
3340
3335
  sctype='str',
3341
- scope='global',
3336
+ scope=Scope.GLOBAL,
3342
3337
  shorthelp=f"Package: author {item}",
3343
3338
  switch=f"-package_author_{item} 'userid <str>'",
3344
3339
  example=[
@@ -3351,7 +3346,7 @@ def schema_package(cfg):
3351
3346
 
3352
3347
  scparam(cfg, ['package', 'source', source, 'path'],
3353
3348
  sctype='str',
3354
- scope='global',
3349
+ scope=Scope.GLOBAL,
3355
3350
  shorthelp="Package: data source path",
3356
3351
  switch="-package_source_path 'source <str>'",
3357
3352
  example=[
@@ -3375,7 +3370,7 @@ def schema_package(cfg):
3375
3370
 
3376
3371
  scparam(cfg, ['package', 'source', source, 'ref'],
3377
3372
  sctype='str',
3378
- scope='global',
3373
+ scope=Scope.GLOBAL,
3379
3374
  shorthelp="Package: data source reference",
3380
3375
  switch="-package_source_ref 'source <str>'",
3381
3376
  example=[
@@ -3397,7 +3392,7 @@ def schema_checklist(cfg):
3397
3392
 
3398
3393
  scparam(cfg, ['checklist', standard, item, 'description'],
3399
3394
  sctype='str',
3400
- scope='global',
3395
+ scope=Scope.GLOBAL,
3401
3396
  shorthelp="Checklist: item description",
3402
3397
  switch="-checklist_description 'standard item <str>'",
3403
3398
  example=[
@@ -3408,7 +3403,7 @@ def schema_checklist(cfg):
3408
3403
 
3409
3404
  scparam(cfg, ['checklist', standard, item, 'requirement'],
3410
3405
  sctype='str',
3411
- scope='global',
3406
+ scope=Scope.GLOBAL,
3412
3407
  shorthelp="Checklist: item requirement",
3413
3408
  switch="-checklist_requirement 'standard item <str>'",
3414
3409
  example=[
@@ -3420,7 +3415,7 @@ def schema_checklist(cfg):
3420
3415
 
3421
3416
  scparam(cfg, ['checklist', standard, item, 'dataformat'],
3422
3417
  sctype='str',
3423
- scope='global',
3418
+ scope=Scope.GLOBAL,
3424
3419
  shorthelp="Checklist: item data format",
3425
3420
  switch="-checklist_dataformat 'standard item <str>'",
3426
3421
  example=[
@@ -3432,7 +3427,7 @@ def schema_checklist(cfg):
3432
3427
 
3433
3428
  scparam(cfg, ['checklist', standard, item, 'rationale'],
3434
3429
  sctype='[str]',
3435
- scope='global',
3430
+ scope=Scope.GLOBAL,
3436
3431
  shorthelp="Checklist: item rational",
3437
3432
  switch="-checklist_rationale 'standard item <str>'",
3438
3433
  example=[
@@ -3445,7 +3440,7 @@ def schema_checklist(cfg):
3445
3440
 
3446
3441
  scparam(cfg, ['checklist', standard, item, 'criteria'],
3447
3442
  sctype='[str]',
3448
- scope='global',
3443
+ scope=Scope.GLOBAL,
3449
3444
  shorthelp="Checklist: item criteria",
3450
3445
  switch="-checklist_criteria 'standard item <str>'",
3451
3446
  example=[
@@ -3459,7 +3454,7 @@ def schema_checklist(cfg):
3459
3454
 
3460
3455
  scparam(cfg, ['checklist', standard, item, 'task'],
3461
3456
  sctype='[(str,str,str)]',
3462
- scope='global',
3457
+ scope=Scope.GLOBAL,
3463
3458
  shorthelp="Checklist: item task",
3464
3459
  switch="-checklist_task 'standard item <(str,str,str)>'",
3465
3460
  example=[
@@ -3472,7 +3467,7 @@ def schema_checklist(cfg):
3472
3467
 
3473
3468
  scparam(cfg, ['checklist', standard, item, 'report'],
3474
3469
  sctype='[file]',
3475
- scope='global',
3470
+ scope=Scope.GLOBAL,
3476
3471
  shorthelp="Checklist: item report",
3477
3472
  switch="-checklist_report 'standard item <file>'",
3478
3473
  example=[
@@ -3484,7 +3479,7 @@ def schema_checklist(cfg):
3484
3479
 
3485
3480
  scparam(cfg, ['checklist', standard, item, 'waiver', metric],
3486
3481
  sctype='[file]',
3487
- scope='global',
3482
+ scope=Scope.GLOBAL,
3488
3483
  shorthelp="Checklist: item metric waivers",
3489
3484
  switch="-checklist_waiver 'standard item metric <file>'",
3490
3485
  example=[
@@ -3496,7 +3491,7 @@ def schema_checklist(cfg):
3496
3491
 
3497
3492
  scparam(cfg, ['checklist', standard, item, 'ok'],
3498
3493
  sctype='bool',
3499
- scope='global',
3494
+ scope=Scope.GLOBAL,
3500
3495
  shorthelp="Checklist: item ok",
3501
3496
  switch="-checklist_ok 'standard item <bool>'",
3502
3497
  example=[
@@ -3518,8 +3513,8 @@ def schema_asic(cfg):
3518
3513
 
3519
3514
  scparam(cfg, ['asic', 'logiclib'],
3520
3515
  sctype='[str]',
3521
- scope='job',
3522
- pernode='optional',
3516
+ scope=Scope.JOB,
3517
+ pernode=PerNode.OPTIONAL,
3523
3518
  shorthelp="ASIC: logic libraries",
3524
3519
  switch="-asic_logiclib <str>",
3525
3520
  example=["cli: -asic_logiclib nangate45",
@@ -3530,8 +3525,8 @@ def schema_asic(cfg):
3530
3525
 
3531
3526
  scparam(cfg, ['asic', 'macrolib'],
3532
3527
  sctype='[str]',
3533
- scope='job',
3534
- pernode='optional',
3528
+ scope=Scope.JOB,
3529
+ pernode=PerNode.OPTIONAL,
3535
3530
  shorthelp="ASIC: macro libraries",
3536
3531
  switch="-asic_macrolib <str>",
3537
3532
  example=["cli: -asic_macrolib sram64x1024",
@@ -3543,8 +3538,8 @@ def schema_asic(cfg):
3543
3538
 
3544
3539
  scparam(cfg, ['asic', 'delaymodel'],
3545
3540
  sctype='str',
3546
- scope='job',
3547
- pernode='optional',
3541
+ scope=Scope.JOB,
3542
+ pernode=PerNode.OPTIONAL,
3548
3543
  shorthelp="ASIC: delay model",
3549
3544
  switch="-asic_delaymodel <str>",
3550
3545
  example=["cli: -asic_delaymodel ccs",
@@ -3570,7 +3565,7 @@ def schema_asic(cfg):
3570
3565
  for item in names:
3571
3566
  scparam(cfg, ['asic', 'cells', item],
3572
3567
  sctype='[str]',
3573
- pernode='optional',
3568
+ pernode=PerNode.OPTIONAL,
3574
3569
  shorthelp=f"ASIC: {item} cell list",
3575
3570
  switch=f"-asic_cells_{item} '<str>'",
3576
3571
  example=[
@@ -3584,7 +3579,7 @@ def schema_asic(cfg):
3584
3579
 
3585
3580
  scparam(cfg, ['asic', 'libarch'],
3586
3581
  sctype='str',
3587
- pernode='optional',
3582
+ pernode=PerNode.OPTIONAL,
3588
3583
  shorthelp="ASIC: library architecture",
3589
3584
  switch="-asic_libarch '<str>'",
3590
3585
  example=[
@@ -3598,7 +3593,7 @@ def schema_asic(cfg):
3598
3593
  libarch = 'default'
3599
3594
  scparam(cfg, ['asic', 'site', libarch],
3600
3595
  sctype='[str]',
3601
- pernode='optional',
3596
+ pernode=PerNode.OPTIONAL,
3602
3597
  shorthelp="ASIC: library sites",
3603
3598
  switch="-asic_site 'libarch <str>'",
3604
3599
  example=[
@@ -3622,9 +3617,9 @@ def schema_constraint(cfg):
3622
3617
  pin = 'default'
3623
3618
  scparam(cfg, ['constraint', 'timing', scenario, 'voltage', pin],
3624
3619
  sctype='float',
3625
- pernode='optional',
3620
+ pernode=PerNode.OPTIONAL,
3626
3621
  unit='V',
3627
- scope='job',
3622
+ scope=Scope.JOB,
3628
3623
  shorthelp="Constraint: pin voltage level",
3629
3624
  switch="-constraint_timing_voltage 'scenario pin <float>'",
3630
3625
  example=["cli: -constraint_timing_voltage 'worst VDD 0.9'",
@@ -3633,9 +3628,9 @@ def schema_constraint(cfg):
3633
3628
 
3634
3629
  scparam(cfg, ['constraint', 'timing', scenario, 'temperature'],
3635
3630
  sctype='float',
3636
- pernode='optional',
3631
+ pernode=PerNode.OPTIONAL,
3637
3632
  unit='C',
3638
- scope='job',
3633
+ scope=Scope.JOB,
3639
3634
  shorthelp="Constraint: temperature",
3640
3635
  switch="-constraint_timing_temperature 'scenario <float>'",
3641
3636
  example=["cli: -constraint_timing_temperature 'worst 125'",
@@ -3644,8 +3639,8 @@ def schema_constraint(cfg):
3644
3639
 
3645
3640
  scparam(cfg, ['constraint', 'timing', scenario, 'libcorner'],
3646
3641
  sctype='[str]',
3647
- pernode='optional',
3648
- scope='job',
3642
+ pernode=PerNode.OPTIONAL,
3643
+ scope=Scope.JOB,
3649
3644
  shorthelp="Constraint: library corner",
3650
3645
  switch="-constraint_timing_libcorner 'scenario <str>'",
3651
3646
  example=["cli: -constraint_timing_libcorner 'worst ttt'",
@@ -3655,8 +3650,8 @@ def schema_constraint(cfg):
3655
3650
 
3656
3651
  scparam(cfg, ['constraint', 'timing', scenario, 'pexcorner'],
3657
3652
  sctype='str',
3658
- pernode='optional',
3659
- scope='job',
3653
+ pernode=PerNode.OPTIONAL,
3654
+ scope=Scope.JOB,
3660
3655
  shorthelp="Constraint: pex corner",
3661
3656
  switch="-constraint_timing_pexcorner 'scenario <str>'",
3662
3657
  example=["cli: -constraint_timing_pexcorner 'worst max'",
@@ -3666,8 +3661,8 @@ def schema_constraint(cfg):
3666
3661
 
3667
3662
  scparam(cfg, ['constraint', 'timing', scenario, 'opcond'],
3668
3663
  sctype='str',
3669
- pernode='optional',
3670
- scope='job',
3664
+ pernode=PerNode.OPTIONAL,
3665
+ scope=Scope.JOB,
3671
3666
  shorthelp="Constraint: operating condition",
3672
3667
  switch="-constraint_timing_opcond 'scenario <str>'",
3673
3668
  example=["cli: -constraint_timing_opcond 'worst typical_1.0'",
@@ -3678,8 +3673,8 @@ def schema_constraint(cfg):
3678
3673
 
3679
3674
  scparam(cfg, ['constraint', 'timing', scenario, 'mode'],
3680
3675
  sctype='str',
3681
- pernode='optional',
3682
- scope='job',
3676
+ pernode=PerNode.OPTIONAL,
3677
+ scope=Scope.JOB,
3683
3678
  shorthelp="Constraint: operating mode",
3684
3679
  switch="-constraint_timing_mode 'scenario <str>'",
3685
3680
  example=["cli: -constraint_timing_mode 'worst test'",
@@ -3689,8 +3684,8 @@ def schema_constraint(cfg):
3689
3684
 
3690
3685
  scparam(cfg, ['constraint', 'timing', scenario, 'file'],
3691
3686
  sctype='[file]',
3692
- pernode='optional',
3693
- scope='job',
3687
+ pernode=PerNode.OPTIONAL,
3688
+ scope=Scope.JOB,
3694
3689
  copy=True,
3695
3690
  shorthelp="Constraint: SDC files",
3696
3691
  switch="-constraint_timing_file 'scenario <file>'",
@@ -3704,8 +3699,8 @@ def schema_constraint(cfg):
3704
3699
 
3705
3700
  scparam(cfg, ['constraint', 'timing', scenario, 'check'],
3706
3701
  sctype='[str]',
3707
- pernode='optional',
3708
- scope='job',
3702
+ pernode=PerNode.OPTIONAL,
3703
+ scope=Scope.JOB,
3709
3704
  shorthelp="Constraint: timing checks",
3710
3705
  switch="-constraint_timing_check 'scenario <str>'",
3711
3706
  example=[
@@ -3724,7 +3719,7 @@ def schema_constraint(cfg):
3724
3719
 
3725
3720
  scparam(cfg, ['constraint', 'component', inst, 'placement'],
3726
3721
  sctype='(float,float)',
3727
- pernode='optional',
3722
+ pernode=PerNode.OPTIONAL,
3728
3723
  unit='um',
3729
3724
  shorthelp="Constraint: component placement",
3730
3725
  switch="-constraint_component_placement 'inst <(float,float)>'",
@@ -3739,20 +3734,21 @@ def schema_constraint(cfg):
3739
3734
 
3740
3735
  scparam(cfg, ['constraint', 'component', inst, 'partname'],
3741
3736
  sctype='str',
3742
- pernode='optional',
3737
+ pernode=PerNode.OPTIONAL,
3743
3738
  shorthelp="Constraint: component part name",
3744
3739
  switch="-constraint_component_partname 'inst <str>'",
3745
3740
  example=[
3746
3741
  "cli: -constraint_component_partname 'i0 filler_x1'",
3747
3742
  "api: chip.set('constraint', 'component', 'i0', 'partname', 'filler_x1')"],
3748
3743
  schelp="""
3749
- Part name of the instance. The parameter is required for instances
3750
- that are not contained within the design netlist (ie. physical only cells).
3751
- """)
3744
+ Name of the model, type, or variant of the placed component. In the chip
3745
+ design domain, 'partname' is synonymous to 'cellname' or 'cell'. The
3746
+ 'partname' is required for instances that are not represented within
3747
+ the design netlist (ie. physical only cells).""")
3752
3748
 
3753
3749
  scparam(cfg, ['constraint', 'component', inst, 'halo'],
3754
3750
  sctype='(float,float)',
3755
- pernode='optional',
3751
+ pernode=PerNode.OPTIONAL,
3756
3752
  unit='um',
3757
3753
  shorthelp="Constraint: component halo",
3758
3754
  switch="-constraint_component_halo 'inst <(float,float)>'",
@@ -3765,7 +3761,7 @@ def schema_constraint(cfg):
3765
3761
 
3766
3762
  scparam(cfg, ['constraint', 'component', inst, 'rotation'],
3767
3763
  sctype='enum',
3768
- pernode='optional',
3764
+ pernode=PerNode.OPTIONAL,
3769
3765
  defvalue='R0',
3770
3766
  enum=['R0', 'R90', 'R180', 'R270',
3771
3767
  'MX', 'MX_R90', 'MX_R180', 'MX_R270',
@@ -3808,21 +3804,21 @@ def schema_constraint(cfg):
3808
3804
 
3809
3805
  scparam(cfg, ['constraint', 'component', inst, 'substrate'],
3810
3806
  sctype='str',
3811
- pernode='optional',
3807
+ pernode=PerNode.OPTIONAL,
3812
3808
  shorthelp="Constraint: component substrate",
3813
3809
  switch="-constraint_component_substrate 'inst <str>'",
3814
3810
  example=[
3815
3811
  "cli: -constraint_component_substrate 'i0 pcb0'",
3816
3812
  "api: chip.set('constraint', 'component', 'i0', 'substrate', 'pcb0')"],
3817
3813
  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.""")
3814
+ Name of physical substrates instance that components are placed upon.
3815
+ Any flat surface can serve as a substrate (eg. wafers, dies, panels, PCBs,
3816
+ substrates, interposers).""")
3821
3817
 
3822
3818
  scparam(cfg, ['constraint', 'component', inst, 'side'],
3823
3819
  sctype='enum',
3824
3820
  enum=['left', 'right', 'front', 'back', 'top', 'bottom'],
3825
- pernode='optional',
3821
+ pernode=PerNode.OPTIONAL,
3826
3822
  shorthelp="Constraint: component side",
3827
3823
  switch="-constraint_component_side 'inst <str>'",
3828
3824
  example=[
@@ -3830,13 +3826,13 @@ def schema_constraint(cfg):
3830
3826
  "api: chip.set('constraint', 'component', 'i0', 'side', 'top')"],
3831
3827
  schelp="""
3832
3828
  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.
3829
+ is defined with respect to a viewer looking sideways at an object.
3834
3830
  Top is towards the sky, front is the side closest to the viewer, and
3835
3831
  right is right. The maximum number of sides per substrate is six""")
3836
3832
 
3837
3833
  scparam(cfg, ['constraint', 'component', inst, 'zheight'],
3838
3834
  sctype='float',
3839
- pernode='optional',
3835
+ pernode=PerNode.OPTIONAL,
3840
3836
  unit='um',
3841
3837
  shorthelp="Constraint: component placement zheight",
3842
3838
  switch="-constraint_component_zheight 'inst <float>'",
@@ -3853,7 +3849,7 @@ def schema_constraint(cfg):
3853
3849
  name = 'default'
3854
3850
  scparam(cfg, ['constraint', 'pin', name, 'placement'],
3855
3851
  sctype='(float,float)',
3856
- pernode='optional',
3852
+ pernode=PerNode.OPTIONAL,
3857
3853
  unit='um',
3858
3854
  shorthelp="Constraint: pin placement",
3859
3855
  switch="-constraint_pin_placement 'name <(float,float)>'",
@@ -3868,32 +3864,45 @@ def schema_constraint(cfg):
3868
3864
  may adjust sizes to meet competing goals such as manufacturing design
3869
3865
  rules and grid placement guidelines.""")
3870
3866
 
3871
- metrics = {'width': ['width', 1.0],
3872
- 'length': ['length', 1.0],
3873
- 'height': ['height', 1.0]
3874
- }
3867
+ scparam(cfg, ['constraint', 'pin', name, 'width'],
3868
+ sctype='float',
3869
+ unit='um',
3870
+ pernode=PerNode.OPTIONAL,
3871
+ shorthelp="Constraint: pin width",
3872
+ switch="-constraint_pin_width 'name <float>'",
3873
+ example=[
3874
+ "cli: -constraint_pin_width 'nreset 1.0'",
3875
+ "api: chip.set('constraint', 'pin', 'nreset', 'width', 1.0)"],
3876
+ schelp="""
3877
+ Pin width constraint. Package pin width is the lateral
3878
+ (side-to-side) thickness of a pin on a physical component.
3879
+ This parameter represents goal/intent, not an exact
3880
+ specification. The layout system may adjust dimensions to meet
3881
+ competing goals such as manufacturing design rules and grid placement
3882
+ guidelines.""")
3875
3883
 
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.""")
3884
+ scparam(cfg, ['constraint', 'pin', name, 'length'],
3885
+ sctype='float',
3886
+ unit='um',
3887
+ pernode=PerNode.OPTIONAL,
3888
+ shorthelp="Constraint: pin length",
3889
+ switch="-constraint_pin_length 'name <float>'",
3890
+ example=[
3891
+ "cli: -constraint_pin_length 'nreset 1.0'",
3892
+ "api: chip.set('constraint', 'pin', 'nreset', 'length', 1.0)"],
3893
+ schelp="""
3894
+ Pin length constraint. Package pin length refers to the
3895
+ length of the electrical pins extending out from (or into)
3896
+ a component. This parameter represents goal/intent, not an exact
3897
+ specification. The layout system may adjust dimensions to meet
3898
+ competing goals such as manufacturing design rules and grid placement
3899
+ guidelines.""")
3891
3900
 
3892
3901
  scparam(cfg, ['constraint', 'pin', name, 'shape'],
3893
3902
  sctype='enum',
3894
3903
  enum=['circle', 'rectangle', 'square',
3895
3904
  'hexagon', 'octagon', 'oval', 'pill', 'polygon'],
3896
- pernode='optional',
3905
+ pernode=PerNode.OPTIONAL,
3897
3906
  shorthelp="Constraint: pin shape",
3898
3907
  switch="-constraint_pin_shape 'name <str>'",
3899
3908
  example=[
@@ -3908,20 +3917,21 @@ def schema_constraint(cfg):
3908
3917
 
3909
3918
  scparam(cfg, ['constraint', 'pin', name, 'layer'],
3910
3919
  sctype='str',
3911
- pernode='optional',
3920
+ pernode=PerNode.OPTIONAL,
3912
3921
  shorthelp="Constraint: pin layer",
3913
3922
  switch="-constraint_pin_layer 'name <str>'",
3914
3923
  example=[
3915
3924
  "cli: -constraint_pin_layer 'nreset m4'",
3916
3925
  "api: chip.set('constraint', 'pin', 'nreset', 'layer', 'm4')"],
3917
3926
  schelp="""
3918
- Pin metal layer specified based on the SC standard layer stack
3919
- starting with m1 as the lowest routing layer and ending
3920
- with m<n> as the highest routing layer.""")
3927
+ Pin metal layer constraint specified on a per pin basis.
3928
+ Metal names should either be the PDK specific metal stack name or
3929
+ an integer with '1' being the lowest routing layer.
3930
+ The wildcard character '*' is supported for pin names.""")
3921
3931
 
3922
3932
  scparam(cfg, ['constraint', 'pin', name, 'side'],
3923
3933
  sctype='int',
3924
- pernode='optional',
3934
+ pernode=PerNode.OPTIONAL,
3925
3935
  shorthelp="Constraint: pin side",
3926
3936
  switch="-constraint_pin_side 'name <int>'",
3927
3937
  example=[
@@ -3937,7 +3947,7 @@ def schema_constraint(cfg):
3937
3947
 
3938
3948
  scparam(cfg, ['constraint', 'pin', name, 'order'],
3939
3949
  sctype='int',
3940
- pernode='optional',
3950
+ pernode=PerNode.OPTIONAL,
3941
3951
  shorthelp="Constraint: pin order",
3942
3952
  switch="-constraint_pin_order 'name <int>'",
3943
3953
  example=[
@@ -3953,7 +3963,7 @@ def schema_constraint(cfg):
3953
3963
  # NETS
3954
3964
  scparam(cfg, ['constraint', 'net', name, 'maxlength'],
3955
3965
  sctype='float',
3956
- pernode='optional',
3966
+ pernode=PerNode.OPTIONAL,
3957
3967
  unit='um',
3958
3968
  shorthelp="Constraint: net max length",
3959
3969
  switch="-constraint_net_maxlength 'name <float>'",
@@ -3966,7 +3976,7 @@ def schema_constraint(cfg):
3966
3976
 
3967
3977
  scparam(cfg, ['constraint', 'net', name, 'maxresistance'],
3968
3978
  sctype='float',
3969
- pernode='optional',
3979
+ pernode=PerNode.OPTIONAL,
3970
3980
  unit='ohm',
3971
3981
  shorthelp="Constraint: net max resistance",
3972
3982
  switch="-constraint_net_maxresistance 'name <float>'",
@@ -3979,7 +3989,7 @@ def schema_constraint(cfg):
3979
3989
 
3980
3990
  scparam(cfg, ['constraint', 'net', name, 'ndr'],
3981
3991
  sctype='(float,float)',
3982
- pernode='optional',
3992
+ pernode=PerNode.OPTIONAL,
3983
3993
  unit='um',
3984
3994
  shorthelp="Constraint: net routing rule",
3985
3995
  switch="-constraint_net_ndr 'name <(float,float)>'",
@@ -3993,7 +4003,7 @@ def schema_constraint(cfg):
3993
4003
 
3994
4004
  scparam(cfg, ['constraint', 'net', name, 'minlayer'],
3995
4005
  sctype='str',
3996
- pernode='optional',
4006
+ pernode=PerNode.OPTIONAL,
3997
4007
  shorthelp="Constraint: net minimum routing layer",
3998
4008
  switch="-constraint_net_minlayer 'name <str>'",
3999
4009
  example=[
@@ -4007,7 +4017,7 @@ def schema_constraint(cfg):
4007
4017
 
4008
4018
  scparam(cfg, ['constraint', 'net', name, 'maxlayer'],
4009
4019
  sctype='str',
4010
- pernode='optional',
4020
+ pernode=PerNode.OPTIONAL,
4011
4021
  shorthelp="Constraint: net maximum routing layer",
4012
4022
  switch="-constraint_net_maxlayer 'name <str>'",
4013
4023
  example=[
@@ -4021,7 +4031,7 @@ def schema_constraint(cfg):
4021
4031
 
4022
4032
  scparam(cfg, ['constraint', 'net', name, 'shield'],
4023
4033
  sctype='str',
4024
- pernode='optional',
4034
+ pernode=PerNode.OPTIONAL,
4025
4035
  shorthelp="Constraint: net shielding",
4026
4036
  switch="-constraint_net_shield 'name <str>'",
4027
4037
  example=[
@@ -4033,7 +4043,7 @@ def schema_constraint(cfg):
4033
4043
 
4034
4044
  scparam(cfg, ['constraint', 'net', name, 'match'],
4035
4045
  sctype='[str]',
4036
- pernode='optional',
4046
+ pernode=PerNode.OPTIONAL,
4037
4047
  shorthelp="Constraint: net matched routing",
4038
4048
  switch="-constraint_net_match 'name <str>'",
4039
4049
  example=[
@@ -4046,7 +4056,7 @@ def schema_constraint(cfg):
4046
4056
 
4047
4057
  scparam(cfg, ['constraint', 'net', name, 'diffpair'],
4048
4058
  sctype='str',
4049
- pernode='optional',
4059
+ pernode=PerNode.OPTIONAL,
4050
4060
  shorthelp="Constraint: net diffpair",
4051
4061
  switch="-constraint_net_diffpair 'name <str>'",
4052
4062
  example=[
@@ -4058,7 +4068,7 @@ def schema_constraint(cfg):
4058
4068
 
4059
4069
  scparam(cfg, ['constraint', 'net', name, 'sympair'],
4060
4070
  sctype='str',
4061
- pernode='optional',
4071
+ pernode=PerNode.OPTIONAL,
4062
4072
  shorthelp="Constraint: net sympair",
4063
4073
  switch="-constraint_net_sympair 'name <str>'",
4064
4074
  example=[
@@ -4072,9 +4082,9 @@ def schema_constraint(cfg):
4072
4082
  # AREA
4073
4083
  scparam(cfg, ['constraint', 'outline'],
4074
4084
  sctype='[(float,float)]',
4075
- pernode='optional',
4085
+ pernode=PerNode.OPTIONAL,
4076
4086
  unit='um',
4077
- scope='job',
4087
+ scope=Scope.JOB,
4078
4088
  shorthelp="Constraint: layout outline",
4079
4089
  switch="-constraint_outline <(float,float)>",
4080
4090
  example=["cli: -constraint_outline '(0,0)'",
@@ -4086,9 +4096,9 @@ def schema_constraint(cfg):
4086
4096
 
4087
4097
  scparam(cfg, ['constraint', 'corearea'],
4088
4098
  sctype='[(float,float)]',
4089
- pernode='optional',
4099
+ pernode=PerNode.OPTIONAL,
4090
4100
  unit='um',
4091
- scope='job',
4101
+ scope=Scope.JOB,
4092
4102
  shorthelp="Constraint: layout core area",
4093
4103
  switch="-constraint_corearea <(float,float)>",
4094
4104
  example=["cli: -constraint_corearea '(0,0)'",
@@ -4100,9 +4110,9 @@ def schema_constraint(cfg):
4100
4110
 
4101
4111
  scparam(cfg, ['constraint', 'coremargin'],
4102
4112
  sctype='float',
4103
- pernode='optional',
4113
+ pernode=PerNode.OPTIONAL,
4104
4114
  unit='um',
4105
- scope='job',
4115
+ scope=Scope.JOB,
4106
4116
  shorthelp="Constraint: layout core margin",
4107
4117
  switch="-constraint_coremargin <float>",
4108
4118
  example=["cli: -constraint_coremargin 1",
@@ -4113,8 +4123,8 @@ def schema_constraint(cfg):
4113
4123
 
4114
4124
  scparam(cfg, ['constraint', 'density'],
4115
4125
  sctype='float',
4116
- pernode='optional',
4117
- scope='job',
4126
+ pernode=PerNode.OPTIONAL,
4127
+ scope=Scope.JOB,
4118
4128
  shorthelp="Constraint: layout density",
4119
4129
  switch="-constraint_density <float>",
4120
4130
  example=["cli: -constraint_density 30",
@@ -4128,9 +4138,9 @@ def schema_constraint(cfg):
4128
4138
 
4129
4139
  scparam(cfg, ['constraint', 'aspectratio'],
4130
4140
  sctype='float',
4131
- pernode='optional',
4141
+ pernode=PerNode.OPTIONAL,
4132
4142
  defvalue='1.0',
4133
- scope='job',
4143
+ scope=Scope.JOB,
4134
4144
  shorthelp="Constraint: layout aspect ratio",
4135
4145
  switch="-constraint_aspectratio <float>",
4136
4146
  example=["cli: -constraint_aspectratio 2.0",