librelane 3.0.0.dev40__py3-none-any.whl → 3.0.0.dev42__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.

librelane/__init__.py CHANGED
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
  """
15
15
  The LibreLane API
16
- ----------------
16
+ -----------------
17
17
 
18
18
  Documented elements of this API represent the primary programming interface for
19
19
  the LibreLane infrastructure.
librelane/__main__.py CHANGED
@@ -217,7 +217,10 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool):
217
217
  if len(discovered_plugins) > 0:
218
218
  print("Discovered plugins:")
219
219
  for name, module in discovered_plugins.items():
220
- print(f"{name} -> {module.__version__}")
220
+ if hasattr(module, "__version__"):
221
+ print(f"{name} -> {module.__version__}")
222
+ else:
223
+ print(f"{name}")
221
224
 
222
225
  ctx.exit(0)
223
226
 
librelane/common/tcl.py CHANGED
@@ -16,7 +16,6 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
  import re
19
- import tkinter
20
19
  from typing import Dict, Mapping, Any, Iterable
21
20
 
22
21
  _env_rx = re.compile(r"(?:\:\:)?env\((\w+)\)")
@@ -59,6 +58,8 @@ class TclUtils(object):
59
58
 
60
59
  @staticmethod
61
60
  def _eval_env(env_in: Mapping[str, Any], tcl_in: str) -> Dict[str, Any]:
61
+ import tkinter
62
+
62
63
  interpreter = tkinter.Tcl()
63
64
 
64
65
  interpreter.eval("array unset ::env")
@@ -16,7 +16,6 @@ import inspect
16
16
  from enum import Enum
17
17
  from decimal import Decimal, InvalidOperation
18
18
  from dataclasses import (
19
- _MISSING_TYPE,
20
19
  MISSING,
21
20
  asdict,
22
21
  dataclass,
@@ -24,6 +23,7 @@ from dataclasses import (
24
23
  fields,
25
24
  is_dataclass,
26
25
  )
26
+ import types
27
27
  from typing import (
28
28
  ClassVar,
29
29
  Dict,
@@ -219,7 +219,8 @@ class Macro:
219
219
 
220
220
  def is_optional(t: Type[Any]) -> bool:
221
221
  type_args = get_args(t)
222
- return get_origin(t) is Union and type(None) in type_args
222
+ origin = get_origin(t)
223
+ return (origin is Union or origin is types.UnionType) and type(None) in type_args
223
224
 
224
225
 
225
226
  def some_of(t: Type[Any]) -> Type[Any]:
@@ -229,11 +230,20 @@ def some_of(t: Type[Any]) -> Type[Any]:
229
230
  # t must be a Union with None if we're here
230
231
 
231
232
  type_args = get_args(t)
233
+ origin = get_origin(t)
232
234
 
233
- args_without_none = [arg for arg in type_args if arg != type(None)]
235
+ args_without_none = [arg for arg in type_args if arg is not type(None)]
234
236
  if len(args_without_none) == 1:
235
237
  return args_without_none[0]
236
238
 
239
+ if origin is types.UnionType:
240
+ # Use the | operator to create a UnionType
241
+ result = args_without_none[0]
242
+ for arg in args_without_none[1:]:
243
+ result = result | arg
244
+ return result
245
+
246
+ # Otherwise, return a typing.Union
237
247
  new_union = Union[tuple(args_without_none)] # type: ignore
238
248
  return new_union # type: ignore
239
249
 
@@ -440,7 +450,7 @@ class Variable:
440
450
  return_value = list()
441
451
  raw = value
442
452
  if isinstance(raw, list) or isinstance(raw, tuple):
443
- if type_origin == list and type_args == (str,):
453
+ if type_origin is list and type_args == (str,):
444
454
  if any(isinstance(item, List) for item in raw):
445
455
  Variable.__flatten_list(value)
446
456
  pass
@@ -462,7 +472,7 @@ class Variable:
462
472
  f"List provided for variable '{key_path}' is invalid: {value}"
463
473
  )
464
474
 
465
- if type_origin == tuple:
475
+ if type_origin is tuple:
466
476
  if len(raw) != len(type_args):
467
477
  raise ValueError(
468
478
  f"Value provided for variable '{key_path}' of type {validating_type} is invalid: ({len(raw)}/{len(type_args)}) tuple entries provided"
@@ -481,11 +491,11 @@ class Variable:
481
491
  )
482
492
  )
483
493
 
484
- if type_origin == tuple:
494
+ if type_origin is tuple:
485
495
  return tuple(return_value)
486
496
 
487
497
  return return_value
488
- elif type_origin == dict:
498
+ elif type_origin is dict:
489
499
  raw = value
490
500
  key_type, value_type = type_args
491
501
  if isinstance(raw, dict):
@@ -586,7 +596,7 @@ class Variable:
586
596
  field_default = None
587
597
  if (
588
598
  current_field.default is not None
589
- and type(current_field.default) != _MISSING_TYPE
599
+ and current_field.default != MISSING
590
600
  ):
591
601
  field_default = current_field.default
592
602
  if current_field.default_factory != MISSING:
@@ -615,7 +625,7 @@ class Variable:
615
625
  result = Path(value)
616
626
  result.validate(f"Path provided for variable '{key_path}' is invalid")
617
627
  return result
618
- elif validating_type == bool:
628
+ elif validating_type is bool:
619
629
  if not permissive_typing and not isinstance(value, bool):
620
630
  raise ValueError(
621
631
  f"Refusing to automatically convert '{value}' at '{key_path}' to a Boolean"
@@ -629,7 +639,7 @@ class Variable:
629
639
  f"Value provided for variable '{key_path}' of type {validating_type.__name__} is invalid: '{value}'"
630
640
  )
631
641
  elif issubclass(validating_type, Enum):
632
- if type(value) == validating_type:
642
+ if type(value) is validating_type:
633
643
  return value
634
644
  try:
635
645
  return validating_type[value]
librelane/container.py CHANGED
@@ -57,10 +57,13 @@ def gui_args(osinfo: OSInfo) -> List[str]:
57
57
  args += [
58
58
  "-e",
59
59
  f"DISPLAY={os.environ.get('DISPLAY')}",
60
- "-v",
61
- "/tmp/.X11-unix:/tmp/.X11-unix",
62
- "-v",
63
- f"{os.path.expanduser('~')}/.Xauthority:/.Xauthority",
60
+ ]
61
+ if os.path.isdir("/tmp/.X11-unix"):
62
+ args += ["-v", "/tmp/.X11-unix:/tmp/.X11-unix"]
63
+ homedir = os.path.expanduser("~")
64
+ if os.path.isfile(f"{homedir}/.Xauthority"):
65
+ args += ["-v", f"{homedir}/.Xauthority:/.Xauthority"]
66
+ args += [
64
67
  "--network",
65
68
  "host",
66
69
  "--security-opt",
@@ -0,0 +1,18 @@
1
+ DESIGN_NAME: hold_violation
2
+ CLOCK_PORT: clk
3
+ CLOCK_PERIOD: 5
4
+ VERILOG_FILES: dir::demo.v
5
+ RUN_POST_CTS_RESIZER_TIMING: false
6
+ RUN_POST_GRT_RESIZER_TIMING: false
7
+ FP_SIZING: absolute
8
+ DIE_AREA: [0, 0, 100, 100]
9
+ INSERT_ECO_BUFFERS:
10
+ - target: u_ff1/Q
11
+ buffer: sky130_fd_sc_hd__buf_1
12
+ - target: u_ff1/Q
13
+ buffer: sky130_fd_sc_hd__buf_1
14
+ meta:
15
+ flow: Classic
16
+ substituting_steps:
17
+ "+OpenROAD.DetailedRouting": "Odb.InsertECOBuffers"
18
+ "+Odb.InsertECOBuffers": "OpenROAD.DetailedRouting"
@@ -0,0 +1,27 @@
1
+ module hold_violation(
2
+ input clk,
3
+ input d,
4
+ output q
5
+ );
6
+ wire intermediate;
7
+ wire clk_delayed;
8
+
9
+ sky130_fd_sc_hd__clkbuf_4 dly (
10
+ .A(clk),
11
+ .X(clk_delayed)
12
+ );
13
+
14
+ sky130_fd_sc_hd__dfrtp_4 u_ff1 (
15
+ .CLK(clk),
16
+ .D(d),
17
+ .RESET_B(1'b1),
18
+ .Q(intermediate)
19
+ );
20
+
21
+ sky130_fd_sc_hd__dfrtp_1 u_ff2 (
22
+ .CLK(clk_delayed),
23
+ .D(intermediate),
24
+ .RESET_B(1'b1),
25
+ .Q(q)
26
+ );
27
+ endmodule
librelane/flows/cli.py CHANGED
@@ -43,7 +43,7 @@ from cloup.typing import Decorator
43
43
 
44
44
  from .flow import Flow
45
45
  from ..common import set_tpe, cli, get_pdk_hash, _get_process_limit
46
- from ..logging import set_log_level, verbose, err, options, LogLevels
46
+ from ..logging import set_log_level, verbose, info, err, options, LogLevels
47
47
  from ..state import State, InvalidState
48
48
 
49
49
 
@@ -520,16 +520,29 @@ def cloup_flow_opts(
520
520
  err(f"Could not resolve the PDK '{pdk}'.")
521
521
  exit(1)
522
522
 
523
- version = ciel.fetch(
524
- ciel_home,
525
- pdk_family,
526
- opdks_rev,
527
- data_source=StaticWebDataSource(
528
- "https://fossi-foundation.github.io/ciel-releases"
529
- ),
530
- include_libraries=include_libraries,
531
- )
532
- pdk_root = version.get_dir(ciel_home)
523
+ if pdk_family == "ihp-sg13g2":
524
+ err(
525
+ "The IHP Open PDK is only supported in the development version of LibreLane, specifically 3.0.0.dev28 or higher."
526
+ )
527
+ info(
528
+ "If you're using Nix, switch to the 'dev' branch. If you're using the Python package, run \"python3 -m pip install 'librelane>=3.0.0.dev28'\"."
529
+ )
530
+ exit(1)
531
+
532
+ try:
533
+ version = ciel.fetch(
534
+ ciel_home,
535
+ pdk_family,
536
+ opdks_rev,
537
+ data_source=StaticWebDataSource(
538
+ "https://fossi-foundation.github.io/ciel-releases"
539
+ ),
540
+ include_libraries=include_libraries,
541
+ )
542
+ pdk_root = version.get_dir(ciel_home)
543
+ except ValueError as e:
544
+ err(f"Failed to download PDK: {e}")
545
+ exit(1)
533
546
 
534
547
  return f(*args, pdk_root=pdk_root, pdk=pdk, scl=scl, **kwargs)
535
548
 
@@ -248,13 +248,19 @@ def relocate_pins(db, input_lefs, template_def, permissive, copy_def_power=False
248
248
  pin_name = bterm.getName()
249
249
  pin_net_name = bterm.getNet().getName()
250
250
  pin_net = output_block.findNet(pin_net_name)
251
+ new_net_created = False
251
252
  if pin_net is None:
252
253
  pin_net = odb.dbNet.create(output_block, pin_net_name, True)
253
254
  pin_net.setSpecial()
254
255
  pin_net.setSigType(bterm.getSigType())
255
- pin_bterm = odb.dbBTerm.create(pin_net, pin_name)
256
- pin_bterm.setSigType(bterm.getSigType())
257
- output_bterms.append(pin_bterm)
256
+ new_net_created = True
257
+ pin_bterm = output_block.findBTerm(pin_name)
258
+ if pin_bterm is None:
259
+ pin_bterm = odb.dbBTerm.create(pin_net, pin_name)
260
+ pin_bterm.setSigType(bterm.getSigType())
261
+ output_bterms.append(pin_bterm)
262
+ elif new_net_created:
263
+ pin_bterm.connect(pin_net)
258
264
 
259
265
  grid_errors = False
260
266
  for output_bterm in output_bterms:
@@ -43,8 +43,9 @@ def cli(reader):
43
43
  grt_inc = GRT.IncrementalGRoute(grt, reader.block)
44
44
  i = 0
45
45
 
46
- for target_info in reader.config["INSERT_ECO_BUFFERS"]:
47
- target_name, target_pin = target_info["target"].rsplit("/", 1)
46
+ eco_buffers = reader.config["INSERT_ECO_BUFFERS"] or []
47
+ for target_info in eco_buffers:
48
+ target_name, target_pin = target_info["target"].split("/")
48
49
  name_escaped = reader.escape_verilog_name(target_name)
49
50
  buffer_master = target_info["buffer"]
50
51
 
@@ -38,9 +38,9 @@ def cli(reader):
38
38
  # print(grt)
39
39
  grt_inc = GRT.IncrementalGRoute(grt, reader.block)
40
40
  i = 0
41
-
42
- for target_info in reader.config["INSERT_ECO_DIODES"]:
43
- target_name, target_pin = target_info["target"].rsplit("/", 1)
41
+ diodes = reader.config["INSERT_ECO_DIODES"] or []
42
+ for target_info in diodes:
43
+ target_name, target_pin = target_info["target"].split("/")
44
44
  name_escaped = reader.escape_verilog_name(target_name)
45
45
 
46
46
  target = reader.block.findInst(name_escaped)
@@ -47,8 +47,9 @@ def load_step_from_inputs(
47
47
  if Found := Step.factory.get(id):
48
48
  Target = Found
49
49
  else:
50
- err(
51
- f"No step registered with id '{id}'. Ensure all relevant plugins are installed."
50
+ err(f"No step registered with id '{id}'.")
51
+ info(
52
+ f"If the step '{id}' is part of a plugin, make sure the plugin's parent directory is in the PYTHONPATH environment variable."
52
53
  )
53
54
  ctx.exit(-1)
54
55
 
@@ -79,22 +79,21 @@ class MetricChecker(Step):
79
79
  deferred: ClassVar[bool] = True
80
80
  error_on_var: Optional[Variable] = None
81
81
 
82
- @classmethod
83
- def get_help_md(Self, **kwargs): # pragma: no cover
84
- threshold_string = Self.get_threshold_description(None)
82
+ def __init_subclass__(cls):
83
+ threshold_string = cls.get_threshold_description(None)
85
84
  if threshold_string is None:
86
- threshold_string = str(Self.get_threshold(None))
85
+ threshold_string = str(cls.get_threshold(None))
87
86
  dynamic_docstring = "Raises"
88
- if Self.deferred:
87
+ if cls.deferred:
89
88
  dynamic_docstring += " a deferred error"
90
89
  else:
91
90
  dynamic_docstring += " an immediate error"
92
- dynamic_docstring += f" if {Self.metric_description} (metric: ``{Self.metric_name}``) are >= {threshold_string}."
91
+ dynamic_docstring += f" if {cls.metric_description} (metric: ``{cls.metric_name}``) are >= {threshold_string}."
93
92
  dynamic_docstring += (
94
93
  " Doesn't raise an error depending on error_on_var if defined."
95
94
  )
96
-
97
- return super().get_help_md(docstring_override=dynamic_docstring, **kwargs)
95
+ cls.__doc__ = dynamic_docstring
96
+ return super().__init_subclass__()
98
97
 
99
98
  def get_threshold(self: Optional["MetricChecker"]) -> Optional[Decimal]:
100
99
  return Decimal(0)
@@ -353,6 +353,15 @@ class XOR(KLayoutStep):
353
353
 
354
354
  @Step.factory.register()
355
355
  class DRC(KLayoutStep):
356
+ """
357
+ Runs DRC using KLayout.
358
+
359
+ Unlike most steps, the KLayout scripts vary quite wildly by PDK. If a PDK
360
+ is not supported by this step, it will simply be skipped.
361
+
362
+ Currently, only sky130A and sky130B are supported.
363
+ """
364
+
356
365
  id = "KLayout.DRC"
357
366
  name = "Design Rule Check (KLayout)"
358
367
 
librelane/steps/misc.py CHANGED
@@ -53,6 +53,11 @@ class LoadBaseSDC(Step):
53
53
 
54
54
  @Step.factory.register()
55
55
  class ReportManufacturability(Step):
56
+ """
57
+ Logs a simple "manufacturability report", i.e., the status of DRC, LVS, and
58
+ antenna violations.
59
+ """
60
+
56
61
  id = "Misc.ReportManufacturability"
57
62
  name = "Report Manufacturability"
58
63
  long_name = "Report Manufacturability (DRC, LVS, Antenna)"
librelane/steps/odb.py CHANGED
@@ -184,6 +184,10 @@ class OdbpyStep(Step):
184
184
 
185
185
  @Step.factory.register()
186
186
  class CheckMacroAntennaProperties(OdbpyStep):
187
+ """
188
+ Prints warnings if the LEF views of macros are missing antenna information.
189
+ """
190
+
187
191
  id = "Odb.CheckMacroAntennaProperties"
188
192
  name = "Check Antenna Properties of Macros Pins in Their LEF Views"
189
193
  inputs = OdbpyStep.inputs
@@ -221,6 +225,10 @@ class CheckMacroAntennaProperties(OdbpyStep):
221
225
 
222
226
  @Step.factory.register()
223
227
  class CheckDesignAntennaProperties(CheckMacroAntennaProperties):
228
+ """
229
+ Prints warnings if the LEF view of the design is missing antenna information.
230
+ """
231
+
224
232
  id = "Odb.CheckDesignAntennaProperties"
225
233
  name = "Check Antenna Properties of Pins in The Generated Design LEF view"
226
234
  inputs = CheckMacroAntennaProperties.inputs + [DesignFormat.LEF]
@@ -527,6 +535,11 @@ class ReportDisconnectedPins(OdbpyStep):
527
535
 
528
536
  @Step.factory.register()
529
537
  class AddRoutingObstructions(OdbpyStep):
538
+ """
539
+ Adds obstructions on metal layers which prevent shapes from being created in
540
+ the designated areas.
541
+ """
542
+
530
543
  id = "Odb.AddRoutingObstructions"
531
544
  name = "Add Obstructions"
532
545
  config_vars = [
@@ -569,6 +582,11 @@ class AddRoutingObstructions(OdbpyStep):
569
582
 
570
583
  @Step.factory.register()
571
584
  class RemoveRoutingObstructions(AddRoutingObstructions):
585
+ """
586
+ Removes any routing obstructions previously placed by
587
+ <#Odb.AddRoutingObstructions>`_.
588
+ """
589
+
572
590
  id = "Odb.RemoveRoutingObstructions"
573
591
  name = "Remove Obstructions"
574
592
 
@@ -578,6 +596,15 @@ class RemoveRoutingObstructions(AddRoutingObstructions):
578
596
 
579
597
  @Step.factory.register()
580
598
  class AddPDNObstructions(AddRoutingObstructions):
599
+ """
600
+ Adds obstructions on metal layers which prevent shapes from being created in
601
+ the designated areas.
602
+
603
+ A soft-duplicate of <#Odb.AddRoutingObstructions>`_ , though this one uses
604
+ a different variable name so the obstructions can be restricted for PDN
605
+ steps only.
606
+ """
607
+
581
608
  id = "Odb.AddPDNObstructions"
582
609
  name = "Add PDN obstructions"
583
610
 
@@ -595,6 +622,11 @@ class AddPDNObstructions(AddRoutingObstructions):
595
622
 
596
623
  @Step.factory.register()
597
624
  class RemovePDNObstructions(RemoveRoutingObstructions):
625
+ """
626
+ Removes any PDN obstructions previously placed by
627
+ <#Odb.RemovePDNObstructions>`_.
628
+ """
629
+
598
630
  id = "Odb.RemovePDNObstructions"
599
631
  name = "Remove PDN obstructions"
600
632
 
@@ -1518,11 +1518,6 @@ class GlobalPlacementSkipIO(_GlobalPlacement):
1518
1518
  "Path to a custom pin configuration file.",
1519
1519
  deprecated_names=["FP_PIN_ORDER_CFG"],
1520
1520
  ),
1521
- Variable(
1522
- "FP_DEF_TEMPLATE",
1523
- Optional[Path],
1524
- "Points to the DEF file to be used as a template.",
1525
- ),
1526
1521
  ]
1527
1522
 
1528
1523
  def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
librelane/steps/pyosys.py CHANGED
@@ -327,6 +327,12 @@ class VerilogStep(PyosysStep):
327
327
 
328
328
  @Step.factory.register()
329
329
  class JsonHeader(VerilogStep):
330
+ """
331
+ Extracts a high-level hierarchical view of the circuit in JSON format,
332
+ including power connections. The power connections are used in later steps
333
+ to ensure macros and cells are connected as desired.
334
+ """
335
+
330
336
  id = "Yosys.JsonHeader"
331
337
  name = "Generate JSON Header"
332
338
  long_name = "Generate JSON Header"
librelane/steps/yosys.py CHANGED
@@ -258,6 +258,14 @@ class YosysStep(TclStep):
258
258
 
259
259
  @Step.factory.register()
260
260
  class EQY(Step):
261
+ """
262
+ Experimental: Uses the `EQY <https://github.com/yosyshq/eqy>`_ utility to
263
+ perform an RTL vs. Netlist equivalence check.
264
+
265
+ Currently, you are expected to provide your own EQY script if you want this
266
+ to work properly.
267
+ """
268
+
261
269
  id = "Yosys.EQY"
262
270
  name = "Equivalence Check"
263
271
  long_name = "RTL/Netlist Equivalence Check"
@@ -272,7 +280,7 @@ class EQY(Step):
272
280
  Variable(
273
281
  "EQY_SCRIPT",
274
282
  Optional[Path],
275
- "An optional override for the automatically generated EQY script for more complex designs.",
283
+ "The EQY script to use. If unset, a generic EQY script will be generated, but this fails in a number of scenarios.",
276
284
  ),
277
285
  Variable(
278
286
  "MACRO_PLACEMENT_CFG",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: librelane
3
- Version: 3.0.0.dev40
3
+ Version: 3.0.0.dev42
4
4
  Summary: An infrastructure for implementing chip design flows
5
5
  License-Expression: Apache-2.0
6
6
  Maintainer: Mohamed Gaber
@@ -1,5 +1,5 @@
1
- librelane/__init__.py,sha256=EMpoZrRmS_wsweKjhyAg52OXCK7HWQ8o8CVrYaX4ub0,1220
2
- librelane/__main__.py,sha256=-yJXvww0nKyt-jcOl_QLnZskKZDL_2zScEgjSZ-7ANE,14702
1
+ librelane/__init__.py,sha256=Xbz6e-J9pNxv0AIi89-mApMEQQtRgxJyzHS6yYc00Y0,1221
2
+ librelane/__main__.py,sha256=ZuqbIeyoGOZFJBdTvSOBLA_3PMAohzYBL3V76KfoB1I,14804
3
3
  librelane/__version__.py,sha256=dbE4stCACDmIoxgKksesAkTa-_hi5dW6nPLWw9Pfq3Q,1486
4
4
  librelane/common/__init__.py,sha256=fK52kxuueEpKI1HNNhUOJFQ4yvxJs0f0Vz1a5S-CBGY,1569
5
5
  librelane/common/cli.py,sha256=xi48GBGHRsYrLGwx40ARwpykHx7GnuHbJjHxjOwtZ5Y,2349
@@ -12,7 +12,7 @@ librelane/common/metrics/metric.py,sha256=h3Xd26z5M80IJgVmmrBTjKcdGLb4I0wyjM-H4j
12
12
  librelane/common/metrics/util.py,sha256=Bl_9znlot7-Os2VigYLSmMf56aAkGdv3evWz9vfK7K4,9344
13
13
  librelane/common/misc.py,sha256=_xoU3lnA9Odf1PidjCJ4RDiGZQ3nd3YNGyooHu4RHe4,14757
14
14
  librelane/common/ring_buffer.py,sha256=DGFen9y0JOmiL7E27tmzDTVSJKZtV-waF9hl5Rz9uek,1898
15
- librelane/common/tcl.py,sha256=AfTxbSLA0VUXVMMwoAQndyQTcEZQoQfMa4FFizZiEgU,4341
15
+ librelane/common/tcl.py,sha256=kq09m9dj-RK7uvvduAgxHMCf0xjzMRS9IPcrhQFl-Xc,4350
16
16
  librelane/common/toolbox.py,sha256=ijR__rVqQ_nJtfm34H-VdSCIeArKns7lVAc1TcTUSsQ,20975
17
17
  librelane/common/tpe.py,sha256=Txj0fVscXSDJTYmEKZ2ESFHOeqrhHnaPPiwWBgyx4g8,1285
18
18
  librelane/common/types.py,sha256=xo_OKq-2ue7JVpyQb6oUu6JuVSnLNEFKQCPBqNhZnQ4,3509
@@ -23,9 +23,11 @@ librelane/config/flow.py,sha256=Dr2i9MlCcGFg_ilCpeys3vPo_DLDb1yF6yGrMCZZabE,1700
23
23
  librelane/config/pdk_compat.py,sha256=ofqYuD-MgTcfvPVXpGJo8H1GKzCvN6sxHsK_OqCVXa8,12870
24
24
  librelane/config/preprocessor.py,sha256=ATi29SHz0_OBq1IqUkGxvhHUDKB5z5jO0KqvoQXg8R8,14913
25
25
  librelane/config/removals.py,sha256=vxqTuRTJ0jt2TX4KmFZCZPTwghDFkCVjIhF2iReHwJA,2958
26
- librelane/config/variable.py,sha256=oPPdvo12Gy17sIcEJtjJkrIO93AOUSrIZaG_ocL70vI,26837
27
- librelane/container.py,sha256=7w_V2Fpb3dbnZ8FqBce1vK31jH30UrxByppfEJRyG9M,8672
26
+ librelane/config/variable.py,sha256=SKhMJT3jnJt7w3vZacD8_4n5YUH3hecG0iAnHjZrkPk,27162
27
+ librelane/container.py,sha256=GN1lqVguuqPAuTxINii-bWKBKmIQ-VJc0WHPDEp73sU,8829
28
28
  librelane/env_info.py,sha256=xF9iqwwJv5yZz7n7BTrrT_yP3Dp1HjAOUObNE9k_1g4,11074
29
+ librelane/examples/hold_eco_demo/config.yaml,sha256=InDj4pS6o6TpyvQZyR3qCrYcIHdmCd6l04wqanKnK_A,490
30
+ librelane/examples/hold_eco_demo/demo.v,sha256=0In_gDLH1svr4xK59l5N15VjCNtN74uZx1yT5tIVGrM,471
29
31
  librelane/examples/spm/config.yaml,sha256=H2ERY4xoIeXN7kM3N9yGWiFBbtByyaN2Ni1kFqYPtO4,612
30
32
  librelane/examples/spm/pin_order.cfg,sha256=-8mTGFKnES0vhQATfaE2TXN_mdCZ3SZIN90Src1l6fY,52
31
33
  librelane/examples/spm/src/impl.sdc,sha256=wP18UoVlOJ9q4lmUoa3XpgcpPdyzEqHBNxCgOOU7QH0,2961
@@ -42,7 +44,7 @@ librelane/examples/spm-user_project_wrapper/user_project_wrapper.v,sha256=zc6GC5
42
44
  librelane/flows/__init__.py,sha256=ghtmUG-taVpHJ3CKJRYZGn3dU0r93araT1EIGlBEsxg,896
43
45
  librelane/flows/builtins.py,sha256=tR14Qc1ZUey2w-Ar4DWOvxuP7LGPtMecCJq8WgcYJpk,773
44
46
  librelane/flows/classic.py,sha256=JB9gVgP2hHPhMuCJg7hvoj2BvJcvRec7suEXPgHmz14,10971
45
- librelane/flows/cli.py,sha256=ClFU3f81I5PDUMg249UzSdlYU_iZoX_CaEQtYpwvkA8,19346
47
+ librelane/flows/cli.py,sha256=c0kSA5i5yr1VtBCqCPJ02T0r176CU_E6pk2EsXyWbZY,20062
46
48
  librelane/flows/flow.py,sha256=kV6874HFxceFCrGpv4V7hjplajUpd7OvEyU5-2OhGQg,37128
47
49
  librelane/flows/misc.py,sha256=32Om3isexesfKKiJZCajNmINc-xdv7eVx_tgoh9SR6U,2015
48
50
  librelane/flows/optimizing.py,sha256=OwZz6WGmXpliwO8vtmhjKHD-kzDyNv-zoCECZIigXsI,6076
@@ -83,11 +85,11 @@ librelane/scripts/odbpy/apply_def_template.py,sha256=Tn6y65biu0bAQ6XilYxq5jn3a_K
83
85
  librelane/scripts/odbpy/cell_frequency.py,sha256=NfGgM8wxIvjM1C_GHUghZPOh8gpdasLOWR4qBdHHLFE,3105
84
86
  librelane/scripts/odbpy/check_antenna_properties.py,sha256=dMD-RcoA7plcAu9IIqa2e-8XCO0EMcKG-6P39D3Gpic,3942
85
87
  librelane/scripts/odbpy/contextualize.py,sha256=G8EEgmK6ISikXD2-Pw-RTs1JxLWPnuppwL7oPfAsb84,4020
86
- librelane/scripts/odbpy/defutil.py,sha256=g0UaAQRt8hXb9nfI6SbMp_Hx__0o1POw33_fS6xyibU,17849
88
+ librelane/scripts/odbpy/defutil.py,sha256=gBANy_XTeLeXRBMGdCy2vI5y44qMB6E_Fy0VeyW6rUg,18104
87
89
  librelane/scripts/odbpy/diodes.py,sha256=qpsTW2RQlqNm4pzrUFm7d0Jj4x4zSQqladcv5SJF7XI,11752
88
90
  librelane/scripts/odbpy/disconnected_pins.py,sha256=hS_Iletg7N6K6yN_ccvWxZ3nWNZp4ecUJM-oY0kkEfA,11139
89
- librelane/scripts/odbpy/eco_buffer.py,sha256=GnqKNEXqBb_NE6JWqnjp5Sx6baUD1pEEXclxlm6hbSU,6260
90
- librelane/scripts/odbpy/eco_diode.py,sha256=RK1_58Jwx4ufJp_XRXEAScTQL4J3h-jt0C7VUMNm9p0,4286
91
+ librelane/scripts/odbpy/eco_buffer.py,sha256=lb7KtVZUzXSkPq9mRTXPVnSo_isy4845wohLFPhDN30,6292
92
+ librelane/scripts/odbpy/eco_diode.py,sha256=LSM3D0ygE7_vSHbXt49DU1R068NkqmSYVlb32a3scZI,4307
91
93
  librelane/scripts/odbpy/filter_unannotated.py,sha256=Gvcaj_WNr6TPiHk-36nkMu4betNHZo1g2lD3UcA9hDQ,2950
92
94
  librelane/scripts/odbpy/io_place.py,sha256=LSJIJQDLSOpENyQOg_kVTIbh1AbYLiHIXx0siduo-lg,15589
93
95
  librelane/scripts/odbpy/ioplace_parser/__init__.py,sha256=_xCDqam3PxWO-uhTZ6afdn3dpuu4XlX2T_RaOn7QqJQ,877
@@ -151,23 +153,23 @@ librelane/state/__main__.py,sha256=Ici4Ejg1ICUZNSYZRguC3BfEk_wFxsmE0ag0Vv8iY1I,1
151
153
  librelane/state/design_format.py,sha256=v1Nj-glM3Nc6SVXMZKanAMiaBjgDnW8KjAlmr_TiOqk,6560
152
154
  librelane/state/state.py,sha256=tYn2si8NlkVErOSWKfVhsgrMpyxeX2Hv9EAPsQBWx2c,11902
153
155
  librelane/steps/__init__.py,sha256=j3JYrdnWM74dYuEvE931oSrQI7FUz-hKWr8Mts8C0wg,1668
154
- librelane/steps/__main__.py,sha256=GQZiV4s-9GIF4AwP34W61zwgzMvPp-QTR4cNELi7r5c,13349
155
- librelane/steps/checker.py,sha256=HD5YFPAbHQKsFmBDrIAbo_0clZcCszNhIXb4lHaNIeQ,21629
156
+ librelane/steps/__main__.py,sha256=p7eQ8l8V47RBmQifLcwZPXbEN807qR9ICUx4sMwM7fY,13450
157
+ librelane/steps/checker.py,sha256=FCyKa9K9xEPTHbZIBSH379eT77erQloQKf46q-8kd90,21581
156
158
  librelane/steps/common_variables.py,sha256=NA0zH_amgyiorfPrBu6YJIt9En4wkycYRox11bJ1CoY,13764
157
159
  librelane/steps/cvc_rv.py,sha256=qeroQPjidSAMYSp3nJNiQBYt8V73kkz3JK97uioo7J8,5294
158
- librelane/steps/klayout.py,sha256=18B7trKjyD8HnGUVwrjQV8XRzGu298CuosM1WOzg9oM,23255
160
+ librelane/steps/klayout.py,sha256=aNzAGYQzkihnYt_P51BQ3du3AaZpD2ms6tSrMtPtwWw,23497
159
161
  librelane/steps/magic.py,sha256=a7OfO9S8zhrn8eGsgAa_IriiPirmaOXDOUqc8LEkhZU,21807
160
- librelane/steps/misc.py,sha256=8ubCvFeFEspXrgnzNWINY5-TXTyalNtlvcX8TSw0qdg,5685
162
+ librelane/steps/misc.py,sha256=3O-6V3QPnqsYACoogg9I7SrJ7C0VMQbtA0anF13wa7w,5806
161
163
  librelane/steps/netgen.py,sha256=R9sDWv-9wKMdi2rkuLQdOc4uLlbYhXcKKd6WsZsnLt0,8953
162
- librelane/steps/odb.py,sha256=szve7HMRVR9kWrIHkeViyeGszXlNd9k-oP9litb_tmo,38931
163
- librelane/steps/openroad.py,sha256=Mma0nPoEJ6JdYmZF24Uju21RL332wN9FH8GeOgMj9Qk,100890
164
+ librelane/steps/odb.py,sha256=D-x_geZH3t-3-jmTgDc4DiSSEFLXoG6UrhPpPHAnoPU,39766
165
+ librelane/steps/openroad.py,sha256=-wkSYnBTM-36jc6ZTzBmmCf-asExHFupk61Z-fCU-LA,100738
164
166
  librelane/steps/openroad_alerts.py,sha256=IJyB4piBDCKXhkJswHGMYCRDwbdQsR0GZlrGGDhmW6Q,3364
165
- librelane/steps/pyosys.py,sha256=CqHpKPbLb199E5g9axfeUSGlzdgoXdmuy4iRBSdjjQ4,24978
167
+ librelane/steps/pyosys.py,sha256=yVBk_Tv2GCTN3m4cIMBlPePQZSoU2qxNeKVjaa6Q7ug,25206
166
168
  librelane/steps/step.py,sha256=tYTN5QzX0huhFMLegpir4mPi3q9QAVSFZ7kchW6OECk,55849
167
169
  librelane/steps/tclstep.py,sha256=68AjCmbLhBscbzQDxRcPQVU-6UvZQNOalO7qNwUXCa4,10138
168
170
  librelane/steps/verilator.py,sha256=m3vcsBStF4i1eutzHdWHPGGoSEBwQrCKMY2k-1qJbMI,8964
169
- librelane/steps/yosys.py,sha256=lYdZPFvjcmdu_NE6rtB94_dysIK2qwGdGb480W6pg2w,12711
170
- librelane-3.0.0.dev40.dist-info/METADATA,sha256=wFojMkKM8YiFCuQTjcUa_jUXyZD7zNVaiUA_Vn_uzzU,6572
171
- librelane-3.0.0.dev40.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
172
- librelane-3.0.0.dev40.dist-info/entry_points.txt,sha256=Ub2wE2U4uZPjJgBVTPYFeXtwhNyqAqaKT8q4jGoKIUk,274
173
- librelane-3.0.0.dev40.dist-info/RECORD,,
171
+ librelane/steps/yosys.py,sha256=m67kD6F7aJ3ObKRBdbXwYUkzbma5FVZ5YrqdTq_Wyjs,12983
172
+ librelane-3.0.0.dev42.dist-info/METADATA,sha256=Uvz4FzXxcRasVLZpshNZqVFcxh0eYbpHhIYJDYkVwSs,6572
173
+ librelane-3.0.0.dev42.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
174
+ librelane-3.0.0.dev42.dist-info/entry_points.txt,sha256=Ub2wE2U4uZPjJgBVTPYFeXtwhNyqAqaKT8q4jGoKIUk,274
175
+ librelane-3.0.0.dev42.dist-info/RECORD,,