siliconcompiler 0.34.1__py3-none-any.whl → 0.34.3__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 (129) hide show
  1. siliconcompiler/__init__.py +23 -4
  2. siliconcompiler/__main__.py +1 -7
  3. siliconcompiler/_metadata.py +1 -1
  4. siliconcompiler/apps/_common.py +104 -23
  5. siliconcompiler/apps/sc.py +4 -8
  6. siliconcompiler/apps/sc_dashboard.py +6 -4
  7. siliconcompiler/apps/sc_install.py +10 -6
  8. siliconcompiler/apps/sc_issue.py +7 -5
  9. siliconcompiler/apps/sc_remote.py +1 -1
  10. siliconcompiler/apps/sc_server.py +9 -14
  11. siliconcompiler/apps/sc_show.py +7 -6
  12. siliconcompiler/apps/smake.py +130 -94
  13. siliconcompiler/apps/utils/replay.py +4 -7
  14. siliconcompiler/apps/utils/summarize.py +3 -5
  15. siliconcompiler/asic.py +420 -0
  16. siliconcompiler/checklist.py +25 -2
  17. siliconcompiler/cmdlineschema.py +534 -0
  18. siliconcompiler/constraints/__init__.py +17 -0
  19. siliconcompiler/constraints/asic_component.py +378 -0
  20. siliconcompiler/constraints/asic_floorplan.py +449 -0
  21. siliconcompiler/constraints/asic_pins.py +489 -0
  22. siliconcompiler/constraints/asic_timing.py +517 -0
  23. siliconcompiler/core.py +10 -35
  24. siliconcompiler/data/templates/tcl/manifest.tcl.j2 +8 -0
  25. siliconcompiler/dependencyschema.py +96 -202
  26. siliconcompiler/design.py +327 -241
  27. siliconcompiler/filesetschema.py +250 -0
  28. siliconcompiler/flowgraph.py +298 -106
  29. siliconcompiler/fpga.py +124 -1
  30. siliconcompiler/library.py +331 -0
  31. siliconcompiler/metric.py +327 -92
  32. siliconcompiler/metrics/__init__.py +7 -0
  33. siliconcompiler/metrics/asic.py +245 -0
  34. siliconcompiler/metrics/fpga.py +220 -0
  35. siliconcompiler/package/__init__.py +391 -67
  36. siliconcompiler/package/git.py +92 -16
  37. siliconcompiler/package/github.py +114 -22
  38. siliconcompiler/package/https.py +79 -16
  39. siliconcompiler/packageschema.py +341 -16
  40. siliconcompiler/pathschema.py +255 -0
  41. siliconcompiler/pdk.py +566 -1
  42. siliconcompiler/project.py +1460 -0
  43. siliconcompiler/record.py +38 -1
  44. siliconcompiler/remote/__init__.py +5 -2
  45. siliconcompiler/remote/client.py +11 -6
  46. siliconcompiler/remote/schema.py +5 -23
  47. siliconcompiler/remote/server.py +41 -54
  48. siliconcompiler/report/__init__.py +3 -3
  49. siliconcompiler/report/dashboard/__init__.py +48 -14
  50. siliconcompiler/report/dashboard/cli/__init__.py +99 -21
  51. siliconcompiler/report/dashboard/cli/board.py +364 -179
  52. siliconcompiler/report/dashboard/web/__init__.py +90 -12
  53. siliconcompiler/report/dashboard/web/components/__init__.py +219 -240
  54. siliconcompiler/report/dashboard/web/components/flowgraph.py +49 -26
  55. siliconcompiler/report/dashboard/web/components/graph.py +139 -100
  56. siliconcompiler/report/dashboard/web/layouts/__init__.py +29 -1
  57. siliconcompiler/report/dashboard/web/layouts/_common.py +38 -2
  58. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph.py +39 -26
  59. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_node_tab.py +50 -50
  60. siliconcompiler/report/dashboard/web/layouts/vertical_flowgraph_sac_tabs.py +49 -46
  61. siliconcompiler/report/dashboard/web/state.py +141 -14
  62. siliconcompiler/report/dashboard/web/utils/__init__.py +79 -16
  63. siliconcompiler/report/dashboard/web/utils/file_utils.py +74 -11
  64. siliconcompiler/report/dashboard/web/viewer.py +25 -1
  65. siliconcompiler/report/report.py +5 -2
  66. siliconcompiler/report/summary_image.py +29 -11
  67. siliconcompiler/scheduler/__init__.py +9 -1
  68. siliconcompiler/scheduler/docker.py +81 -4
  69. siliconcompiler/scheduler/run_node.py +37 -20
  70. siliconcompiler/scheduler/scheduler.py +211 -36
  71. siliconcompiler/scheduler/schedulernode.py +394 -60
  72. siliconcompiler/scheduler/send_messages.py +77 -29
  73. siliconcompiler/scheduler/slurm.py +76 -12
  74. siliconcompiler/scheduler/taskscheduler.py +142 -21
  75. siliconcompiler/schema/__init__.py +0 -4
  76. siliconcompiler/schema/baseschema.py +338 -59
  77. siliconcompiler/schema/editableschema.py +14 -6
  78. siliconcompiler/schema/journal.py +28 -17
  79. siliconcompiler/schema/namedschema.py +22 -14
  80. siliconcompiler/schema/parameter.py +89 -28
  81. siliconcompiler/schema/parametertype.py +2 -0
  82. siliconcompiler/schema/parametervalue.py +258 -15
  83. siliconcompiler/schema/safeschema.py +25 -2
  84. siliconcompiler/schema/schema_cfg.py +23 -19
  85. siliconcompiler/schema/utils.py +2 -2
  86. siliconcompiler/schema_obj.py +24 -5
  87. siliconcompiler/tool.py +1131 -265
  88. siliconcompiler/tools/bambu/__init__.py +41 -0
  89. siliconcompiler/tools/builtin/concatenate.py +2 -2
  90. siliconcompiler/tools/builtin/minimum.py +2 -1
  91. siliconcompiler/tools/builtin/mux.py +2 -1
  92. siliconcompiler/tools/builtin/nop.py +2 -1
  93. siliconcompiler/tools/builtin/verify.py +2 -1
  94. siliconcompiler/tools/klayout/__init__.py +95 -0
  95. siliconcompiler/tools/openroad/__init__.py +289 -0
  96. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +3 -0
  97. siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +7 -2
  98. siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +8 -4
  99. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +9 -5
  100. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +5 -1
  101. siliconcompiler/tools/slang/__init__.py +1 -1
  102. siliconcompiler/tools/slang/elaborate.py +2 -1
  103. siliconcompiler/tools/vivado/scripts/sc_run.tcl +1 -1
  104. siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +8 -1
  105. siliconcompiler/tools/vivado/syn_fpga.py +6 -0
  106. siliconcompiler/tools/vivado/vivado.py +35 -2
  107. siliconcompiler/tools/vpr/__init__.py +150 -0
  108. siliconcompiler/tools/yosys/__init__.py +369 -1
  109. siliconcompiler/tools/yosys/scripts/procs.tcl +0 -1
  110. siliconcompiler/toolscripts/_tools.json +5 -10
  111. siliconcompiler/utils/__init__.py +66 -0
  112. siliconcompiler/utils/flowgraph.py +2 -2
  113. siliconcompiler/utils/issue.py +2 -1
  114. siliconcompiler/utils/logging.py +14 -0
  115. siliconcompiler/utils/multiprocessing.py +256 -0
  116. siliconcompiler/utils/showtools.py +10 -0
  117. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/METADATA +6 -6
  118. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/RECORD +122 -115
  119. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/entry_points.txt +3 -0
  120. siliconcompiler/schema/cmdlineschema.py +0 -250
  121. siliconcompiler/schema/packageschema.py +0 -101
  122. siliconcompiler/toolscripts/rhel8/install-slang.sh +0 -40
  123. siliconcompiler/toolscripts/rhel9/install-slang.sh +0 -40
  124. siliconcompiler/toolscripts/ubuntu20/install-slang.sh +0 -47
  125. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -37
  126. siliconcompiler/toolscripts/ubuntu24/install-slang.sh +0 -37
  127. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/WHEEL +0 -0
  128. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/licenses/LICENSE +0 -0
  129. {siliconcompiler-0.34.1.dist-info → siliconcompiler-0.34.3.dist-info}/top_level.txt +0 -0
siliconcompiler/pdk.py CHANGED
@@ -2,19 +2,584 @@ from siliconcompiler.schema import NamedSchema
2
2
  from siliconcompiler.schema import EditableSchema, Parameter, Scope
3
3
  from siliconcompiler.schema.utils import trim
4
4
 
5
+ from siliconcompiler import ToolLibrarySchema
5
6
 
6
- class PDKSchema(NamedSchema):
7
+
8
+ class PDKSchema(ToolLibrarySchema):
9
+ """
10
+ A class for managing Process Design Kit (PDK) schemas.
11
+ """
12
+ def __init__(self, name: str = None):
13
+ """
14
+ Initializes a PDKSchema object.
15
+
16
+ Args:
17
+ name (str, optional): The name of the PDK. Defaults to None.
18
+ """
19
+ super().__init__()
20
+ self.set_name(name)
21
+
22
+ schema = EditableSchema(self)
23
+
24
+ schema.insert(
25
+ "pdk", 'foundry',
26
+ Parameter(
27
+ 'str',
28
+ scope=Scope.GLOBAL,
29
+ shorthelp="PDK: foundry name",
30
+ switch="-pdk_foundry 'pdkname <str>'",
31
+ example=["cli: -pdk_foundry 'asap7 virtual'",
32
+ "api: chip.set('pdk', 'asap7', 'foundry', 'virtual')"],
33
+ help=trim("""
34
+ Name of foundry corporation. Examples include intel, gf, tsmc,
35
+ samsung, skywater, virtual. The \'virtual\' keyword is reserved for
36
+ simulated non-manufacturable processes.""")))
37
+
38
+ schema.insert(
39
+ "pdk", 'node',
40
+ Parameter(
41
+ 'float',
42
+ scope=Scope.GLOBAL,
43
+ unit='nm',
44
+ shorthelp="PDK: process node",
45
+ switch="-pdk_node 'pdkname <float>'",
46
+ example=["cli: -pdk_node 'asap7 130'",
47
+ "api: chip.set('pdk', 'asap7', 'node', 130)"],
48
+ help=trim("""
49
+ Approximate relative minimum dimension of the process target specified
50
+ in nanometers. The parameter is required for flows and tools that
51
+ leverage the value to drive technology dependent synthesis and APR
52
+ optimization. Node examples include 180, 130, 90, 65, 45, 32, 22 14,
53
+ 10, 7, 5, 3.""")))
54
+
55
+ schema.insert(
56
+ "pdk", 'stackup',
57
+ Parameter(
58
+ 'str',
59
+ scope=Scope.GLOBAL,
60
+ shorthelp="PDK: metal stackups",
61
+ switch="-pdk_stackup 'pdkname <str>'",
62
+ example=["cli: -pdk_stackup 'asap7 2MA4MB2MC'",
63
+ "api: chip.add('pdk', 'asap7', 'stackup', '2MA4MB2MC')"],
64
+ help=trim("""
65
+ List of all metal stackups offered in the process node. Older process
66
+ nodes may only offer a single metal stackup, while advanced nodes
67
+ offer a large but finite list of metal stacks with varying combinations
68
+ of metal line pitches and thicknesses. Stackup naming is unique to a
69
+ foundry, but is generally a long string or code. For example, a 10
70
+ metal stackup with two 1x wide, four 2x wide, and 4x wide metals,
71
+ might be identified as 2MA4MB2MC, where MA, MB, and MC denote wiring
72
+ layers with different properties (thickness, width, space). Each
73
+ stackup will come with its own set of routing technology files and
74
+ parasitic models specified in the pdk_pexmodel and pdk_aprtech
75
+ parameters.""")))
76
+
77
+ schema.insert(
78
+ "pdk", 'minlayer',
79
+ Parameter(
80
+ 'str',
81
+ scope=Scope.GLOBAL,
82
+ shorthelp="PDK: minimum routing layer",
83
+ switch="-pdk_minlayer 'pdk stackup <str>'",
84
+ example=[
85
+ "cli: -pdk_minlayer 'asap7 2MA4MB2MC M2'",
86
+ "api: chip.set('pdk', 'asap7', 'minlayer', '2MA4MB2MC', 'M2')"],
87
+ help=trim("""
88
+ Minimum metal layer to be used for automated place and route
89
+ specified on a per stackup basis.""")))
90
+
91
+ schema.insert(
92
+ "pdk", 'maxlayer',
93
+ Parameter(
94
+ 'str',
95
+ scope=Scope.GLOBAL,
96
+ shorthelp="PDK: maximum routing layer",
97
+ switch="-pdk_maxlayer 'pdk stackup <str>'",
98
+ example=[
99
+ "cli: -pdk_maxlayer 'asap7 2MA4MB2MC M8'",
100
+ "api: chip.set('pdk', 'asap7', 'maxlayer', 'MA4MB2MC', 'M8')"],
101
+ help=trim("""
102
+ Maximum metal layer to be used for automated place and route
103
+ specified on a per stackup basis.""")))
104
+
105
+ schema.insert(
106
+ "pdk", 'wafersize',
107
+ Parameter(
108
+ 'float',
109
+ scope=Scope.GLOBAL,
110
+ unit='mm',
111
+ shorthelp="PDK: wafer size",
112
+ switch="-pdk_wafersize 'pdkname <float>'",
113
+ example=["cli: -pdk_wafersize 'asap7 300'",
114
+ "api: chip.set('pdk', 'asap7', 'wafersize', 300)"],
115
+ help=trim("""
116
+ Wafer diameter used in wafer based manufacturing process.
117
+ The standard diameter for leading edge manufacturing is 300mm. For
118
+ older process technologies and specialty fabs, smaller diameters
119
+ such as 200, 150, 125, and 100 are common. The value is used to
120
+ calculate dies per wafer and full factory chip costs.""")))
121
+
122
+ schema.insert(
123
+ "pdk", 'unitcost',
124
+ Parameter(
125
+ 'float',
126
+ scope=Scope.GLOBAL,
127
+ unit='USD',
128
+ shorthelp="PDK: unit cost",
129
+ switch="-pdk_unitcost 'pdkname <float>'",
130
+ example=["cli: -pdk_unitcost 'asap7 10000'",
131
+ "api: chip.set('pdk', 'asap7', 'unitcost', 10000)"],
132
+ help=trim("""
133
+ Raw cost per unit shipped by the factory, not accounting for yield
134
+ loss.""")))
135
+
136
+ schema.insert(
137
+ "pdk", 'd0',
138
+ Parameter(
139
+ 'float',
140
+ scope=Scope.GLOBAL,
141
+ shorthelp="PDK: process defect density",
142
+ switch="-pdk_d0 'pdkname <float>'",
143
+ example=["cli: -pdk_d0 'asap7 0.1'",
144
+ "api: chip.set('pdk', 'asap7', 'd0', 0.1)"],
145
+ help=trim("""
146
+ Process defect density (d0) expressed as random defects per cm^2. The
147
+ value is used to calculate yield losses as a function of area, which in
148
+ turn affects the chip full factory costs. Two yield models are
149
+ supported: Poisson (default), and Murphy. The Poisson based yield is
150
+ calculated as dy = exp(-area * d0/100). The Murphy based yield is
151
+ calculated as dy = ((1-exp(-area * d0/100))/(area * d0/100))^2.""")))
152
+
153
+ schema.insert(
154
+ "pdk", 'scribe',
155
+ Parameter(
156
+ '(float,float)',
157
+ scope=Scope.GLOBAL,
158
+ unit='mm',
159
+ shorthelp="PDK: horizontal scribe line width",
160
+ switch="-pdk_scribe 'pdkname <(float,float)>'",
161
+ example=["cli: -pdk_scribe 'asap7 (0.1,0.1)'",
162
+ "api: chip.set('pdk', 'asap7', 'scribe', (0.1, 0.1))"],
163
+ help=trim("""
164
+ Width of the horizontal and vertical scribe line used during die separation.
165
+ The process is generally completed using a mechanical saw, but can be
166
+ done through combinations of mechanical saws, lasers, wafer thinning,
167
+ and chemical etching in more advanced technologies. The value is used
168
+ to calculate effective dies per wafer and full factory cost.""")))
169
+
170
+ schema.insert(
171
+ "pdk", 'edgemargin',
172
+ Parameter(
173
+ 'float',
174
+ scope=Scope.GLOBAL,
175
+ unit='mm',
176
+ shorthelp="PDK: wafer edge keep-out margin",
177
+ switch="-pdk_edgemargin 'pdkname <float>'",
178
+ example=[
179
+ "cli: -pdk_edgemargin 'asap7 1'",
180
+ "api: chip.set('pdk', 'asap7', 'edgemargin', 1)"],
181
+ help=trim("""
182
+ Keep-out distance/margin from the edge inwards. The edge
183
+ is prone to chipping and need special treatment that preclude
184
+ placement of designs in this area. The edge value is used to
185
+ calculate effective units per wafer/panel and full factory cost.""")))
186
+
187
+ tool = 'default'
188
+ simtype = 'default'
189
+ schema.insert(
190
+ "pdk", 'devmodelfileset', tool, simtype,
191
+ Parameter(
192
+ '[str]',
193
+ scope=Scope.GLOBAL,
194
+ shorthelp="PDK: device models",
195
+ switch="-pdk_devmodel 'pdkname tool simtype stackup <file>'",
196
+ example=[
197
+ "cli: -pdk_devmodel 'asap7 xyce spice M10 asap7.sp'",
198
+ "api: chip.set('devmodel', 'xyce', 'spice', 'M10', 'asap7.sp')"],
199
+ help=trim("""
200
+ List of filepaths to PDK device models for different simulation
201
+ purposes and for different tools. Examples of device model types
202
+ include spice, aging, electromigration, radiation. An example of a
203
+ 'spice' tool is xyce. Device models are specified on a per metal stack
204
+ basis. Process nodes with a single device model across all stacks will
205
+ have a unique parameter record per metal stack pointing to the same
206
+ device model file. Device types and tools are dynamic entries
207
+ that depend on the tool setup and device technology. Pseudo-standardized
208
+ device types include spice, em (electromigration), and aging.""")))
209
+
210
+ corner = 'default'
211
+ schema.insert(
212
+ "pdk", 'pexmodelfileset', tool, corner,
213
+ Parameter(
214
+ '[str]',
215
+ scope=Scope.GLOBAL,
216
+ shorthelp="PDK: parasitic TCAD models",
217
+ switch="-pdk_pexmodel 'pdkname tool stackup corner <file>'",
218
+ example=[
219
+ "cli: -pdk_pexmodel 'asap7 fastcap M10 max wire.mod'",
220
+ "api: chip.set('pdk', 'asap7', 'pexmodel', 'fastcap', 'M10', 'max', "
221
+ "'wire.mod')"],
222
+ help=trim("""
223
+ List of filepaths to PDK wire TCAD models used during automated
224
+ synthesis, APR, and signoff verification. Pexmodels are specified on
225
+ a per metal stack basis. Corner values depend on the process being
226
+ used, but typically include nomenclature such as min, max, nominal.
227
+ For exact names, refer to the DRM. Pexmodels are generally not
228
+ standardized and specified on a per tool basis. An example of pexmodel
229
+ type is 'fastcap'.""")))
230
+
231
+ src = 'default'
232
+ dst = 'default'
233
+ schema.insert(
234
+ "pdk", 'layermapfileset', tool, src, dst,
235
+ Parameter(
236
+ '[str]',
237
+ scope=Scope.GLOBAL,
238
+ shorthelp="PDK: layer map file",
239
+ switch="-pdk_layermap 'pdkname tool src dst stackup <file>'",
240
+ example=[
241
+ "cli: -pdk_layermap 'asap7 klayout db gds M10 asap7.map'",
242
+ "api: chip.set('pdk', 'asap7', 'layermap', 'klayout', 'db', 'gds', 'M10', "
243
+ "'asap7.map')"],
244
+ help=trim("""
245
+ Files describing input/output mapping for streaming layout data from
246
+ one format to another. A foundry PDK will include an official layer
247
+ list for all user entered and generated layers supported in the GDS
248
+ accepted by the foundry for processing, but there is no standardized
249
+ layer definition format that can be read and written by all EDA tools.
250
+ To ensure mask layer matching, key/value type mapping files are needed
251
+ to convert EDA databases to/from GDS and to convert between different
252
+ types of EDA databases. Layer maps are specified on a per metal
253
+ stackup basis. The 'src' and 'dst' can be names of SC supported tools
254
+ or file formats (like 'gds').""")))
255
+
256
+ schema.insert(
257
+ "pdk", 'displayfileset', tool,
258
+ Parameter(
259
+ '[str]',
260
+ scope=Scope.GLOBAL,
261
+ shorthelp="PDK: display file",
262
+ switch="-pdk_display 'pdkname tool stackup <file>'",
263
+ example=[
264
+ "cli: -pdk_display 'asap7 klayout M10 display.lyt'",
265
+ "api: chip.set('pdk', 'asap7', 'display', 'klayout', 'M10', 'display.cfg')"],
266
+ help=trim("""
267
+ Display configuration files describing colors and pattern schemes for
268
+ all layers in the PDK. The display configuration file is entered on a
269
+ stackup and tool basis.""")))
270
+
271
+ # TODO: create firm list of accepted files
272
+ schema.insert(
273
+ "pdk", 'aprtechfileset', tool,
274
+ Parameter(
275
+ '[str]',
276
+ scope=Scope.GLOBAL,
277
+ shorthelp="PDK: APR technology files",
278
+ switch="-pdk_aprtech 'pdkname tool stackup libarch filetype <file>'",
279
+ example=[
280
+ "cli: -pdk_aprtech 'asap7 openroad M10 12t lef tech.lef'",
281
+ "api: chip.set('pdk', 'asap7', 'aprtech', 'openroad', 'M10', '12t', 'lef', "
282
+ "'tech.lef')"],
283
+ help=trim("""
284
+ Technology file containing setup information needed to enable DRC clean APR
285
+ for the specified stackup, libarch, and format. The 'libarch' specifies the
286
+ library architecture (e.g. library height). For example a PDK with support
287
+ for 9 and 12 track libraries might have 'libarchs' called 9t and 12t.
288
+ The standard filetype for specifying place and route design rules for a
289
+ process node is through a 'lef' format technology file. The
290
+ 'filetype' used in the aprtech is used by the tool specific APR TCL scripts
291
+ to set up the technology parameters. Some tools may require additional
292
+ files beyond the tech.lef file. Examples of extra file types include
293
+ antenna, tracks, tapcell, viarules, and em.""")))
294
+
295
+ name = 'default'
296
+ for item in ('lvs', 'drc', 'erc', 'fill'):
297
+ schema.insert(
298
+ "pdk", item, 'runsetfileset', tool, name,
299
+ Parameter(
300
+ '[str]',
301
+ scope=Scope.GLOBAL,
302
+ shorthelp=f"PDK: {item.upper()} runset files",
303
+ switch=f"-pdk_{item}_runset 'pdkname tool stackup name <file>'",
304
+ example=[
305
+ f"cli: -pdk_{item}_runset 'asap7 magic M10 basic $PDK/{item}.rs'",
306
+ f"api: chip.set('{item}', 'runset', 'magic', 'M10', 'basic', "
307
+ f"'$PDK/{item}.rs')"],
308
+ help=trim(f"""Runset files for {item.upper()} task.""")))
309
+
310
+ schema.insert(
311
+ "pdk", item, 'waiverfileset', tool, name,
312
+ Parameter(
313
+ '[str]',
314
+ scope=Scope.GLOBAL,
315
+ shorthelp=f"PDK: {item.upper()} waiver files",
316
+ switch=f"-pdk_{item}_waiver 'pdkname tool stackup name <file>'",
317
+ example=[
318
+ f"cli: -pdk_{item}_waiver 'asap7 magic M10 basic $PDK/{item}.txt'",
319
+ f"api: chip.set('{item}', 'waiver', 'magic', 'M10', 'basic', "
320
+ f"'$PDK/{item}.txt')"],
321
+ help=trim(f"""Waiver files for {item.upper()} task.""")))
322
+
323
+ def set_foundry(self, foundry: str):
324
+ """
325
+ Sets the foundry name for the PDK.
326
+
327
+ Args:
328
+ foundry (str): The name of the foundry.
329
+ """
330
+ return self.set("pdk", "foundry", foundry)
331
+
332
+ def set_node(self, node: float):
333
+ """
334
+ Sets the process node for the PDK.
335
+
336
+ Args:
337
+ node (float): The process node in nanometers.
338
+ """
339
+ return self.set("pdk", "node", node)
340
+
341
+ def set_stackup(self, stackup: str):
342
+ """
343
+ Sets the metal stackup for the PDK.
344
+
345
+ Args:
346
+ stackup (str): The name of the metal stackup.
347
+ """
348
+ return self.set("pdk", "stackup", stackup)
349
+
350
+ def set_wafersize(self, wafersize: float):
351
+ """
352
+ Sets the wafer size for the PDK.
353
+
354
+ Args:
355
+ wafersize (float): The wafer diameter in millimeters.
356
+ """
357
+ return self.set("pdk", "wafersize", wafersize)
358
+
359
+ def set_unitcost(self, unitcost: float):
360
+ """
361
+ Sets the unit cost for the PDK.
362
+
363
+ Args:
364
+ unitcost (float): The unit cost in USD.
365
+ """
366
+ return self.set("pdk", "unitcost", unitcost)
367
+
368
+ def set_defectdensity(self, d0: float):
369
+ """
370
+ Sets the process defect density for the PDK.
371
+
372
+ Args:
373
+ d0 (float): The defect density (defects per cm^2).
374
+ """
375
+ return self.set("pdk", "d0", d0)
376
+
377
+ def set_scribewidth(self, x: float, y: float):
378
+ """
379
+ Sets the scribe line width for the PDK.
380
+
381
+ Args:
382
+ x (float): The horizontal scribe width in millimeters.
383
+ y (float): The vertical scribe width in millimeters.
384
+ """
385
+ return self.set("pdk", "scribe", (x, y))
386
+
387
+ def set_edgemargin(self, margin: float):
388
+ """
389
+ Sets the wafer edge keep-out margin for the PDK.
390
+
391
+ Args:
392
+ margin (float): The edge margin in millimeters.
393
+ """
394
+ return self.set("pdk", "edgemargin", margin)
395
+
396
+ def set_aprroutinglayers(self, min: str = None, max: str = None):
397
+ """
398
+ Sets the minimum and maximum routing layers for the PDK.
399
+
400
+ Args:
401
+ min (str, optional): The minimum routing layer name. Defaults to None.
402
+ max (str, optional): The maximum routing layer name. Defaults to None.
403
+ """
404
+ if min:
405
+ self.set("pdk", "minlayer", min)
406
+ if max:
407
+ self.set("pdk", "maxlayer", max)
408
+
409
+ def add_aprtechfileset(self, tool: str, fileset: str = None, clobber: bool = False):
410
+ """
411
+ Adds a fileset containing APR technology files.
412
+
413
+ Args:
414
+ tool (str): The name of the tool.
415
+ fileset (str, optional): The name of the fileset. Defaults to None,
416
+ which uses the active fileset.
417
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
418
+ """
419
+ if not fileset:
420
+ fileset = self._get_active("fileset")
421
+
422
+ self._assert_fileset(fileset)
423
+
424
+ if clobber:
425
+ return self.set("pdk", "aprtechfileset", tool, fileset)
426
+ else:
427
+ return self.add("pdk", "aprtechfileset", tool, fileset)
428
+
429
+ def add_layermapfileset(self, tool: str, src: str, dst: str, fileset: str = None,
430
+ clobber: bool = False):
431
+ """
432
+ Adds a fileset containing layer map files.
433
+
434
+ Args:
435
+ tool (str): The name of the tool.
436
+ src (str): The source format or tool name.
437
+ dst (str): The destination format or tool name.
438
+ fileset (str, optional): The name of the fileset. Defaults to None,
439
+ which uses the active fileset.
440
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
441
+ """
442
+ if not fileset:
443
+ fileset = self._get_active("fileset")
444
+
445
+ self._assert_fileset(fileset)
446
+
447
+ if clobber:
448
+ return self.set("pdk", "layermapfileset", tool, src, dst, fileset)
449
+ else:
450
+ return self.add("pdk", "layermapfileset", tool, src, dst, fileset)
451
+
452
+ def add_displayfileset(self, tool: str, fileset: str = None, clobber: bool = False):
453
+ """
454
+ Adds a fileset containing display configuration files.
455
+
456
+ Args:
457
+ tool (str): The name of the tool.
458
+ fileset (str, optional): The name of the fileset. Defaults to None,
459
+ which uses the active fileset.
460
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
461
+ """
462
+ if not fileset:
463
+ fileset = self._get_active("fileset")
464
+
465
+ self._assert_fileset(fileset)
466
+
467
+ if clobber:
468
+ return self.set("pdk", "displayfileset", tool, fileset)
469
+ else:
470
+ return self.add("pdk", "displayfileset", tool, fileset)
471
+
472
+ def add_devmodelfileset(self, tool: str, type: str, fileset: str = None,
473
+ clobber: bool = False):
474
+ """
475
+ Adds a fileset containing device model files.
476
+
477
+ Args:
478
+ tool (str): The name of the tool.
479
+ type (str): The type of the device model (e.g., 'spice').
480
+ fileset (str, optional): The name of the fileset. Defaults to None,
481
+ which uses the active fileset.
482
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
483
+ """
484
+ if not fileset:
485
+ fileset = self._get_active("fileset")
486
+
487
+ self._assert_fileset(fileset)
488
+
489
+ if clobber:
490
+ return self.set("pdk", "devmodelfileset", tool, type, fileset)
491
+ else:
492
+ return self.add("pdk", "devmodelfileset", tool, type, fileset)
493
+
494
+ def add_pexmodelfileset(self, tool: str, corner: str, fileset: str = None,
495
+ clobber: bool = False):
496
+ """
497
+ Adds a fileset containing parasitic extraction (pex) model files.
498
+
499
+ Args:
500
+ tool (str): The name of the tool.
501
+ corner (str): The corner name (e.g., 'min', 'max').
502
+ fileset (str, optional): The name of the fileset. Defaults to None,
503
+ which uses the active fileset.
504
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
505
+ """
506
+ if not fileset:
507
+ fileset = self._get_active("fileset")
508
+
509
+ self._assert_fileset(fileset)
510
+
511
+ if clobber:
512
+ return self.set("pdk", "pexmodelfileset", tool, corner, fileset)
513
+ else:
514
+ return self.add("pdk", "pexmodelfileset", tool, corner, fileset)
515
+
516
+ def add_runsetfileset(self, type: str, tool: str, name: str, fileset: str = None,
517
+ clobber: bool = False):
518
+ """
519
+ Adds a fileset containing a runset for a specific verification task.
520
+
521
+ Args:
522
+ type (str): The type of task (e.g., 'lvs', 'drc').
523
+ tool (str): The name of the tool.
524
+ name (str): The name of the runset.
525
+ fileset (str, optional): The name of the fileset. Defaults to None,
526
+ which uses the active fileset.
527
+ clobber (bool, optional): If True, overwrites existing entries. Defaults to False.
528
+ """
529
+ if not fileset:
530
+ fileset = self._get_active("fileset")
531
+
532
+ self._assert_fileset(fileset)
533
+
534
+ if clobber:
535
+ return self.set("pdk", type, "runsetfileset", tool, name, fileset)
536
+ else:
537
+ return self.add("pdk", type, "runsetfileset", tool, name, fileset)
538
+
539
+ @classmethod
540
+ def _getdict_type(cls) -> str:
541
+ """
542
+ Returns the meta data for getdict
543
+ """
544
+
545
+ return PDKSchema.__name__
546
+
547
+
548
+ class PDKSchemaTmp(NamedSchema):
549
+ """
550
+ A temporary PDK schema class for development and testing.
551
+ """
7
552
  def __init__(self, name=None):
553
+ """
554
+ Initializes a temporary PDKSchemaTmp object.
555
+
556
+ Args:
557
+ name (str, optional): The name of the PDK. Defaults to None.
558
+ """
8
559
  super().__init__()
9
560
  self.set_name(name)
10
561
 
11
562
  schema_pdk(self)
12
563
 
564
+ @classmethod
565
+ def _getdict_type(cls) -> str:
566
+ """
567
+ Returns the meta data for getdict
568
+ """
569
+
570
+ return PDKSchemaTmp.__name__
571
+
13
572
 
14
573
  ###############################################################################
15
574
  # PDK
16
575
  ###############################################################################
17
576
  def schema_pdk(schema):
577
+ """
578
+ Adds PDK schema parameters to the given schema.
579
+
580
+ Args:
581
+ schema (EditableSchema): The schema to modify.
582
+ """
18
583
  schema = EditableSchema(schema)
19
584
 
20
585
  tool = 'default'