librelane 3.0.0.dev23__py3-none-any.whl → 3.0.0.dev25__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.

Potentially problematic release.


This version of librelane might be problematic. Click here for more details.

@@ -50,48 +50,28 @@ def _Design_read_verilog_files(
50
50
  synth_parameters: Iterable[str],
51
51
  includes: Iterable[str],
52
52
  defines: Iterable[str],
53
- use_synlig: bool = False,
54
- synlig_defer: bool = False,
53
+ use_slang: bool = False,
55
54
  ):
56
55
  files = list(files) # for easier concatenation
57
56
  include_args = [f"-I{dir}" for dir in includes]
58
57
  define_args = [f"-D{define}" for define in defines]
59
58
  chparams = {}
60
- synlig_chparam_args = []
59
+ slang_chparam_args = []
61
60
  for chparam in synth_parameters:
62
61
  param, value = chparam.split("=", maxsplit=1) # validate
63
62
  chparams[param] = value
64
- synlig_chparam_args.append(f"-P{param}={value}")
63
+ slang_chparam_args.append(f"-G{param}={value}")
65
64
 
66
- if use_synlig and synlig_defer:
67
- self.run_pass("plugin", "-i", "synlig-sv")
68
- for file in files:
69
- self.run_pass(
70
- "read_systemverilog",
71
- "-defer",
72
- "-sverilog",
73
- *define_args,
74
- *include_args,
75
- file,
76
- )
77
- self.run_pass(
78
- "read_systemverilog",
79
- "-link",
80
- "-sverilog",
81
- "-top",
82
- top,
83
- *synlig_chparam_args,
84
- )
85
- elif use_synlig:
86
- self.run_pass("plugin", "-i", "synlig-sv")
65
+ ys.log("use_slang" if use_slang else "wtaf")
66
+ if use_slang:
67
+ self.run_pass("plugin", "-i", "slang")
87
68
  self.run_pass(
88
- "read_systemverilog",
89
- "-sverilog",
90
- "-top",
69
+ "read_slang",
70
+ "--top",
91
71
  top,
92
72
  *define_args,
93
73
  *include_args,
94
- *synlig_chparam_args,
74
+ *slang_chparam_args,
95
75
  *files,
96
76
  )
97
77
  else:
@@ -157,6 +157,13 @@ DesignFormat(
157
157
  alts=["NETLIST"],
158
158
  ).register()
159
159
 
160
+ DesignFormat(
161
+ "logical_nl",
162
+ "logical_nl.v",
163
+ "Logical cell-only Verilog Netlist",
164
+ folder_override="nl",
165
+ ).register()
166
+
160
167
  DesignFormat(
161
168
  "pnl",
162
169
  "pnl.v",
@@ -18,204 +18,253 @@ from ..config import Variable
18
18
 
19
19
  io_layer_variables = [
20
20
  Variable(
21
- "FP_IO_VEXTEND",
21
+ "IO_PIN_V_EXTENSION",
22
22
  Decimal,
23
23
  "Extends the vertical io pins outside of the die by the specified units.",
24
24
  default=0,
25
25
  units="µm",
26
+ deprecated_names=["FP_IO_VEXTEND"],
26
27
  ),
27
28
  Variable(
28
- "FP_IO_HEXTEND",
29
+ "IO_PIN_H_EXTENSION",
29
30
  Decimal,
30
31
  "Extends the horizontal io pins outside of the die by the specified units.",
31
32
  default=0,
32
33
  units="µm",
34
+ deprecated_names=["FP_IO_HEXTEND"],
33
35
  ),
34
36
  Variable(
35
- "FP_IO_VTHICKNESS_MULT",
37
+ "IO_PIN_V_THICKNESS_MULT",
36
38
  Decimal,
37
39
  "A multiplier for vertical pin thickness. Base thickness is the pins layer min width.",
38
40
  default=2,
41
+ deprecated_names=["FP_IO_VTHICKNESS_MULT"],
39
42
  ),
40
43
  Variable(
41
- "FP_IO_HTHICKNESS_MULT",
44
+ "IO_PIN_H_THICKNESS_MULT",
42
45
  Decimal,
43
46
  "A multiplier for horizontal pin thickness. Base thickness is the pins layer min width.",
44
47
  default=2,
48
+ deprecated_names=["FP_IO_HTHICKNESS_MULT"],
49
+ ),
50
+ Variable(
51
+ "IO_PIN_V_LENGTH",
52
+ Optional[Decimal],
53
+ """
54
+ The length of the pins with a north or south orientation. If unspecified by a PDK, OpenROAD will use whichever is higher of the following two values:
55
+ * The pin width
56
+ * The minimum value satisfying the minimum area constraint given the pin width
57
+ """,
58
+ units="µm",
59
+ pdk=True,
60
+ deprecated_names=["FP_IO_VLENGTH"],
61
+ ),
62
+ Variable(
63
+ "IO_PIN_H_LENGTH",
64
+ Optional[Decimal],
65
+ """
66
+ The length of the pins with an east or west orientation. If unspecified by a PDK, OpenROAD will use whichever is higher of the following two values:
67
+ * The pin width
68
+ * The minimum value satisfying the minimum area constraint given the pin width
69
+ """,
70
+ units="µm",
71
+ pdk=True,
72
+ deprecated_names=["FP_IO_HLENGTH"],
45
73
  ),
46
74
  ]
47
75
 
48
76
  pdn_variables = [
49
77
  Variable(
50
- "FP_PDN_SKIPTRIM",
78
+ "PDN_SKIPTRIM",
51
79
  bool,
52
80
  "Enables `-skip_trim` option during pdngen which skips the metal trim step, which attempts to remove metal stubs.",
53
81
  default=False,
82
+ deprecated_names=["FP_PDN_SKIPTRIM"],
54
83
  ),
55
84
  Variable(
56
- "FP_PDN_CORE_RING",
85
+ "PDN_CORE_RING",
57
86
  bool,
58
87
  "Enables adding a core ring around the design. More details on the control variables in the PDK config documentation.",
59
88
  default=False,
89
+ deprecated_names=["FP_PDN_CORE_RING"],
60
90
  ),
61
91
  Variable(
62
- "FP_PDN_ENABLE_RAILS",
92
+ "PDN_ENABLE_RAILS",
63
93
  bool,
64
94
  "Enables the creation of rails in the power grid.",
65
95
  default=True,
96
+ deprecated_names=["FP_PDN_ENABLE_RAILS"],
66
97
  ),
67
98
  Variable(
68
- "FP_PDN_HORIZONTAL_HALO",
99
+ "PDN_HORIZONTAL_HALO",
69
100
  Decimal,
70
101
  "Sets the horizontal halo around the macros during power grid insertion.",
71
102
  default=10,
72
103
  units="µm",
104
+ deprecated_names=["FP_PDN_HORIZONTAL_HALO"],
73
105
  ),
74
106
  Variable(
75
- "FP_PDN_VERTICAL_HALO",
107
+ "PDN_VERTICAL_HALO",
76
108
  Decimal,
77
109
  "Sets the vertical halo around the macros during power grid insertion.",
78
110
  default=10,
79
111
  units="µm",
112
+ deprecated_names=["FP_PDN_VERTICAL_HALO"],
80
113
  ),
81
114
  Variable(
82
- "FP_PDN_MULTILAYER",
115
+ "PDN_MULTILAYER",
83
116
  bool,
84
117
  "Controls the layers used in the power grid. If set to false, only the lower layer will be used, which is useful when hardening a macro for integrating into a larger top-level design.",
85
118
  default=True,
86
- deprecated_names=["DESIGN_IS_CORE"],
119
+ deprecated_names=["FP_PDN_MULTILAYER", "DESIGN_IS_CORE"],
87
120
  ),
88
121
  Variable(
89
- "FP_PDN_RAIL_OFFSET",
122
+ "PDN_RAIL_OFFSET",
90
123
  Decimal,
91
124
  "The offset for the power distribution network rails for first metal layer.",
92
125
  units="µm",
93
126
  pdk=True,
127
+ deprecated_names=["FP_PDN_RAIL_OFFSET"],
94
128
  ),
95
129
  Variable(
96
- "FP_PDN_VWIDTH",
130
+ "PDN_VWIDTH",
97
131
  Decimal,
98
132
  "The strap width for the vertical layer in generated power distribution networks.",
99
133
  units="µm",
100
134
  pdk=True,
135
+ deprecated_names=["FP_PDN_VWIDTH"],
101
136
  ),
102
137
  Variable(
103
- "FP_PDN_HWIDTH",
138
+ "PDN_HWIDTH",
104
139
  Decimal,
105
140
  "The strap width for the horizontal layer in generated power distribution networks.",
106
141
  units="µm",
107
142
  pdk=True,
143
+ deprecated_names=["FP_PDN_HWIDTH"],
108
144
  ),
109
145
  Variable(
110
- "FP_PDN_VSPACING",
146
+ "PDN_VSPACING",
111
147
  Decimal,
112
148
  "Intra-spacing (within a set) of vertical straps in generated power distribution networks.",
113
149
  units="µm",
114
150
  pdk=True,
151
+ deprecated_names=["FP_PDN_VSPACING"],
115
152
  ),
116
153
  Variable(
117
- "FP_PDN_HSPACING",
154
+ "PDN_HSPACING",
118
155
  Decimal,
119
156
  "Intra-spacing (within a set) of horizontal straps in generated power distribution networks.",
120
157
  units="µm",
121
158
  pdk=True,
159
+ deprecated_names=["FP_PDN_HSPACING"],
122
160
  ),
123
161
  Variable(
124
- "FP_PDN_VPITCH",
162
+ "PDN_VPITCH",
125
163
  Decimal,
126
164
  "Inter-distance (between sets) of vertical power straps in generated power distribution networks.",
127
165
  units="µm",
128
166
  pdk=True,
167
+ deprecated_names=["FP_PDN_VPITCH"],
129
168
  ),
130
169
  Variable(
131
- "FP_PDN_HPITCH",
170
+ "PDN_HPITCH",
132
171
  Decimal,
133
172
  "Inter-distance (between sets) of horizontal power straps in generated power distribution networks.",
134
173
  units="µm",
135
174
  pdk=True,
175
+ deprecated_names=["FP_PDN_HPITCH"],
136
176
  ),
137
177
  Variable(
138
- "FP_PDN_VOFFSET",
178
+ "PDN_VOFFSET",
139
179
  Decimal,
140
180
  "Initial offset for sets of vertical power straps.",
141
181
  units="µm",
142
182
  pdk=True,
183
+ deprecated_names=["FP_PDN_VOFFSET"],
143
184
  ),
144
185
  Variable(
145
- "FP_PDN_HOFFSET",
186
+ "PDN_HOFFSET",
146
187
  Decimal,
147
188
  "Initial offset for sets of horizontal power straps.",
148
189
  units="µm",
149
190
  pdk=True,
191
+ deprecated_names=["FP_PDN_HOFFSET"],
150
192
  ),
151
193
  Variable(
152
- "FP_PDN_CORE_RING_VWIDTH",
194
+ "PDN_CORE_RING_VWIDTH",
153
195
  Decimal,
154
196
  "The width for the vertical layer in the core ring of generated power distribution networks.",
155
197
  units="µm",
156
198
  pdk=True,
199
+ deprecated_names=["FP_PDN_CORE_RING_VWIDTH"],
157
200
  ),
158
201
  Variable(
159
- "FP_PDN_CORE_RING_HWIDTH",
202
+ "PDN_CORE_RING_HWIDTH",
160
203
  Decimal,
161
204
  "The width for the horizontal layer in the core ring of generated power distribution networks.",
162
205
  units="µm",
163
206
  pdk=True,
207
+ deprecated_names=["FP_PDN_CORE_RING_HWIDTH"],
164
208
  ),
165
209
  Variable(
166
- "FP_PDN_CORE_RING_VSPACING",
210
+ "PDN_CORE_RING_VSPACING",
167
211
  Decimal,
168
212
  "The spacing for the vertical layer in the core ring of generated power distribution networks.",
169
213
  units="µm",
170
214
  pdk=True,
215
+ deprecated_names=["FP_PDN_CORE_RING_VSPACING"],
171
216
  ),
172
217
  Variable(
173
- "FP_PDN_CORE_RING_HSPACING",
218
+ "PDN_CORE_RING_HSPACING",
174
219
  Decimal,
175
220
  "The spacing for the horizontal layer in the core ring of generated power distribution networks.",
176
221
  units="µm",
177
222
  pdk=True,
223
+ deprecated_names=["FP_PDN_CORE_RING_HSPACING"],
178
224
  ),
179
225
  Variable(
180
- "FP_PDN_CORE_RING_VOFFSET",
226
+ "PDN_CORE_RING_VOFFSET",
181
227
  Decimal,
182
228
  "The offset for the vertical layer in the core ring of generated power distribution networks.",
183
229
  units="µm",
184
230
  pdk=True,
231
+ deprecated_names=["FP_PDN_CORE_RING_VOFFSET"],
185
232
  ),
186
233
  Variable(
187
- "FP_PDN_CORE_RING_HOFFSET",
234
+ "PDN_CORE_RING_HOFFSET",
188
235
  Decimal,
189
236
  "The offset for the horizontal layer in the core ring of generated power distribution networks.",
190
237
  units="µm",
191
238
  pdk=True,
239
+ deprecated_names=["FP_PDN_CORE_RING_HOFFSET"],
192
240
  ),
193
241
  Variable(
194
- "FP_PDN_RAIL_LAYER",
242
+ "PDN_RAIL_LAYER",
195
243
  str,
196
244
  "Defines the metal layer used for PDN rails.",
197
- deprecated_names=["FP_PDN_RAILS_LAYER"],
245
+ deprecated_names=["FP_PDN_RAIL_LAYER", "FP_PDN_RAILS_LAYER"],
198
246
  pdk=True,
199
247
  ),
200
248
  Variable(
201
- "FP_PDN_RAIL_WIDTH",
249
+ "PDN_RAIL_WIDTH",
202
250
  Decimal,
203
251
  "Defines the width of PDN rails on the `FP_PDN_RAILS_LAYER` layer.",
204
252
  units="µm",
205
253
  pdk=True,
254
+ deprecated_names=["FP_PDN_RAIL_WIDTH"],
206
255
  ),
207
256
  Variable(
208
- "FP_PDN_HORIZONTAL_LAYER",
257
+ "PDN_HORIZONTAL_LAYER",
209
258
  str,
210
259
  "Defines the horizontal PDN layer.",
211
- deprecated_names=["FP_PDN_UPPER_LAYER"],
260
+ deprecated_names=["FP_PDN_HORIZONTAL_LAYER", "FP_PDN_UPPER_LAYER"],
212
261
  pdk=True,
213
262
  ),
214
263
  Variable(
215
- "FP_PDN_VERTICAL_LAYER",
264
+ "PDN_VERTICAL_LAYER",
216
265
  str,
217
266
  "Defines the vertical PDN layer.",
218
- deprecated_names=["FP_PDN_LOWER_LAYER"],
267
+ deprecated_names=["FP_PDN_VERTICAL_LAYER", "FP_PDN_LOWER_LAYER"],
219
268
  pdk=True,
220
269
  ),
221
270
  ]
librelane/steps/odb.py CHANGED
@@ -27,7 +27,7 @@ from ..config import Instance, Macro, Variable
27
27
  from ..logging import info, verbose
28
28
  from ..state import DesignFormat, State
29
29
 
30
- from .openroad import DetailedPlacement, GlobalRouting
30
+ from .openroad import DetailedPlacement, GlobalRouting, OpenROADStep
31
31
  from .openroad_alerts import OpenROADAlert, OpenROADOutputProcessor
32
32
  from .common_variables import io_layer_variables, dpl_variables, grt_variables
33
33
  from .step import (
@@ -52,6 +52,10 @@ class OdbpyStep(Step):
52
52
 
53
53
  alerts: Optional[List[OpenROADAlert]] = None
54
54
 
55
+ @classmethod
56
+ def get_openroad_path(Self) -> str:
57
+ return OpenROADStep.get_openroad_path()
58
+
55
59
  def on_alert(self, alert: OpenROADAlert) -> OpenROADAlert:
56
60
  if alert.code in [
57
61
  "ORD-0039", # .openroad ignored with -python
@@ -155,7 +159,7 @@ class OdbpyStep(Step):
155
159
  lefs.append(str(design_lef))
156
160
  return (
157
161
  [
158
- "openroad",
162
+ self.get_openroad_path(),
159
163
  "-exit",
160
164
  "-no_splash",
161
165
  "-metrics",
@@ -614,31 +618,10 @@ class CustomIOPlacement(OdbpyStep):
614
618
 
615
619
  config_vars = io_layer_variables + [
616
620
  Variable(
617
- "FP_IO_VLENGTH",
618
- Optional[Decimal],
619
- """
620
- The length of the pins with a north or south orientation. If unspecified by a PDK, the script will use whichever is higher of the following two values:
621
- * The pin width
622
- * The minimum value satisfying the minimum area constraint given the pin width
623
- """,
624
- units="µm",
625
- pdk=True,
626
- ),
627
- Variable(
628
- "FP_IO_HLENGTH",
629
- Optional[Decimal],
630
- """
631
- The length of the pins with an east or west orientation. If unspecified by a PDK, the script will use whichever is higher of the following two values:
632
- * The pin width
633
- * The minimum value satisfying the minimum area constraint given the pin width
634
- """,
635
- units="µm",
636
- pdk=True,
637
- ),
638
- Variable(
639
- "FP_PIN_ORDER_CFG",
621
+ "IO_PIN_ORDER_CFG",
640
622
  Optional[Path],
641
- "Path to the configuration file. If set to `None`, this step is skipped.",
623
+ "Path to a custom pin configuration file.",
624
+ deprecated_names=["FP_PIN_ORDER_CFG"],
642
625
  ),
643
626
  Variable(
644
627
  "ERRORS_ON_UNMATCHED_IO",
@@ -656,28 +639,28 @@ class CustomIOPlacement(OdbpyStep):
656
639
 
657
640
  def get_command(self) -> List[str]:
658
641
  length_args = []
659
- if self.config["FP_IO_VLENGTH"] is not None:
660
- length_args += ["--ver-length", self.config["FP_IO_VLENGTH"]]
661
- if self.config["FP_IO_HLENGTH"] is not None:
662
- length_args += ["--hor-length", self.config["FP_IO_HLENGTH"]]
642
+ if self.config["IO_PIN_V_LENGTH"] is not None:
643
+ length_args += ["--ver-length", self.config["IO_PIN_V_LENGTH"]]
644
+ if self.config["IO_PIN_H_LENGTH"] is not None:
645
+ length_args += ["--hor-length", self.config["IO_PIN_H_LENGTH"]]
663
646
 
664
647
  return (
665
648
  super().get_command()
666
649
  + [
667
650
  "--config",
668
- self.config["FP_PIN_ORDER_CFG"],
651
+ self.config["IO_PIN_ORDER_CFG"],
669
652
  "--hor-layer",
670
653
  self.config["FP_IO_HLAYER"],
671
654
  "--ver-layer",
672
655
  self.config["FP_IO_VLAYER"],
673
656
  "--hor-width-mult",
674
- str(self.config["FP_IO_VTHICKNESS_MULT"]),
657
+ str(self.config["IO_PIN_V_THICKNESS_MULT"]),
675
658
  "--ver-width-mult",
676
- str(self.config["FP_IO_HTHICKNESS_MULT"]),
659
+ str(self.config["IO_PIN_H_THICKNESS_MULT"]),
677
660
  "--hor-extension",
678
- str(self.config["FP_IO_HEXTEND"]),
661
+ str(self.config["IO_PIN_H_EXTENSION"]),
679
662
  "--ver-extension",
680
- str(self.config["FP_IO_VEXTEND"]),
663
+ str(self.config["IO_PIN_V_EXTENSION"]),
681
664
  "--unmatched-error",
682
665
  self.config["ERRORS_ON_UNMATCHED_IO"],
683
666
  ]
@@ -685,8 +668,8 @@ class CustomIOPlacement(OdbpyStep):
685
668
  )
686
669
 
687
670
  def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
688
- if self.config["FP_PIN_ORDER_CFG"] is None:
689
- info(f"No custom floorplan file configured, skipping '{self.id}'…")
671
+ if self.config["IO_PIN_ORDER_CFG"] is None:
672
+ info(f"No custom I/O placement file configured, skipping '{self.id}'…")
690
673
  return {}, {}
691
674
  return super().run(state_in, **kwargs)
692
675
 
@@ -946,7 +929,12 @@ class CellFrequencyTables(OdbpyStep):
946
929
  lib_list = self.toolbox.filter_views(self.config, self.config["LIB"])
947
930
  env_copy["_PNR_LIBS"] = TclStep.value_to_tcl(lib_list)
948
931
  super().run_subprocess(
949
- ["openroad", "-no_splash", "-exit", self.get_buffer_list_script()],
932
+ [
933
+ self.get_openroad_path(),
934
+ "-no_splash",
935
+ "-exit",
936
+ self.get_buffer_list_script(),
937
+ ],
950
938
  env=env_copy,
951
939
  log_to=self.get_buffer_list_file(),
952
940
  )
@@ -267,6 +267,10 @@ class OpenROADStep(TclStep):
267
267
  ),
268
268
  ]
269
269
 
270
+ @classmethod
271
+ def get_openroad_path(Self) -> str:
272
+ return os.getenv("_LLN_OVERRIDE_OPENROAD", "openroad")
273
+
270
274
  @abstractmethod
271
275
  def get_script_path(self) -> str:
272
276
  pass
@@ -469,7 +473,7 @@ class OpenROADStep(TclStep):
469
473
  def get_command(self) -> List[str]:
470
474
  metrics_path = os.path.join(self.step_dir, "or_metrics_out.json")
471
475
  return [
472
- "openroad",
476
+ self.get_openroad_path(),
473
477
  ("-gui" if os.getenv("_OPENROAD_GUI", "0") == "1" else "-exit"),
474
478
  "-no_splash",
475
479
  "-metrics",
@@ -956,7 +960,7 @@ class STAPostPNR(STAPrePNR):
956
960
  lefs.append(lef)
957
961
  metrics_path = os.path.join(corner_dir, "filter_unannotated_metrics.json")
958
962
  filter_unannotated_cmd = [
959
- "openroad",
963
+ self.get_openroad_path(),
960
964
  "-exit",
961
965
  "-no_splash",
962
966
  "-metrics",
@@ -1173,8 +1177,8 @@ class IOPlacement(OpenROADStep):
1173
1177
  """
1174
1178
  Places I/O pins on a floor-planned ODB file using OpenROAD's built-in placer.
1175
1179
 
1176
- If ``FP_PIN_ORDER_CFG`` is not ``None``, this step is skipped (for
1177
- compatibility with LibreLane 1.)
1180
+ If ``IO_PIN_ORDER_CFG`` is not ``None``, this step is skipped (for
1181
+ compatibility with OpenLane.)
1178
1182
  """
1179
1183
 
1180
1184
  id = "OpenROAD.IOPlacement"
@@ -1185,51 +1189,31 @@ class IOPlacement(OpenROADStep):
1185
1189
  + io_layer_variables
1186
1190
  + [
1187
1191
  Variable(
1188
- "FP_PPL_MODE",
1192
+ "IO_PIN_PLACEMENT_MODE",
1189
1193
  Literal["matching", "random_equidistant", "annealing"],
1190
1194
  "Decides the mode of the random IO placement option.",
1191
1195
  default="matching",
1192
- deprecated_names=[("FP_IO_MODE", _migrate_ppl_mode)],
1196
+ deprecated_names=[("FP_IO_MODE", _migrate_ppl_mode), "FP_PPL_MODE"],
1193
1197
  ),
1194
1198
  Variable(
1195
- "FP_IO_MIN_DISTANCE",
1199
+ "IO_PIN_MIN_DISTANCE",
1196
1200
  Optional[Decimal],
1197
1201
  "The minimum distance between two pins. If unspecified by a PDK, OpenROAD will use the length of two routing tracks.",
1198
1202
  units="µm",
1199
1203
  pdk=True,
1204
+ deprecated_names=["FP_IO_MIN_DISTANCE"],
1200
1205
  ),
1201
1206
  Variable(
1202
- "FP_PIN_ORDER_CFG",
1207
+ "IO_PIN_ORDER_CFG",
1203
1208
  Optional[Path],
1204
1209
  "Path to a custom pin configuration file.",
1210
+ deprecated_names=["FP_PIN_ORDER_CFG"],
1205
1211
  ),
1206
1212
  Variable(
1207
1213
  "FP_DEF_TEMPLATE",
1208
1214
  Optional[Path],
1209
1215
  "Points to the DEF file to be used as a template.",
1210
1216
  ),
1211
- Variable(
1212
- "FP_IO_VLENGTH",
1213
- Optional[Decimal],
1214
- """
1215
- The length of the pins with a north or south orientation. If unspecified by a PDK, OpenROAD will use whichever is higher of the following two values:
1216
- * The pin width
1217
- * The minimum value satisfying the minimum area constraint given the pin width
1218
- """,
1219
- units="µm",
1220
- pdk=True,
1221
- ),
1222
- Variable(
1223
- "FP_IO_HLENGTH",
1224
- Optional[Decimal],
1225
- """
1226
- The length of the pins with an east or west orientation. If unspecified by a PDK, OpenROAD will use whichever is higher of the following two values:
1227
- * The pin width
1228
- * The minimum value satisfying the minimum area constraint given the pin width
1229
- """,
1230
- units="µm",
1231
- pdk=True,
1232
- ),
1233
1217
  ]
1234
1218
  )
1235
1219
 
@@ -1237,8 +1221,8 @@ class IOPlacement(OpenROADStep):
1237
1221
  return os.path.join(get_script_dir(), "openroad", "ioplacer.tcl")
1238
1222
 
1239
1223
  def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
1240
- if self.config["FP_PIN_ORDER_CFG"] is not None:
1241
- info(f"FP_PIN_ORDER_CFG is set. Skipping '{self.id}'…")
1224
+ if self.config["IO_PIN_ORDER_CFG"] is not None:
1225
+ info(f"IO_PIN_ORDER_CFG is set. Skipping '{self.id}'…")
1242
1226
  return {}, {}
1243
1227
  if self.config["FP_DEF_TEMPLATE"] is not None:
1244
1228
  info(
@@ -1349,10 +1333,10 @@ class GeneratePDN(OpenROADStep):
1349
1333
  + pdn_variables
1350
1334
  + [
1351
1335
  Variable(
1352
- "FP_PDN_CFG",
1336
+ "PDN_CFG",
1353
1337
  Optional[Path],
1354
1338
  "A custom PDN configuration file. If not provided, the default PDN config will be used.",
1355
- deprecated_names=["PDN_CFG"],
1339
+ deprecated_names=["FP_PDN_CFG"],
1356
1340
  )
1357
1341
  ]
1358
1342
  )
@@ -1362,17 +1346,25 @@ class GeneratePDN(OpenROADStep):
1362
1346
 
1363
1347
  def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
1364
1348
  kwargs, env = self.extract_env(kwargs)
1365
- if self.config["FP_PDN_CFG"] is None:
1366
- env["FP_PDN_CFG"] = os.path.join(
1349
+ if self.config["PDN_CFG"] is None:
1350
+ env["PDN_CFG"] = os.path.join(
1367
1351
  get_script_dir(), "openroad", "common", "pdn_cfg.tcl"
1368
1352
  )
1369
- info(f"'FP_PDN_CFG' not explicitly set, setting it to {env['FP_PDN_CFG']}…")
1353
+ info(f"'PDN_CFG' not explicitly set, setting it to {env['PDN_CFG']}…")
1370
1354
  views_updates, metrics_updates = super().run(state_in, env=env, **kwargs)
1371
1355
 
1356
+ alerts = self.alerts or []
1372
1357
  error_reports = glob(os.path.join(self.step_dir, "*-grid-errors.rpt"))
1373
1358
  for report in error_reports:
1374
1359
  net = os.path.basename(report).split("-", maxsplit=1)[0]
1375
- count = get_psm_error_count(open(report, encoding="utf8"))
1360
+ no_terminals = any(
1361
+ alert.code == "PSM-0025" and alert.message.startswith(net)
1362
+ for alert in alerts
1363
+ )
1364
+ if no_terminals:
1365
+ count = 1
1366
+ else:
1367
+ count = get_psm_error_count(open(report, encoding="utf8"))
1376
1368
  metrics_updates[f"design__power_grid_violation__count__net:{net}"] = count
1377
1369
 
1378
1370
  metric_updates_with_aggregates = aggregate_metrics(
@@ -1511,16 +1503,17 @@ class GlobalPlacementSkipIO(_GlobalPlacement):
1511
1503
 
1512
1504
  config_vars = _GlobalPlacement.config_vars + [
1513
1505
  Variable(
1514
- "FP_PPL_MODE",
1506
+ "IO_PIN_PLACEMENT_MODE",
1515
1507
  Literal["matching", "random_equidistant", "annealing"],
1516
1508
  "Decides the mode of the random IO placement option.",
1517
1509
  default="matching",
1518
- deprecated_names=[("FP_IO_MODE", _migrate_ppl_mode)],
1510
+ deprecated_names=[("FP_IO_MODE", _migrate_ppl_mode), "FP_PPL_MODE"],
1519
1511
  ),
1520
1512
  Variable(
1521
- "FP_PIN_ORDER_CFG",
1513
+ "IO_PIN_ORDER_CFG",
1522
1514
  Optional[Path],
1523
1515
  "Path to a custom pin configuration file.",
1516
+ deprecated_names=["FP_PIN_ORDER_CFG"],
1524
1517
  ),
1525
1518
  Variable(
1526
1519
  "FP_DEF_TEMPLATE",
@@ -1536,9 +1529,9 @@ class GlobalPlacementSkipIO(_GlobalPlacement):
1536
1529
  f"I/O pins were loaded from {self.config['FP_DEF_TEMPLATE']}. Returning state unaltered…"
1537
1530
  )
1538
1531
  return {}, {}
1539
- if self.config["FP_PIN_ORDER_CFG"] is not None:
1532
+ if self.config["IO_PIN_ORDER_CFG"] is not None:
1540
1533
  info(
1541
- f"I/O pins to be placed from {self.config['FP_PIN_ORDER_CFG']}. Returning state unaltered…"
1534
+ f"I/O pins to be placed from {self.config['IO_PIN_ORDER_CFG']}. Returning state unaltered…"
1542
1535
  )
1543
1536
  return {}, {}
1544
1537
  env["__PL_SKIP_IO"] = "1"