siliconcompiler 0.36.0__py3-none-any.whl → 0.36.2__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 (56) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/asic.py +4 -4
  3. siliconcompiler/design.py +6 -1
  4. siliconcompiler/package/__init__.py +3 -2
  5. siliconcompiler/project.py +30 -14
  6. siliconcompiler/schema_support/filesetschema.py +9 -1
  7. siliconcompiler/schema_support/pathschema.py +16 -10
  8. siliconcompiler/tool.py +3 -1
  9. siliconcompiler/tools/chisel/convert.py +44 -0
  10. siliconcompiler/tools/ghdl/convert.py +37 -2
  11. siliconcompiler/tools/icarus/compile.py +14 -0
  12. siliconcompiler/tools/keplerformal/lec.py +2 -2
  13. siliconcompiler/tools/klayout/drc.py +14 -0
  14. siliconcompiler/tools/klayout/export.py +41 -1
  15. siliconcompiler/tools/klayout/operations.py +40 -0
  16. siliconcompiler/tools/openroad/__init__.py +11 -0
  17. siliconcompiler/tools/openroad/_apr.py +823 -12
  18. siliconcompiler/tools/openroad/antenna_repair.py +26 -0
  19. siliconcompiler/tools/openroad/fillmetal_insertion.py +14 -0
  20. siliconcompiler/tools/openroad/global_placement.py +67 -0
  21. siliconcompiler/tools/openroad/global_route.py +15 -0
  22. siliconcompiler/tools/openroad/init_floorplan.py +14 -0
  23. siliconcompiler/tools/openroad/macro_placement.py +252 -0
  24. siliconcompiler/tools/openroad/power_grid.py +44 -1
  25. siliconcompiler/tools/openroad/rcx_bench.py +28 -0
  26. siliconcompiler/tools/openroad/rcx_extract.py +14 -0
  27. siliconcompiler/tools/openroad/rdlroute.py +14 -0
  28. siliconcompiler/tools/openroad/repair_design.py +41 -0
  29. siliconcompiler/tools/openroad/repair_timing.py +54 -0
  30. siliconcompiler/tools/openroad/screenshot.py +31 -1
  31. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +8 -0
  32. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +5 -1
  33. siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +17 -15
  34. siliconcompiler/tools/openroad/scripts/common/write_data_timing.tcl +3 -1
  35. siliconcompiler/tools/openroad/write_data.py +76 -0
  36. siliconcompiler/tools/opensta/timing.py +37 -2
  37. siliconcompiler/tools/slang/elaborate.py +16 -1
  38. siliconcompiler/tools/surelog/parse.py +54 -0
  39. siliconcompiler/tools/verilator/compile.py +120 -0
  40. siliconcompiler/tools/vivado/syn_fpga.py +27 -0
  41. siliconcompiler/tools/vpr/__init__.py +9 -9
  42. siliconcompiler/tools/vpr/place.py +1 -2
  43. siliconcompiler/tools/vpr/route.py +40 -0
  44. siliconcompiler/tools/xdm/convert.py +14 -0
  45. siliconcompiler/tools/xyce/simulate.py +26 -0
  46. siliconcompiler/tools/yosys/lec_asic.py +13 -0
  47. siliconcompiler/tools/yosys/syn_asic.py +336 -7
  48. siliconcompiler/tools/yosys/syn_fpga.py +39 -8
  49. siliconcompiler/toolscripts/_tools.json +5 -5
  50. siliconcompiler/utils/logging.py +6 -0
  51. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/METADATA +3 -3
  52. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/RECORD +56 -56
  53. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/WHEEL +0 -0
  54. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/entry_points.txt +0 -0
  55. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/licenses/LICENSE +0 -0
  56. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,9 @@ from siliconcompiler.tools.openroad import OpenROADTask
12
12
 
13
13
 
14
14
  class OpenROADSTAParameter(OpenROADTask):
15
+ """
16
+ Mixin class for defining Static Timing Analysis (STA) parameters.
17
+ """
15
18
  def __init__(self):
16
19
  super().__init__()
17
20
 
@@ -31,6 +34,67 @@ class OpenROADSTAParameter(OpenROADTask):
31
34
  defvalue="tools/_common/sdc/sc_constraints.sdc",
32
35
  dataroot="siliconcompiler")
33
36
 
37
+ def set_openroad_earlytimingderate(self, derate: float,
38
+ step: Optional[str] = None, index: Optional[str] = None):
39
+ """
40
+ Sets the timing derating factor to use for hold corners.
41
+
42
+ Args:
43
+ derate (float): The derating factor.
44
+ step (str, optional): The specific step to apply this configuration to.
45
+ index (str, optional): The specific index to apply this configuration to.
46
+ """
47
+ self.set("var", "sta_early_timing_derate", derate, step=step, index=index)
48
+
49
+ def set_openroad_latetimingderate(self, derate: float,
50
+ step: Optional[str] = None, index: Optional[str] = None):
51
+ """
52
+ Sets the timing derating factor to use for setup corners.
53
+
54
+ Args:
55
+ derate (float): The derating factor.
56
+ step (str, optional): The specific step to apply this configuration to.
57
+ index (str, optional): The specific index to apply this configuration to.
58
+ """
59
+ self.set("var", "sta_late_timing_derate", derate, step=step, index=index)
60
+
61
+ def set_openroad_topnpaths(self, n: int,
62
+ step: Optional[str] = None, index: Optional[str] = None):
63
+ """
64
+ Sets the number of paths to report timing for.
65
+
66
+ Args:
67
+ n (int): The number of paths.
68
+ step (str, optional): The specific step to apply this configuration to.
69
+ index (str, optional): The specific index to apply this configuration to.
70
+ """
71
+ self.set("var", "sta_top_n_paths", n, step=step, index=index)
72
+
73
+ def set_openroad_definepathgroups(self, enable: bool,
74
+ step: Optional[str] = None, index: Optional[str] = None):
75
+ """
76
+ Enables or disables the generation of path groups for timing reporting.
77
+
78
+ Args:
79
+ enable (bool): True to enable, False to disable.
80
+ step (str, optional): The specific step to apply this configuration to.
81
+ index (str, optional): The specific index to apply this configuration to.
82
+ """
83
+ self.set("var", "sta_define_path_groups", enable, step=step, index=index)
84
+
85
+ def set_openroad_uniquepathgroupsperclock(self, enable: bool,
86
+ step: Optional[str] = None,
87
+ index: Optional[str] = None):
88
+ """
89
+ Enables or disables the generation of separate path groups per clock.
90
+
91
+ Args:
92
+ enable (bool): True to enable, False to disable.
93
+ step (str, optional): The specific step to apply this configuration to.
94
+ index (str, optional): The specific index to apply this configuration to.
95
+ """
96
+ self.set("var", "sta_unique_path_groups_per_clock", enable, step=step, index=index)
97
+
34
98
  def setup(self):
35
99
  super().setup()
36
100
 
@@ -43,6 +107,9 @@ class OpenROADSTAParameter(OpenROADTask):
43
107
 
44
108
 
45
109
  class OpenROADPSMParameter(OpenROADTask):
110
+ """
111
+ Mixin class for defining Power Supply Map (PSM) analysis parameters.
112
+ """
46
113
  def __init__(self):
47
114
  super().__init__()
48
115
 
@@ -50,6 +117,35 @@ class OpenROADPSMParameter(OpenROADTask):
50
117
  "true/false, when true enables IR drop analysis", defvalue=True)
51
118
  self.add_parameter("psm_skip_nets", "[str]", "list of nets to skip power grid analysis on")
52
119
 
120
+ def set_openroad_psmenable(self, enable: bool,
121
+ step: Optional[str] = None, index: Optional[str] = None):
122
+ """
123
+ Enables or disables IR drop analysis.
124
+
125
+ Args:
126
+ enable (bool): True to enable, False to disable.
127
+ step (str, optional): The specific step to apply this configuration to.
128
+ index (str, optional): The specific index to apply this configuration to.
129
+ """
130
+ self.set("var", "psm_enable", enable, step=step, index=index)
131
+
132
+ def add_openroad_psmskipnets(self, nets: Union[str, List[str]],
133
+ step: Optional[str] = None, index: Optional[str] = None,
134
+ clobber: bool = False):
135
+ """
136
+ Adds nets to skip during power grid analysis.
137
+
138
+ Args:
139
+ nets (Union[str, List[str]]): The net(s) to skip.
140
+ step (str, optional): The specific step to apply this configuration to.
141
+ index (str, optional): The specific index to apply this configuration to.
142
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
143
+ """
144
+ if clobber:
145
+ self.set("var", "psm_skip_nets", nets, step=step, index=index)
146
+ else:
147
+ self.add("var", "psm_skip_nets", nets, step=step, index=index)
148
+
53
149
  def setup(self):
54
150
  super().setup()
55
151
 
@@ -59,12 +155,49 @@ class OpenROADPSMParameter(OpenROADTask):
59
155
 
60
156
 
61
157
  class OpenROADPPLLayersParameter(OpenROADTask):
158
+ """
159
+ Mixin class for defining Pin Placement (PPL) layer parameters.
160
+ """
62
161
  def __init__(self):
63
162
  super().__init__()
64
163
 
65
164
  self.add_parameter("pin_layer_horizontal", "[str]", "layers to use for horizontal pins")
66
165
  self.add_parameter("pin_layer_vertical", "[str]", "layers to use for vertical pins")
67
166
 
167
+ def add_openroad_pinlayerhorizontal(self, layers: Union[str, List[str]],
168
+ step: Optional[str] = None, index: Optional[str] = None,
169
+ clobber: bool = False):
170
+ """
171
+ Adds layers to use for horizontal pins.
172
+
173
+ Args:
174
+ layers (Union[str, List[str]]): The layer(s) to add.
175
+ step (str, optional): The specific step to apply this configuration to.
176
+ index (str, optional): The specific index to apply this configuration to.
177
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
178
+ """
179
+ if clobber:
180
+ self.set("var", "pin_layer_horizontal", layers, step=step, index=index)
181
+ else:
182
+ self.add("var", "pin_layer_horizontal", layers, step=step, index=index)
183
+
184
+ def add_openroad_pinlayervertical(self, layers: Union[str, List[str]],
185
+ step: Optional[str] = None, index: Optional[str] = None,
186
+ clobber: bool = False):
187
+ """
188
+ Adds layers to use for vertical pins.
189
+
190
+ Args:
191
+ layers (Union[str, List[str]]): The layer(s) to add.
192
+ step (str, optional): The specific step to apply this configuration to.
193
+ index (str, optional): The specific index to apply this configuration to.
194
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
195
+ """
196
+ if clobber:
197
+ self.set("var", "pin_layer_vertical", layers, step=step, index=index)
198
+ else:
199
+ self.add("var", "pin_layer_vertical", layers, step=step, index=index)
200
+
68
201
  def setup(self):
69
202
  super().setup()
70
203
 
@@ -73,6 +206,9 @@ class OpenROADPPLLayersParameter(OpenROADTask):
73
206
 
74
207
 
75
208
  class OpenROADPPLParameter(OpenROADPPLLayersParameter):
209
+ """
210
+ Mixin class for defining Pin Placement (PPL) parameters.
211
+ """
76
212
  def __init__(self):
77
213
  super().__init__()
78
214
 
@@ -80,6 +216,40 @@ class OpenROADPPLParameter(OpenROADPPLLayersParameter):
80
216
  "additional arguments to pass along to the pin placer.")
81
217
  self.add_parameter("ppl_constraints", "[file]", "pin placement constraints scripts.")
82
218
 
219
+ def add_openroad_pplarguments(self, args: Union[str, List[str]],
220
+ step: Optional[str] = None, index: Optional[str] = None,
221
+ clobber: bool = False):
222
+ """
223
+ Adds additional arguments to pass along to the pin placer.
224
+
225
+ Args:
226
+ args (Union[str, List[str]]): The argument(s) to add.
227
+ step (str, optional): The specific step to apply this configuration to.
228
+ index (str, optional): The specific index to apply this configuration to.
229
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
230
+ """
231
+ if clobber:
232
+ self.set("var", "ppl_arguments", args, step=step, index=index)
233
+ else:
234
+ self.add("var", "ppl_arguments", args, step=step, index=index)
235
+
236
+ def add_openroad_pplconstraints(self, constraints: Union[str, List[str]],
237
+ step: Optional[str] = None, index: Optional[str] = None,
238
+ clobber: bool = False):
239
+ """
240
+ Adds pin placement constraints scripts.
241
+
242
+ Args:
243
+ constraints (Union[str, List[str]]): The constraint file(s) to add.
244
+ step (str, optional): The specific step to apply this configuration to.
245
+ index (str, optional): The specific index to apply this configuration to.
246
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
247
+ """
248
+ if clobber:
249
+ self.set("var", "ppl_constraints", constraints, step=step, index=index)
250
+ else:
251
+ self.add("var", "ppl_constraints", constraints, step=step, index=index)
252
+
83
253
  def setup(self):
84
254
  super().setup()
85
255
 
@@ -91,6 +261,9 @@ class OpenROADPPLParameter(OpenROADPPLLayersParameter):
91
261
 
92
262
 
93
263
  class OpenROADGPLParameter(OpenROADTask):
264
+ """
265
+ Mixin class for defining Global Placement (GPL) parameters.
266
+ """
94
267
  def __init__(self):
95
268
  super().__init__()
96
269
 
@@ -116,6 +289,91 @@ class OpenROADGPLParameter(OpenROADTask):
116
289
  self.add_parameter("pad_global_place", "int",
117
290
  "global placement cell padding in number of sites", defvalue=0)
118
291
 
292
+ def set_openroad_gplskipio(self, enable: bool,
293
+ step: Optional[str] = None, index: Optional[str] = None):
294
+ """
295
+ Enables or disables skipping I/O placement during global placement.
296
+
297
+ Args:
298
+ enable (bool): True to skip I/O placement, False to include it.
299
+ step (str, optional): The specific step to apply this configuration to.
300
+ index (str, optional): The specific index to apply this configuration to.
301
+ """
302
+ self.set("var", "gpl_enable_skip_io", enable, step=step, index=index)
303
+
304
+ def set_openroad_gplskipinitialplace(self, enable: bool,
305
+ step: Optional[str] = None, index: Optional[str] = None):
306
+ """
307
+ Enables or disables skipping initial placement during global placement.
308
+
309
+ Args:
310
+ enable (bool): True to skip initial placement, False to perform it.
311
+ step (str, optional): The specific step to apply this configuration to.
312
+ index (str, optional): The specific index to apply this configuration to.
313
+ """
314
+ self.set("var", "gpl_enable_skip_initial_place", enable, step=step, index=index)
315
+
316
+ def set_openroad_gpluniformplacementadjustment(self, adjustment: float,
317
+ step: Optional[str] = None,
318
+ index: Optional[str] = None):
319
+ """
320
+ Sets the uniform placement adjustment factor.
321
+
322
+ Args:
323
+ adjustment (float): The adjustment factor (0.00 - 0.99).
324
+ step (str, optional): The specific step to apply this configuration to.
325
+ index (str, optional): The specific index to apply this configuration to.
326
+ """
327
+ self.set("var", "gpl_uniform_placement_adjustment", adjustment, step=step, index=index)
328
+
329
+ def set_openroad_gpltimingdriven(self, enable: bool,
330
+ step: Optional[str] = None, index: Optional[str] = None):
331
+ """
332
+ Enables or disables timing-driven global placement.
333
+
334
+ Args:
335
+ enable (bool): True to enable, False to disable.
336
+ step (str, optional): The specific step to apply this configuration to.
337
+ index (str, optional): The specific index to apply this configuration to.
338
+ """
339
+ self.set("var", "gpl_timing_driven", enable, step=step, index=index)
340
+
341
+ def set_openroad_gplroutabilitydriven(self, enable: bool,
342
+ step: Optional[str] = None, index: Optional[str] = None):
343
+ """
344
+ Enables or disables routability-driven global placement.
345
+
346
+ Args:
347
+ enable (bool): True to enable, False to disable.
348
+ step (str, optional): The specific step to apply this configuration to.
349
+ index (str, optional): The specific index to apply this configuration to.
350
+ """
351
+ self.set("var", "gpl_routability_driven", enable, step=step, index=index)
352
+
353
+ def set_openroad_placedensity(self, density: float,
354
+ step: Optional[str] = None, index: Optional[str] = None):
355
+ """
356
+ Sets the global placement density.
357
+
358
+ Args:
359
+ density (float): The target placement density (0.0 - 1.0).
360
+ step (str, optional): The specific step to apply this configuration to.
361
+ index (str, optional): The specific index to apply this configuration to.
362
+ """
363
+ self.set("var", "place_density", density, step=step, index=index)
364
+
365
+ def set_openroad_padglobalplace(self, padding: int,
366
+ step: Optional[str] = None, index: Optional[str] = None):
367
+ """
368
+ Sets the global placement cell padding.
369
+
370
+ Args:
371
+ padding (int): The padding in number of sites.
372
+ step (str, optional): The specific step to apply this configuration to.
373
+ index (str, optional): The specific index to apply this configuration to.
374
+ """
375
+ self.set("var", "pad_global_place", padding, step=step, index=index)
376
+
119
377
  def setup(self):
120
378
  super().setup()
121
379
 
@@ -130,6 +388,9 @@ class OpenROADGPLParameter(OpenROADTask):
130
388
 
131
389
 
132
390
  class OpenROADRSZDRVParameter(OpenROADTask):
391
+ """
392
+ Mixin class for defining Resizer (RSZ) Design Rule Violation (DRV) repair parameters.
393
+ """
133
394
  def __init__(self):
134
395
  super().__init__()
135
396
 
@@ -140,6 +401,30 @@ class OpenROADRSZDRVParameter(OpenROADTask):
140
401
  "specifies the amount of margin to apply to max slew repairs in percent "
141
402
  "(0 - 100)", defvalue=0.0)
142
403
 
404
+ def set_openroad_rszcapmargin(self, margin: float,
405
+ step: Optional[str] = None, index: Optional[str] = None):
406
+ """
407
+ Sets the margin for max capacitance repairs.
408
+
409
+ Args:
410
+ margin (float): The margin in percent (0 - 100).
411
+ step (str, optional): The specific step to apply this configuration to.
412
+ index (str, optional): The specific index to apply this configuration to.
413
+ """
414
+ self.set("var", "rsz_cap_margin", margin, step=step, index=index)
415
+
416
+ def set_openroad_rszslewmargin(self, margin: float,
417
+ step: Optional[str] = None, index: Optional[str] = None):
418
+ """
419
+ Sets the margin for max slew repairs.
420
+
421
+ Args:
422
+ margin (float): The margin in percent (0 - 100).
423
+ step (str, optional): The specific step to apply this configuration to.
424
+ index (str, optional): The specific index to apply this configuration to.
425
+ """
426
+ self.set("var", "rsz_slew_margin", margin, step=step, index=index)
427
+
143
428
  def setup(self):
144
429
  super().setup()
145
430
 
@@ -148,6 +433,9 @@ class OpenROADRSZDRVParameter(OpenROADTask):
148
433
 
149
434
 
150
435
  class OpenROADRSZTimingParameter(OpenROADTask):
436
+ """
437
+ Mixin class for defining Resizer (RSZ) timing repair parameters.
438
+ """
151
439
  def __init__(self):
152
440
  super().__init__()
153
441
 
@@ -169,6 +457,78 @@ class OpenROADRSZTimingParameter(OpenROADTask):
169
457
  "percentage of paths to attempt to recover power (0 - 100)",
170
458
  defvalue=100)
171
459
 
460
+ def set_openroad_rszsetupslackmargin(self, margin: float,
461
+ step: Optional[str] = None, index: Optional[str] = None):
462
+ """
463
+ Sets the margin for setup timing repair.
464
+
465
+ Args:
466
+ margin (float): The margin in ns.
467
+ step (str, optional): The specific step to apply this configuration to.
468
+ index (str, optional): The specific index to apply this configuration to.
469
+ """
470
+ self.set("var", "rsz_setup_slack_margin", margin, step=step, index=index)
471
+
472
+ def set_openroad_rszholdslackmargin(self, margin: float,
473
+ step: Optional[str] = None, index: Optional[str] = None):
474
+ """
475
+ Sets the margin for hold timing repair.
476
+
477
+ Args:
478
+ margin (float): The margin in ns.
479
+ step (str, optional): The specific step to apply this configuration to.
480
+ index (str, optional): The specific index to apply this configuration to.
481
+ """
482
+ self.set("var", "rsz_hold_slack_margin", margin, step=step, index=index)
483
+
484
+ def set_openroad_rszskippinswap(self, skip: bool,
485
+ step: Optional[str] = None, index: Optional[str] = None):
486
+ """
487
+ Enables or disables pin swap optimization.
488
+
489
+ Args:
490
+ skip (bool): True to skip pin swap, False to perform it.
491
+ step (str, optional): The specific step to apply this configuration to.
492
+ index (str, optional): The specific index to apply this configuration to.
493
+ """
494
+ self.set("var", "rsz_skip_pin_swap", skip, step=step, index=index)
495
+
496
+ def set_openroad_rszskipgatecloning(self, skip: bool,
497
+ step: Optional[str] = None, index: Optional[str] = None):
498
+ """
499
+ Enables or disables gate cloning optimization.
500
+
501
+ Args:
502
+ skip (bool): True to skip gate cloning, False to perform it.
503
+ step (str, optional): The specific step to apply this configuration to.
504
+ index (str, optional): The specific index to apply this configuration to.
505
+ """
506
+ self.set("var", "rsz_skip_gate_cloning", skip, step=step, index=index)
507
+
508
+ def set_openroad_rszrepairtns(self, percentage: float,
509
+ step: Optional[str] = None, index: Optional[str] = None):
510
+ """
511
+ Sets the percentage of violating nets to attempt to repair.
512
+
513
+ Args:
514
+ percentage (float): The percentage (0 - 100).
515
+ step (str, optional): The specific step to apply this configuration to.
516
+ index (str, optional): The specific index to apply this configuration to.
517
+ """
518
+ self.set("var", "rsz_repair_tns", percentage, step=step, index=index)
519
+
520
+ def set_openroad_rszrecoverpower(self, percentage: float,
521
+ step: Optional[str] = None, index: Optional[str] = None):
522
+ """
523
+ Sets the percentage of paths to attempt to recover power.
524
+
525
+ Args:
526
+ percentage (float): The percentage (0 - 100).
527
+ step (str, optional): The specific step to apply this configuration to.
528
+ index (str, optional): The specific index to apply this configuration to.
529
+ """
530
+ self.set("var", "rsz_recover_power", percentage, step=step, index=index)
531
+
172
532
  def setup(self):
173
533
  super().setup()
174
534
 
@@ -181,6 +541,9 @@ class OpenROADRSZTimingParameter(OpenROADTask):
181
541
 
182
542
 
183
543
  class OpenROADDPLParameter(OpenROADTask):
544
+ """
545
+ Mixin class for defining Detailed Placement (DPL) parameters.
546
+ """
184
547
  def __init__(self):
185
548
  super().__init__()
186
549
 
@@ -190,6 +553,31 @@ class OpenROADDPLParameter(OpenROADTask):
190
553
  "maximum cell movement in detailed placement in microns, 0 will result "
191
554
  "in the tool default maximum displacement", defvalue=(0, 0))
192
555
 
556
+ def set_openroad_paddetailplace(self, padding: int,
557
+ step: Optional[str] = None, index: Optional[str] = None):
558
+ """
559
+ Sets the detailed placement cell padding.
560
+
561
+ Args:
562
+ padding (int): The padding in number of sites.
563
+ step (str, optional): The specific step to apply this configuration to.
564
+ index (str, optional): The specific index to apply this configuration to.
565
+ """
566
+ self.set("var", "pad_detail_place", padding, step=step, index=index)
567
+
568
+ def set_openroad_dplmaxdisplacement(self, x: float, y: float,
569
+ step: Optional[str] = None, index: Optional[str] = None):
570
+ """
571
+ Sets the maximum cell displacement for detailed placement.
572
+
573
+ Args:
574
+ x (float): The maximum displacement in X (microns).
575
+ y (float): The maximum displacement in Y (microns).
576
+ step (str, optional): The specific step to apply this configuration to.
577
+ index (str, optional): The specific index to apply this configuration to.
578
+ """
579
+ self.set("var", "dpl_max_displacement", (x, y), step=step, index=index)
580
+
193
581
  def setup(self):
194
582
  super().setup()
195
583
 
@@ -198,6 +586,9 @@ class OpenROADDPLParameter(OpenROADTask):
198
586
 
199
587
 
200
588
  class OpenROADFillCellsParameter(OpenROADTask):
589
+ """
590
+ Mixin class for defining filler cell insertion parameters.
591
+ """
201
592
  def __init__(self):
202
593
  super().__init__()
203
594
 
@@ -205,6 +596,18 @@ class OpenROADFillCellsParameter(OpenROADTask):
205
596
  "true/false, use decap fillers along with non-decap fillers",
206
597
  defvalue=True)
207
598
 
599
+ def set_openroad_dplusedecapfillers(self, enable: bool,
600
+ step: Optional[str] = None, index: Optional[str] = None):
601
+ """
602
+ Enables or disables the use of decap fillers.
603
+
604
+ Args:
605
+ enable (bool): True to use decap fillers, False otherwise.
606
+ step (str, optional): The specific step to apply this configuration to.
607
+ index (str, optional): The specific index to apply this configuration to.
608
+ """
609
+ self.set("var", "dpl_use_decap_fillers", enable, step=step, index=index)
610
+
208
611
  def setup(self):
209
612
  super().setup()
210
613
 
@@ -212,6 +615,9 @@ class OpenROADFillCellsParameter(OpenROADTask):
212
615
 
213
616
 
214
617
  class OpenROADDPOParameter(OpenROADTask):
618
+ """
619
+ Mixin class for defining Detailed Placement Optimization (DPO) parameters.
620
+ """
215
621
  def __init__(self):
216
622
  super().__init__()
217
623
 
@@ -223,6 +629,31 @@ class OpenROADDPOParameter(OpenROADTask):
223
629
  "0 will result in the tool default maximum displacement", unit="um",
224
630
  defvalue=(5, 5))
225
631
 
632
+ def set_openroad_dpoenable(self, enable: bool,
633
+ step: Optional[str] = None, index: Optional[str] = None):
634
+ """
635
+ Enables or disables detailed placement optimization.
636
+
637
+ Args:
638
+ enable (bool): True to enable, False to disable.
639
+ step (str, optional): The specific step to apply this configuration to.
640
+ index (str, optional): The specific index to apply this configuration to.
641
+ """
642
+ self.set("var", "dpo_enable", enable, step=step, index=index)
643
+
644
+ def set_openroad_dpomaxdisplacement(self, x: float, y: float,
645
+ step: Optional[str] = None, index: Optional[str] = None):
646
+ """
647
+ Sets the maximum cell displacement for detailed placement optimization.
648
+
649
+ Args:
650
+ x (float): The maximum displacement in X (microns).
651
+ y (float): The maximum displacement in Y (microns).
652
+ step (str, optional): The specific step to apply this configuration to.
653
+ index (str, optional): The specific index to apply this configuration to.
654
+ """
655
+ self.set("var", "dpo_max_displacement", (x, y), step=step, index=index)
656
+
226
657
  def setup(self):
227
658
  super().setup()
228
659
 
@@ -231,6 +662,9 @@ class OpenROADDPOParameter(OpenROADTask):
231
662
 
232
663
 
233
664
  class OpenROADCTSParameter(OpenROADTask):
665
+ """
666
+ Mixin class for defining Clock Tree Synthesis (CTS) parameters.
667
+ """
234
668
  def __init__(self):
235
669
  super().__init__()
236
670
 
@@ -248,6 +682,67 @@ class OpenROADCTSParameter(OpenROADTask):
248
682
  self.add_parameter("cts_obstruction_aware", "bool",
249
683
  "make clock tree synthesis aware of obstructions", defvalue=True)
250
684
 
685
+ def set_openroad_ctsdistancebetweenbuffers(self, distance: float,
686
+ step: Optional[str] = None,
687
+ index: Optional[str] = None):
688
+ """
689
+ Sets the maximum distance between buffers during CTS.
690
+
691
+ Args:
692
+ distance (float): The distance in microns.
693
+ step (str, optional): The specific step to apply this configuration to.
694
+ index (str, optional): The specific index to apply this configuration to.
695
+ """
696
+ self.set("var", "cts_distance_between_buffers", distance, step=step, index=index)
697
+
698
+ def set_openroad_ctsclusterdiameter(self, diameter: float,
699
+ step: Optional[str] = None, index: Optional[str] = None):
700
+ """
701
+ Sets the clustering diameter for CTS.
702
+
703
+ Args:
704
+ diameter (float): The diameter in microns.
705
+ step (str, optional): The specific step to apply this configuration to.
706
+ index (str, optional): The specific index to apply this configuration to.
707
+ """
708
+ self.set("var", "cts_cluster_diameter", diameter, step=step, index=index)
709
+
710
+ def set_openroad_ctsclustersize(self, size: int,
711
+ step: Optional[str] = None, index: Optional[str] = None):
712
+ """
713
+ Sets the cluster size for CTS.
714
+
715
+ Args:
716
+ size (int): The number of instances in a cluster.
717
+ step (str, optional): The specific step to apply this configuration to.
718
+ index (str, optional): The specific index to apply this configuration to.
719
+ """
720
+ self.set("var", "cts_cluster_size", size, step=step, index=index)
721
+
722
+ def set_openroad_ctsbalancelevels(self, enable: bool,
723
+ step: Optional[str] = None, index: Optional[str] = None):
724
+ """
725
+ Enables or disables level balancing during CTS.
726
+
727
+ Args:
728
+ enable (bool): True to enable, False to disable.
729
+ step (str, optional): The specific step to apply this configuration to.
730
+ index (str, optional): The specific index to apply this configuration to.
731
+ """
732
+ self.set("var", "cts_balance_levels", enable, step=step, index=index)
733
+
734
+ def set_openroad_ctsobstructionaware(self, enable: bool,
735
+ step: Optional[str] = None, index: Optional[str] = None):
736
+ """
737
+ Enables or disables obstruction-aware CTS.
738
+
739
+ Args:
740
+ enable (bool): True to enable, False to disable.
741
+ step (str, optional): The specific step to apply this configuration to.
742
+ index (str, optional): The specific index to apply this configuration to.
743
+ """
744
+ self.set("var", "cts_obstruction_aware", enable, step=step, index=index)
745
+
251
746
  def setup(self):
252
747
  super().setup()
253
748
 
@@ -259,6 +754,9 @@ class OpenROADCTSParameter(OpenROADTask):
259
754
 
260
755
 
261
756
  class OpenROADGRTGeneralParameter(OpenROADTask):
757
+ """
758
+ Mixin class for defining general Global Routing (GRT) parameters.
759
+ """
262
760
  def __init__(self):
263
761
  super().__init__()
264
762
 
@@ -274,6 +772,66 @@ class OpenROADGRTGeneralParameter(OpenROADTask):
274
772
  self.add_parameter("grt_clock_max_layer", "str",
275
773
  "maximum layer to use for global routing of clock nets")
276
774
 
775
+ def set_openroad_grtmacroextension(self, extension: int,
776
+ step: Optional[str] = None, index: Optional[str] = None):
777
+ """
778
+ Sets the macro extension distance for global routing.
779
+
780
+ Args:
781
+ extension (int): The extension distance in number of gcells.
782
+ step (str, optional): The specific step to apply this configuration to.
783
+ index (str, optional): The specific index to apply this configuration to.
784
+ """
785
+ self.set("var", "grt_macro_extension", extension, step=step, index=index)
786
+
787
+ def set_openroad_grtsignalminlayer(self, layer: str,
788
+ step: Optional[str] = None, index: Optional[str] = None):
789
+ """
790
+ Sets the minimum layer for signal routing.
791
+
792
+ Args:
793
+ layer (str): The layer name.
794
+ step (str, optional): The specific step to apply this configuration to.
795
+ index (str, optional): The specific index to apply this configuration to.
796
+ """
797
+ self.set("var", "grt_signal_min_layer", layer, step=step, index=index)
798
+
799
+ def set_openroad_grtsignalmaxlayer(self, layer: str,
800
+ step: Optional[str] = None, index: Optional[str] = None):
801
+ """
802
+ Sets the maximum layer for signal routing.
803
+
804
+ Args:
805
+ layer (str): The layer name.
806
+ step (str, optional): The specific step to apply this configuration to.
807
+ index (str, optional): The specific index to apply this configuration to.
808
+ """
809
+ self.set("var", "grt_signal_max_layer", layer, step=step, index=index)
810
+
811
+ def set_openroad_grtclockminlayer(self, layer: str,
812
+ step: Optional[str] = None, index: Optional[str] = None):
813
+ """
814
+ Sets the minimum layer for clock routing.
815
+
816
+ Args:
817
+ layer (str): The layer name.
818
+ step (str, optional): The specific step to apply this configuration to.
819
+ index (str, optional): The specific index to apply this configuration to.
820
+ """
821
+ self.set("var", "grt_clock_min_layer", layer, step=step, index=index)
822
+
823
+ def set_openroad_grtclockmaxlayer(self, layer: str,
824
+ step: Optional[str] = None, index: Optional[str] = None):
825
+ """
826
+ Sets the maximum layer for clock routing.
827
+
828
+ Args:
829
+ layer (str): The layer name.
830
+ step (str, optional): The specific step to apply this configuration to.
831
+ index (str, optional): The specific index to apply this configuration to.
832
+ """
833
+ self.set("var", "grt_clock_max_layer", layer, step=step, index=index)
834
+
277
835
  def setup(self):
278
836
  super().setup()
279
837
 
@@ -298,6 +856,9 @@ class OpenROADGRTGeneralParameter(OpenROADTask):
298
856
 
299
857
 
300
858
  class OpenROADGRTParameter(OpenROADGRTGeneralParameter):
859
+ """
860
+ Mixin class for defining Global Routing (GRT) parameters.
861
+ """
301
862
  def __init__(self):
302
863
  super().__init__()
303
864
 
@@ -308,6 +869,30 @@ class OpenROADGRTParameter(OpenROADGRTGeneralParameter):
308
869
  "maximum number of iterations to use in global routing when attempting "
309
870
  "to solve overflow", defvalue=100)
310
871
 
872
+ def set_openroad_grtallowcongestion(self, allow: bool,
873
+ step: Optional[str] = None, index: Optional[str] = None):
874
+ """
875
+ Enables or disables allowing congestion in global routing.
876
+
877
+ Args:
878
+ allow (bool): True to allow congestion, False otherwise.
879
+ step (str, optional): The specific step to apply this configuration to.
880
+ index (str, optional): The specific index to apply this configuration to.
881
+ """
882
+ self.set("var", "grt_allow_congestion", allow, step=step, index=index)
883
+
884
+ def set_openroad_grtoverflowiter(self, iterations: int,
885
+ step: Optional[str] = None, index: Optional[str] = None):
886
+ """
887
+ Sets the maximum number of overflow iterations for global routing.
888
+
889
+ Args:
890
+ iterations (int): The number of iterations.
891
+ step (str, optional): The specific step to apply this configuration to.
892
+ index (str, optional): The specific index to apply this configuration to.
893
+ """
894
+ self.set("var", "grt_overflow_iter", iterations, step=step, index=index)
895
+
311
896
  def setup(self):
312
897
  super().setup()
313
898
 
@@ -316,6 +901,9 @@ class OpenROADGRTParameter(OpenROADGRTGeneralParameter):
316
901
 
317
902
 
318
903
  class OpenROADANTParameter(OpenROADTask):
904
+ """
905
+ Mixin class for defining Antenna repair parameters.
906
+ """
319
907
  def __init__(self):
320
908
  super().__init__()
321
909
 
@@ -325,6 +913,30 @@ class OpenROADANTParameter(OpenROADTask):
325
913
  self.add_parameter("ant_margin", "float", "adds a margin to the antenna ratios (0 - 100)",
326
914
  defvalue=0)
327
915
 
916
+ def set_openroad_antiterations(self, iterations: int,
917
+ step: Optional[str] = None, index: Optional[str] = None):
918
+ """
919
+ Sets the maximum number of antenna repair iterations.
920
+
921
+ Args:
922
+ iterations (int): The number of iterations.
923
+ step (str, optional): The specific step to apply this configuration to.
924
+ index (str, optional): The specific index to apply this configuration to.
925
+ """
926
+ self.set("var", "ant_iterations", iterations, step=step, index=index)
927
+
928
+ def set_openroad_antmargin(self, margin: float,
929
+ step: Optional[str] = None, index: Optional[str] = None):
930
+ """
931
+ Sets the margin for antenna ratios.
932
+
933
+ Args:
934
+ margin (float): The margin (0 - 100).
935
+ step (str, optional): The specific step to apply this configuration to.
936
+ index (str, optional): The specific index to apply this configuration to.
937
+ """
938
+ self.set("var", "ant_margin", margin, step=step, index=index)
939
+
328
940
  def setup(self):
329
941
  super().setup()
330
942
 
@@ -333,6 +945,9 @@ class OpenROADANTParameter(OpenROADTask):
333
945
 
334
946
 
335
947
  class _OpenROADDRTCommonParameter(OpenROADTask):
948
+ """
949
+ Base mixin class for defining common Detailed Routing (DRT) parameters.
950
+ """
336
951
  def __init__(self):
337
952
  super().__init__()
338
953
 
@@ -345,6 +960,54 @@ class _OpenROADDRTCommonParameter(OpenROADTask):
345
960
  "list of layers to treat as unidirectional regardless of what the tech "
346
961
  "lef specifies")
347
962
 
963
+ def set_openroad_drtprocessnode(self, node: str,
964
+ step: Optional[str] = None, index: Optional[str] = None):
965
+ """
966
+ Sets the process node for detailed routing.
967
+
968
+ Args:
969
+ node (str): The process node name.
970
+ step (str, optional): The specific step to apply this configuration to.
971
+ index (str, optional): The specific index to apply this configuration to.
972
+ """
973
+ self.set("var", "drt_process_node", node, step=step, index=index)
974
+
975
+ def add_openroad_detailedroutedefaultvia(self, vias: Union[str, List[str]],
976
+ step: Optional[str] = None,
977
+ index: Optional[str] = None,
978
+ clobber: bool = False):
979
+ """
980
+ Adds default vias to use for detailed routing.
981
+
982
+ Args:
983
+ vias (Union[str, List[str]]): The via(s) to add.
984
+ step (str, optional): The specific step to apply this configuration to.
985
+ index (str, optional): The specific index to apply this configuration to.
986
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
987
+ """
988
+ if clobber:
989
+ self.set("var", "detailed_route_default_via", vias, step=step, index=index)
990
+ else:
991
+ self.add("var", "detailed_route_default_via", vias, step=step, index=index)
992
+
993
+ def add_openroad_detailedrouteunidirectionallayer(self, layers: Union[str, List[str]],
994
+ step: Optional[str] = None,
995
+ index: Optional[str] = None,
996
+ clobber: bool = False):
997
+ """
998
+ Adds layers to treat as unidirectional during detailed routing.
999
+
1000
+ Args:
1001
+ layers (Union[str, List[str]]): The layer(s) to add.
1002
+ step (str, optional): The specific step to apply this configuration to.
1003
+ index (str, optional): The specific index to apply this configuration to.
1004
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
1005
+ """
1006
+ if clobber:
1007
+ self.set("var", "detailed_route_unidirectional_layer", layers, step=step, index=index)
1008
+ else:
1009
+ self.add("var", "detailed_route_unidirectional_layer", layers, step=step, index=index)
1010
+
348
1011
  def setup(self):
349
1012
  super().setup()
350
1013
 
@@ -363,11 +1026,17 @@ class _OpenROADDRTCommonParameter(OpenROADTask):
363
1026
 
364
1027
 
365
1028
  class OpenROADDRTPinAccessParameter(_OpenROADDRTCommonParameter):
1029
+ """
1030
+ Mixin class for defining Detailed Routing (DRT) pin access parameters.
1031
+ """
366
1032
  def __init__(self):
367
1033
  super().__init__()
368
1034
 
369
1035
 
370
1036
  class OpenROADDRTParameter(_OpenROADDRTCommonParameter):
1037
+ """
1038
+ Mixin class for defining Detailed Routing (DRT) parameters.
1039
+ """
371
1040
  def __init__(self):
372
1041
  super().__init__()
373
1042
 
@@ -386,9 +1055,83 @@ class OpenROADDRTParameter(_OpenROADDRTCommonParameter):
386
1055
  self.add_parameter("drt_end_iteration", "int",
387
1056
  "end iteration for detailed routing")
388
1057
 
1058
+ def set_openroad_drtdisableviagen(self, disable: bool,
1059
+ step: Optional[str] = None, index: Optional[str] = None):
1060
+ """
1061
+ Enables or disables automatic via generation in the detailed router.
1062
+
1063
+ Args:
1064
+ disable (bool): True to disable via generation, False to enable.
1065
+ step (str, optional): The specific step to apply this configuration to.
1066
+ index (str, optional): The specific index to apply this configuration to.
1067
+ """
1068
+ self.set("var", "drt_disable_via_gen", disable, step=step, index=index)
1069
+
1070
+ def set_openroad_drtviainpinbottomlayer(self, layer: str,
1071
+ step: Optional[str] = None,
1072
+ index: Optional[str] = None):
1073
+ """
1074
+ Sets the bottom layer to allow vias inside pins.
1075
+
1076
+ Args:
1077
+ layer (str): The layer name.
1078
+ step (str, optional): The specific step to apply this configuration to.
1079
+ index (str, optional): The specific index to apply this configuration to.
1080
+ """
1081
+ self.set("var", "drt_via_in_pin_bottom_layer", layer, step=step, index=index)
1082
+
1083
+ def set_openroad_drtviainpintoplayer(self, layer: str,
1084
+ step: Optional[str] = None, index: Optional[str] = None):
1085
+ """
1086
+ Sets the top layer to allow vias inside pins.
1087
+
1088
+ Args:
1089
+ layer (str): The layer name.
1090
+ step (str, optional): The specific step to apply this configuration to.
1091
+ index (str, optional): The specific index to apply this configuration to.
1092
+ """
1093
+ self.set("var", "drt_via_in_pin_top_layer", layer, step=step, index=index)
1094
+
1095
+ def set_openroad_drtrepairpdnvias(self, layer: str,
1096
+ step: Optional[str] = None, index: Optional[str] = None):
1097
+ """
1098
+ Sets the layer to repair PDN vias on.
1099
+
1100
+ Args:
1101
+ layer (str): The layer name.
1102
+ step (str, optional): The specific step to apply this configuration to.
1103
+ index (str, optional): The specific index to apply this configuration to.
1104
+ """
1105
+ self.set("var", "drt_repair_pdn_vias", layer, step=step, index=index)
1106
+
1107
+ def set_openroad_drtreportinterval(self, interval: int,
1108
+ step: Optional[str] = None, index: Optional[str] = None):
1109
+ """
1110
+ Sets the reporting interval for detailed routing.
1111
+
1112
+ Args:
1113
+ interval (int): The interval in steps.
1114
+ step (str, optional): The specific step to apply this configuration to.
1115
+ index (str, optional): The specific index to apply this configuration to.
1116
+ """
1117
+ self.set("var", "drt_report_interval", interval, step=step, index=index)
1118
+
1119
+ def set_openroad_drtenditeration(self, iteration: int,
1120
+ step: Optional[str] = None, index: Optional[str] = None):
1121
+ """
1122
+ Sets the end iteration for detailed routing.
1123
+
1124
+ Args:
1125
+ iteration (int): The iteration number.
1126
+ step (str, optional): The specific step to apply this configuration to.
1127
+ index (str, optional): The specific index to apply this configuration to.
1128
+ """
1129
+ self.set("var", "drt_end_iteration", iteration, step=step, index=index)
1130
+
389
1131
  def setup(self):
390
1132
  super().setup()
391
1133
 
1134
+ self.add_required_key("var", "drt_disable_via_gen")
392
1135
  if not self.get("var", "drt_disable_via_gen"):
393
1136
  if self.pdk.get("tool", "openroad", "drt_disable_via_gen"):
394
1137
  self.add_required_key(self.pdk, "tool", "openroad", "drt_disable_via_gen")
@@ -401,7 +1144,17 @@ class OpenROADDRTParameter(_OpenROADDRTCommonParameter):
401
1144
  self.set("var", "drt_repair_pdn_vias",
402
1145
  self.pdk.get("tool", "openroad", "drt_repair_pdn_vias"))
403
1146
 
404
- self.add_required_key("var", "drt_disable_via_gen")
1147
+ bottom_via_layer = self.get("var", "drt_via_in_pin_bottom_layer")
1148
+ top_via_layer = self.get("var", "drt_via_in_pin_top_layer")
1149
+ if not bottom_via_layer or not top_via_layer:
1150
+ pdk_via_layers = self.pdk.get("tool", "openroad", "drt_via_in_pin_layers")
1151
+ if pdk_via_layers:
1152
+ self.add_required_key(self.pdk, "tool", "openroad", "drt_via_in_pin_layers")
1153
+ if not bottom_via_layer:
1154
+ self.set("var", "drt_via_in_pin_bottom_layer", pdk_via_layers[0])
1155
+ if not top_via_layer:
1156
+ self.set("var", "drt_via_in_pin_top_layer", pdk_via_layers[1])
1157
+
405
1158
  if self.get("var", "drt_via_in_pin_bottom_layer"):
406
1159
  self.add_required_key("var", "drt_via_in_pin_bottom_layer")
407
1160
  if self.get("var", "drt_via_in_pin_top_layer"):
@@ -465,6 +1218,10 @@ class APRTask(OpenROADTask):
465
1218
  "used to indicate if global routing information should be loaded",
466
1219
  defvalue=False)
467
1220
 
1221
+ self.add_parameter("load_sdcs", "bool",
1222
+ "used to indicate if SDC files should be loaded before APR",
1223
+ defvalue=True)
1224
+
468
1225
  self.add_parameter("global_connect_fileset", "[(str,str)]",
469
1226
  "list of libraries and filesets to generate connects from")
470
1227
 
@@ -511,6 +1268,18 @@ class APRTask(OpenROADTask):
511
1268
  """
512
1269
  self.set("var", "ord_heatmap_bins", (x, y), step=step, index=index)
513
1270
 
1271
+ def set_openroad_loadsdcs(self, enable: bool,
1272
+ step: Optional[str] = None, index: Optional[str] = None) -> None:
1273
+ """
1274
+ Enables or disables loading SDC files before APR.
1275
+
1276
+ Args:
1277
+ enable: True to load SDC files, False to disable.
1278
+ step: The specific step to apply this configuration to.
1279
+ index: The specific index to apply this configuration to.
1280
+ """
1281
+ self.set("var", "load_sdcs", enable, step=step, index=index)
1282
+
514
1283
  def set_openroad_powercorner(self, corner: str,
515
1284
  step: Optional[str] = None, index: Optional[str] = None) -> None:
516
1285
  """
@@ -581,6 +1350,7 @@ class APRTask(OpenROADTask):
581
1350
  self.add_required_key("var", "ord_enable_images")
582
1351
  self.add_required_key("var", "ord_heatmap_bins")
583
1352
  self.add_required_key("var", "load_grt_setup")
1353
+ self.add_required_key("var", "load_sdcs")
584
1354
 
585
1355
  if not self.get("var", "global_connect_fileset"):
586
1356
  self.__import_globalconnect_filesets()
@@ -593,9 +1363,20 @@ class APRTask(OpenROADTask):
593
1363
  libcorners = set()
594
1364
  for scenario in self.project.constraint.timing.get_scenario().values():
595
1365
  libcorners.update(scenario.get_libcorner(self.step, self.index))
1366
+ self.add_required_key(scenario, "pexcorner")
1367
+ self.add_required_key(scenario, "libcorner")
1368
+ if scenario.get_check(self.step, self.index):
1369
+ self.add_required_key(scenario, "check")
1370
+ mode = scenario.get_mode(self.step, self.index)
1371
+ if mode:
1372
+ self.add_required_key(scenario, "mode")
1373
+ if self.get("var", "load_sdcs"):
1374
+ mode_obj = self.project.constraint.timing.get_mode(mode)
1375
+ self.add_required_key(mode_obj, "sdcfileset")
1376
+
596
1377
  delay_model = self.project.get("asic", "delaymodel")
597
1378
  for asiclib in self.project.get("asic", "asiclib"):
598
- lib = self.project.get("library", asiclib, field="schema")
1379
+ lib = self.project.get_library(asiclib)
599
1380
  for corner in libcorners:
600
1381
  if not lib.valid("asic", "libcornerfileset", corner, delay_model):
601
1382
  continue
@@ -609,24 +1390,53 @@ class APRTask(OpenROADTask):
609
1390
 
610
1391
  def __import_globalconnect_filesets(self):
611
1392
  for lib in self.project.get("asic", "asiclib"):
612
- libobj = self.project.get("library", lib, field="schema")
1393
+ libobj = self.project.get_library(lib)
613
1394
  if libobj.valid("tool", "openroad", "global_connect_fileset"):
614
1395
  for fileset in libobj.get("tool", "openroad", "global_connect_fileset"):
615
1396
  self.add_openroad_globalconnectfileset(lib, fileset)
616
1397
 
617
1398
  def _set_reports(self, task_reports: List[str]):
618
- self.set("var", "reports", set(task_reports).difference(self.get("var", "skip_reports")))
1399
+ skip_reports = set(self.get("var", "skip_reports"))
1400
+
1401
+ if not self.get("var", "load_sdcs"):
1402
+ skip_reports.update((
1403
+ "setup",
1404
+ "hold",
1405
+ "unconstrained",
1406
+ "clock_skew",
1407
+ "fmax",
1408
+ "check_setup",
1409
+ "clock_placement",
1410
+ "clock_trees"))
1411
+
1412
+ self.set("var", "reports", set(task_reports).difference(skip_reports))
619
1413
 
620
1414
  if "power" in self.get("var", "reports"):
621
1415
  self.add_required_key("var", "power_corner")
622
1416
 
623
1417
  def _add_pnr_inputs(self):
624
- if f"{self.design_topmodule}.sdc" in self.get_files_from_input_nodes():
625
- self.add_input_file(ext="sdc")
626
- else:
627
- for lib, fileset in self.project.get_filesets():
628
- if lib.has_file(fileset=fileset, filetype="sdc"):
629
- self.add_required_key(lib, "fileset", fileset, "file", "sdc")
1418
+ if self.get("var", "load_sdcs"):
1419
+ if f"{self.design_topmodule}.sdc" in self.get_files_from_input_nodes():
1420
+ self.add_input_file(ext="sdc")
1421
+ else:
1422
+ for lib, fileset in self.project.get_filesets():
1423
+ if lib.has_file(fileset=fileset, filetype="sdc"):
1424
+ self.add_required_key(lib, "fileset", fileset, "file", "sdc")
1425
+
1426
+ modes = set()
1427
+ for scenario in self.project.constraint.timing.get_scenario().values():
1428
+ mode = scenario.get_mode(self.step, self.index)
1429
+ if mode:
1430
+ modes.add(mode)
1431
+ self.add_required_key(scenario, "mode")
1432
+ mode_obj = self.project.constraint.timing.get_mode(mode)
1433
+ self.add_required_key(mode_obj, "sdcfileset")
1434
+
1435
+ for mode in modes:
1436
+ mode_obj = self.project.constraint.timing.get_mode(mode)
1437
+ for lib, fileset in mode_obj.get_sdcfileset():
1438
+ libobj = self.project.get_library(lib)
1439
+ self.add_required_key(libobj, "fileset", fileset, "file", "sdc")
630
1440
 
631
1441
  if f"{self.design_topmodule}.odb" in self.get_files_from_input_nodes():
632
1442
  self.add_input_file(ext="odb")
@@ -636,14 +1446,15 @@ class APRTask(OpenROADTask):
636
1446
  pass
637
1447
 
638
1448
  def _add_pnr_outputs(self):
639
- self.add_output_file(ext="sdc")
1449
+ if self.get("var", "load_sdcs"):
1450
+ self.add_output_file(ext="sdc")
640
1451
  self.add_output_file(ext="vg")
641
1452
  self.add_output_file(ext="lec.vg")
642
1453
  self.add_output_file(ext="def")
643
1454
  self.add_output_file(ext="odb")
644
1455
 
645
1456
  for lib in self.project.get("asic", "asiclib"):
646
- libobj = self.project.get("library", lib, field="schema")
1457
+ libobj = self.project.get_library(lib)
647
1458
  for celltype in ["decap", "tie", "filler", "tap", "endcap", "antenna", "physicalonly"]:
648
1459
  if libobj.valid("asic", "cells", celltype) and \
649
1460
  libobj.get("asic", "cells", celltype):