librelane 3.0.0.dev22__py3-none-any.whl → 3.0.0.dev24__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/__main__.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2025 The American University in Cairo
1
+ # Copyright 2025 LibreLane Contributors
2
2
  #
3
3
  # Adapted from OpenLane
4
4
  #
@@ -14,7 +14,6 @@
14
14
  import os
15
15
  import sys
16
16
  import json
17
- import functools
18
17
  from decimal import Decimal
19
18
 
20
19
  import click
@@ -111,9 +110,7 @@ def create_config(
111
110
  print("At least one source RTL file is required.", file=sys.stderr)
112
111
  exit(1)
113
112
  source_rtl_key = "VERILOG_FILES"
114
- if not functools.reduce(
115
- lambda acc, x: acc and (x.endswith(".sv") or x.endswith(".v")), source_rtl, True
116
- ):
113
+ if not all((file.endswith(".sv") or file.endswith(".v")) for file in source_rtl):
117
114
  print(
118
115
  "Only Verilog/SystemVerilog files are supported by create-config.",
119
116
  file=sys.stderr,
@@ -42,4 +42,5 @@ removed_variables: Dict[str, str] = {
42
42
  "FP_PADFRAME_CFG": "To be implemented.",
43
43
  "FP_CONTEXT_DEF": "To be implemented.",
44
44
  "FP_CONTEXT_LEF": "To be implemented.",
45
+ "SYNLIG_DEFER": "Synlig replaced with Slang.",
45
46
  }
@@ -575,7 +575,7 @@ class Variable:
575
575
  kwargs_dict = {}
576
576
  for current_field in fields(validating_type):
577
577
  key = current_field.name
578
- subtype = current_field.type
578
+ subtype: Type[Any] = current_field.type # type: ignore
579
579
  explicitly_specified = False
580
580
  if key in raw:
581
581
  explicitly_specified = True
@@ -1,4 +1,4 @@
1
- # Copyright 2025 The American University in Cairo
1
+ # Copyright 2025 LibreLane Contributors
2
2
  #
3
3
  # Adapted from ioplace_parser
4
4
  #
@@ -1,4 +1,4 @@
1
- # Copyright 2025 The American University in Cairo
1
+ # Copyright 2025 LibreLane Contributors
2
2
  #
3
3
  # Adapted from ioplace_parser
4
4
  #
@@ -166,7 +166,7 @@ class OdbReader(object):
166
166
  grt.setMinLayerForClock(min_clk_idx)
167
167
  grt.setMaxLayerForClock(max_clk_idx)
168
168
  grt.setMacroExtension(self.config["GRT_MACRO_EXTENSION"])
169
- grt.setOverflowIterations(self.config["GRT_OVERFLOW_ITERS"])
169
+ grt.setCongestionIterations(self.config["GRT_OVERFLOW_ITERS"])
170
170
  grt.setAllowCongestion(self.config["GRT_ALLOW_CONGESTION"])
171
171
  grt.setVerbose(True)
172
172
  grt.initFastRoute(min_layer_idx, max_layer_idx)
@@ -174,9 +174,9 @@ proc read_timing_info {args} {
174
174
  foreach nl $::env(_CURRENT_CORNER_NETLISTS) {
175
175
  puts "Reading macro netlist at '$nl'…"
176
176
  if { [catch {read_verilog $nl} err] } {
177
- puts "Error while reading macro netlist '$nl':"
178
- puts $err
179
- puts "Make sure that this a gate-level netlist and not an RTL file."
177
+ puts stderr "Error while reading macro netlist '$nl':"
178
+ puts stderr $err
179
+ puts stderr "Make sure that this a gate-level netlist and not an RTL file."
180
180
  exit 1
181
181
  }
182
182
  }
@@ -185,9 +185,9 @@ proc read_timing_info {args} {
185
185
  if { [string_in_file $verilog_file $blackbox_wildcard] } {
186
186
  puts "Found '$blackbox_wildcard' in '$verilog_file', skipping…"
187
187
  } elseif { [catch {puts "Reading Verilog model at '$verilog_file'…"; read_verilog $verilog_file} err] } {
188
- puts "Error while reading $verilog_file:"
189
- puts $err
190
- puts "Make sure that this a gate-level netlist and not an RTL file, otherwise, you can add the following comment '$blackbox_wildcard' in the file to skip it and blackbox the modules inside if needed."
188
+ puts stderr "Error while reading $verilog_file:"
189
+ puts stderr $err
190
+ puts stderr "Make sure that this a gate-level netlist and not an RTL file, otherwise, you can add the following comment '$blackbox_wildcard' in the file to skip it and blackbox the modules inside if needed."
191
191
  exit 1
192
192
  }
193
193
  }
@@ -411,6 +411,13 @@ proc write_views {args} {
411
411
  write_verilog $::env(SAVE_NL)
412
412
  }
413
413
 
414
+ if { [info exists ::env(SAVE_LOGICAL_NL)] } {
415
+ puts "Writing logic-only netlist to '$::env(SAVE_LOGICAL_NL)'…"
416
+ write_verilog\
417
+ -remove_cells "[get_physical_cells]"\
418
+ $::env(SAVE_LOGICAL_NL)
419
+ }
420
+
414
421
  if { [info exists ::env(SAVE_PNL)] } {
415
422
  puts "Writing powered netlist to '$::env(SAVE_PNL)'…"
416
423
  write_verilog -include_pwr_gnd $::env(SAVE_PNL)
@@ -575,7 +582,8 @@ proc get_layers {args} {
575
582
  flags {-constrained}
576
583
 
577
584
  if { ![info exists keys(-types)] } {
578
- puts "\[ERROR\] Invalid usage of get_layers: -types is required."
585
+ puts stderr "\[ERROR\] Invalid usage of get_layers: -types is required."
586
+ return -code error
579
587
  }
580
588
 
581
589
  set layers [$::tech getLayers]
@@ -94,8 +94,7 @@ if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
94
94
  -grid stdcell_grid \
95
95
  -layer $::env(FP_PDN_RAIL_LAYER) \
96
96
  -width $::env(FP_PDN_RAIL_WIDTH) \
97
- -followpins \
98
- -starts_with POWER
97
+ -followpins
99
98
 
100
99
  add_pdn_connect \
101
100
  -grid stdcell_grid \
@@ -107,6 +106,7 @@ if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
107
106
  if { $::env(FP_PDN_CORE_RING) == 1 } {
108
107
  if { $::env(FP_PDN_MULTILAYER) == 1 } {
109
108
  add_pdn_ring \
109
+ -allow_out_of_die \
110
110
  -grid stdcell_grid \
111
111
  -layers "$::env(FP_PDN_VERTICAL_LAYER) $::env(FP_PDN_HORIZONTAL_LAYER)" \
112
112
  -widths "$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)" \
@@ -56,7 +56,7 @@ proc set_global_connections {} {
56
56
  }
57
57
  }
58
58
  if { $matched != 1 } {
59
- puts "\[ERROR\] No match found for regular expression '$instance_name' defined in PDN_MACRO_CONNECTIONS."
59
+ puts stderr "\[ERROR\] No match found for regular expression '$instance_name' defined in PDN_MACRO_CONNECTIONS."
60
60
  exit_unless_gui 1
61
61
  }
62
62
 
@@ -17,8 +17,8 @@ proc drt_run {i args} {
17
17
  set output_drc "-output_drc $::env(STEP_DIR)/$directory/$::env(DESIGN_NAME).drc"
18
18
  log_cmd detailed_route {*}$args {*}$output_drc
19
19
  if { $::env(DRT_SAVE_SNAPSHOTS) } {
20
- foreach snapshot [glob -nocomplain drt_iter*.odb] {
21
- file rename -force $snapshot $directory/[file tail $snapshot]
20
+ foreach snapshot [glob -nocomplain $::env(STEP_DIR)/drt_iter*.odb] {
21
+ file rename -force $snapshot $::env(STEP_DIR)/$directory/[file tail $snapshot]
22
22
  }
23
23
  }
24
24
  foreach drc_file [glob -nocomplain $::env(STEP_DIR)/$directory/*.drc] {
@@ -41,13 +41,11 @@ set max_layer $::env(RT_MAX_LAYER)
41
41
  if { [info exists ::env(DRT_MAX_LAYER)] } {
42
42
  set max_layer $::env(DRT_MAX_LAYER)
43
43
  }
44
- if { $::env(DRT_SAVE_SNAPSHOTS) } {
45
- set_debug_level DRT snapshot 1
46
- }
47
44
  set drc_report_iter_step_arg ""
48
45
  if { $::env(DRT_SAVE_SNAPSHOTS) } {
49
46
  set_debug_level DRT snapshot 1
50
47
  set drc_report_iter_step_arg "-drc_report_iter_step 1"
48
+ detailed_route_debug -snapshot_dir "$::env(STEP_DIR)/$directory"
51
49
  }
52
50
  if { [info exists ::env(DRT_SAVE_DRC_REPORT_ITERS)] } {
53
51
  set drc_report_iter_step_arg "-drc_report_iter_step $::env(DRT_SAVE_DRC_REPORT_ITERS)"
@@ -33,10 +33,18 @@ puts "Using site height: $::default_site_height and site width: $::default_site_
33
33
 
34
34
  unset_propagated_clock [all_clocks]
35
35
 
36
- set bottom_margin [expr $::default_site_height * $::env(BOTTOM_MARGIN_MULT)]
37
- set top_margin [expr $::default_site_height * $::env(TOP_MARGIN_MULT)]
38
- set left_margin [expr $::default_site_width * $::env(LEFT_MARGIN_MULT)]
39
- set right_margin [expr $::default_site_width * $::env(RIGHT_MARGIN_MULT)]
36
+ proc set_margin {var site_dimension mult} {
37
+ set value [expr $site_dimension * $mult]
38
+ if { $value < 0 } {
39
+ puts stderr "\[ERROR IFP-0013\] Negative values not allowed for margins."
40
+ exit_unless_gui 1
41
+ }
42
+ uplevel 1 set "$var $value"
43
+ }
44
+ set_margin bottom_margin $::default_site_height $::env(BOTTOM_MARGIN_MULT)
45
+ set_margin top_margin $::default_site_height $::env(TOP_MARGIN_MULT)
46
+ set_margin left_margin $::default_site_width $::env(LEFT_MARGIN_MULT)
47
+ set_margin right_margin $::default_site_width $::env(RIGHT_MARGIN_MULT)
40
48
 
41
49
  set arg_list [list]
42
50
 
@@ -30,10 +30,10 @@ foreach {instance_name macro_name} $::env(_check_macro_instances) {
30
30
  set instances [get_cells -hierarchical $instance_name]
31
31
  set instance_count [llength $instances]
32
32
  if { $instance_count < 1 } {
33
- puts "\[ERROR\] No macro instance $instance_name found."
33
+ puts stderr "\[ERROR\] No macro instance $instance_name found."
34
34
  incr error_count
35
35
  } elseif { $instance_count > 1 } {
36
- puts "\[ERROR\] Macro instance name $instance_name matches multiple cells."
36
+ puts stderr "\[ERROR\] Macro instance name $instance_name matches multiple cells."
37
37
  incr error_count
38
38
  } else {
39
39
  # The next line doesn't actually matter because this is Tcl but I'd feel
@@ -42,7 +42,7 @@ foreach {instance_name macro_name} $::env(_check_macro_instances) {
42
42
 
43
43
  set master_name [get_property $instance ref_name]
44
44
  if { $master_name != $macro_name } {
45
- puts "\[ERROR\] Instance $instance_name is configured as an instance of macro $macro_name, but is an instance of $master_name."
45
+ puts stderr "\[ERROR\] Instance $instance_name is configured as an instance of macro $macro_name, but is an instance of $master_name."
46
46
  incr error_count
47
47
  }
48
48
  }
@@ -54,7 +54,7 @@ puts "\n========================================================================
54
54
  puts "report_checks -path_delay min (Hold)"
55
55
  puts "============================================================================"
56
56
  puts "======================= [$corner name] Corner ===================================\n"
57
- report_checks -sort_by_slack -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 1000 -corner [$corner name]
57
+ report_checks -sort_by_slack -path_delay min -fields {slew cap input net fanout} -format full_clock_expanded -group_path_count 1000 -corner [$corner name]
58
58
  puts ""
59
59
  puts "%OL_END_REPORT"
60
60
 
@@ -64,7 +64,7 @@ puts "\n========================================================================
64
64
  puts "report_checks -path_delay max (Setup)"
65
65
  puts "============================================================================"
66
66
  puts "======================= [$corner name] Corner ===================================\n"
67
- report_checks -sort_by_slack -path_delay max -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 1000 -corner [$corner name]
67
+ report_checks -sort_by_slack -path_delay max -fields {slew cap input net fanout} -format full_clock_expanded -group_path_count 1000 -corner [$corner name]
68
68
  puts ""
69
69
  puts "%OL_END_REPORT"
70
70
 
@@ -74,7 +74,7 @@ puts "\n========================================================================
74
74
  puts "report_checks -unconstrained"
75
75
  puts "==========================================================================="
76
76
  puts "======================= [$corner name] Corner ===================================\n"
77
- report_checks -unconstrained -fields {slew cap input nets fanout} -format full_clock_expanded -corner [$corner name]
77
+ report_checks -unconstrained -fields {slew cap input net fanout} -format full_clock_expanded -corner [$corner name]
78
78
  puts ""
79
79
 
80
80
 
@@ -82,7 +82,7 @@ puts "\n========================================================================
82
82
  puts "report_checks --slack_max -0.01"
83
83
  puts "============================================================================"
84
84
  puts "======================= [$corner name] Corner ===================================\n"
85
- report_checks -slack_max -0.01 -fields {slew cap input nets fanout} -format full_clock_expanded -corner [$corner name]
85
+ report_checks -slack_max -0.01 -fields {slew cap input net fanout} -format full_clock_expanded -corner [$corner name]
86
86
  puts ""
87
87
 
88
88
  puts "\n==========================================================================="
@@ -260,7 +260,7 @@ if { [info exists ::env(STA_MAX_VIOLATOR_COUNT)] } {
260
260
  set max_violator_count $::env(STA_MAX_VIOLATOR_COUNT)
261
261
  }
262
262
 
263
- set hold_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay min -sort_by_slack -group_count $max_violator_count -slack_max 0]
263
+ set hold_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay min -sort_by_slack -group_path_count $max_violator_count -slack_max 0]
264
264
  foreach path $hold_violating_paths {
265
265
  set start_pin [get_property $path startpoint]
266
266
  set end_pin [get_property $path endpoint]
@@ -279,7 +279,7 @@ foreach path $hold_violating_paths {
279
279
  }
280
280
 
281
281
  set worst_r2r_hold_slack 1e30
282
- set hold_paths [find_timing_paths -unique_paths_to_endpoint -path_delay min -sort_by_slack -group_count $max_violator_count -slack_max $worst_r2r_hold_slack]
282
+ set hold_paths [find_timing_paths -unique_paths_to_endpoint -path_delay min -sort_by_slack -group_path_count $max_violator_count -slack_max $worst_r2r_hold_slack]
283
283
  foreach path $hold_paths {
284
284
  set start_pin [get_property $path startpoint]
285
285
  set end_pin [get_property $path endpoint]
@@ -295,7 +295,7 @@ foreach path $hold_paths {
295
295
  }
296
296
  }
297
297
 
298
- set setup_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_count $max_violator_count -slack_max 0]
298
+ set setup_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_path_count $max_violator_count -slack_max 0]
299
299
  foreach path $setup_violating_paths {
300
300
  set start_pin [get_property $path startpoint]
301
301
  set end_pin [get_property $path endpoint]
@@ -314,7 +314,7 @@ foreach path $setup_violating_paths {
314
314
  }
315
315
 
316
316
  set worst_r2r_setup_slack 1e30
317
- set setup_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_count $max_violator_count -slack_max $worst_r2r_setup_slack]
317
+ set setup_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_path_count $max_violator_count -slack_max $worst_r2r_setup_slack]
318
318
  foreach path $setup_paths {
319
319
  set start_pin [get_property $path startpoint]
320
320
  set end_pin [get_property $path endpoint]
@@ -62,8 +62,7 @@ def json_header(
62
62
  synth_parameters=config["SYNTH_PARAMETERS"] or [],
63
63
  includes=includes,
64
64
  defines=defines,
65
- use_synlig=config["USE_SYNLIG"],
66
- synlig_defer=config["SYNLIG_DEFER"],
65
+ use_slang=config["USE_SLANG"],
67
66
  )
68
67
  d.run_pass(
69
68
  "hierarchy",
@@ -262,8 +262,7 @@ def synthesize(
262
262
  synth_parameters=[],
263
263
  includes=includes,
264
264
  defines=defines,
265
- use_synlig=False,
266
- synlig_defer=False,
265
+ use_slang=False,
267
266
  )
268
267
  elif verilog_files := config.get("VERILOG_FILES"):
269
268
  d.read_verilog_files(
@@ -272,8 +271,7 @@ def synthesize(
272
271
  synth_parameters=config["SYNTH_PARAMETERS"] or [],
273
272
  includes=includes,
274
273
  defines=defines,
275
- use_synlig=config["USE_SYNLIG"],
276
- synlig_defer=config["SYNLIG_DEFER"],
274
+ use_slang=config["USE_SLANG"],
277
275
  )
278
276
  elif vhdl_files := config.get("VHDL_FILES"):
279
277
  d.run_pass("plugin", "-i", "ghdl")
@@ -300,6 +298,8 @@ def synthesize(
300
298
  )
301
299
  except Exception:
302
300
  pass
301
+ if config["SYNTH_NORMALIZE_SINGLE_BIT_VECTORS"]:
302
+ d.run_pass("attrmap", "-remove", "single_bit_vector")
303
303
  d.run_pass("select", "-clear")
304
304
 
305
305
  lib_arguments = []
@@ -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",
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",
@@ -946,7 +950,12 @@ class CellFrequencyTables(OdbpyStep):
946
950
  lib_list = self.toolbox.filter_views(self.config, self.config["LIB"])
947
951
  env_copy["_PNR_LIBS"] = TclStep.value_to_tcl(lib_list)
948
952
  super().run_subprocess(
949
- ["openroad", "-no_splash", "-exit", self.get_buffer_list_script()],
953
+ [
954
+ self.get_openroad_path(),
955
+ "-no_splash",
956
+ "-exit",
957
+ self.get_buffer_list_script(),
958
+ ],
950
959
  env=env_copy,
951
960
  log_to=self.get_buffer_list_file(),
952
961
  )
@@ -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",
@@ -1369,10 +1373,18 @@ class GeneratePDN(OpenROADStep):
1369
1373
  info(f"'FP_PDN_CFG' not explicitly set, setting it to {env['FP_PDN_CFG']}…")
1370
1374
  views_updates, metrics_updates = super().run(state_in, env=env, **kwargs)
1371
1375
 
1376
+ alerts = self.alerts or []
1372
1377
  error_reports = glob(os.path.join(self.step_dir, "*-grid-errors.rpt"))
1373
1378
  for report in error_reports:
1374
1379
  net = os.path.basename(report).split("-", maxsplit=1)[0]
1375
- count = get_psm_error_count(open(report, encoding="utf8"))
1380
+ no_terminals = any(
1381
+ alert.code == "PSM-0025" and alert.message.startswith(net)
1382
+ for alert in alerts
1383
+ )
1384
+ if no_terminals:
1385
+ count = 1
1386
+ else:
1387
+ count = get_psm_error_count(open(report, encoding="utf8"))
1376
1388
  metrics_updates[f"design__power_grid_violation__count__net:{net}"] = count
1377
1389
 
1378
1390
  metric_updates_with_aggregates = aggregate_metrics(
librelane/steps/pyosys.py CHANGED
@@ -122,16 +122,11 @@ verilog_rtl_cfg_vars = [
122
122
  "Key-value pairs to be `chparam`ed in Yosys, in the format `key1=value1`.",
123
123
  ),
124
124
  Variable(
125
- "USE_SYNLIG",
125
+ "USE_SLANG",
126
126
  bool,
127
- "Use the Synlig plugin to process files, which has better SystemVerilog parsing capabilities but may not be compatible with all Yosys commands and attributes.",
128
- default=False,
129
- ),
130
- Variable(
131
- "SYNLIG_DEFER",
132
- bool,
133
- "Uses -defer flag when reading files the Synlig plugin, which may improve performance by reading each file separately, but is experimental.",
127
+ "Use the Slang frontend to process files, which has better SystemVerilog parsing capabilities but is not as battle-tested as the default Yosys friend.",
134
128
  default=False,
129
+ deprecated_names=["USE_SYNLIG"],
135
130
  ),
136
131
  ]
137
132
 
@@ -216,6 +211,10 @@ class PyosysStep(Step):
216
211
  ),
217
212
  ]
218
213
 
214
+ @classmethod
215
+ def get_yosys_path(Self) -> str:
216
+ return os.getenv("_LLN_OVERRIDE_YOSYS", "yosys")
217
+
219
218
  @abstractmethod
220
219
  def get_script_path(self) -> str:
221
220
  pass
@@ -223,7 +222,7 @@ class PyosysStep(Step):
223
222
  def get_command(self, state_in: State) -> List[str]:
224
223
  script_path = self.get_script_path()
225
224
  # HACK: Get Colab working
226
- yosys_bin = "yosys"
225
+ yosys_bin = self.get_yosys_path()
227
226
  if "google.colab" in sys.modules:
228
227
  yosys_bin = shutil.which("yosys") or "yosys"
229
228
  cmd = [yosys_bin, "-y", script_path]
@@ -497,6 +496,12 @@ class SynthesisCommon(VerilogStep):
497
496
  "If true, Verilog-2001 attributes are omitted from output netlists. Some utilities do not support attributes.",
498
497
  default=True,
499
498
  ),
499
+ Variable(
500
+ "SYNTH_NORMALIZE_SINGLE_BIT_VECTORS",
501
+ bool,
502
+ "If true, vectors with the shape [0:0] are converted to normal wires in the netlist. If disabled, even one-width pins will be suffixed [0] in the layout when imported by most PnR tools.",
503
+ default=True,
504
+ ),
500
505
  # Variable(
501
506
  # "SYNTH_SDC_FILE",
502
507
  # Optional[Path],
librelane/steps/yosys.py CHANGED
@@ -19,7 +19,13 @@ from typing import List, Literal, Optional, Set, Tuple
19
19
 
20
20
  from .tclstep import TclStep
21
21
  from .step import ViewsUpdate, MetricsUpdate, Step
22
- from .pyosys import JsonHeader, verilog_rtl_cfg_vars, Synthesis, VHDLSynthesis
22
+ from .pyosys import (
23
+ PyosysStep,
24
+ JsonHeader,
25
+ verilog_rtl_cfg_vars,
26
+ Synthesis,
27
+ VHDLSynthesis,
28
+ )
23
29
 
24
30
  from ..config import Variable, Config
25
31
  from ..state import State, DesignFormat
@@ -210,9 +216,17 @@ class YosysStep(TclStep):
210
216
  ),
211
217
  ]
212
218
 
219
+ @classmethod
220
+ def get_yosys_path(Self) -> str:
221
+ return PyosysStep.get_yosys_path()
222
+
223
+ @abstractmethod
224
+ def get_script_path(self) -> str:
225
+ pass
226
+
213
227
  def get_command(self) -> List[str]:
214
228
  script_path = self.get_script_path()
215
- cmd = ["yosys", "-c", script_path]
229
+ cmd = [self.get_yosys_path(), "-c", script_path]
216
230
  if self.config["YOSYS_LOG_LEVEL"] != "ALL":
217
231
  cmd += ["-Q"]
218
232
  if self.config["YOSYS_LOG_LEVEL"] == "WARNING":
@@ -221,10 +235,6 @@ class YosysStep(TclStep):
221
235
  cmd += ["-qq"]
222
236
  return cmd
223
237
 
224
- @abstractmethod
225
- def get_script_path(self) -> str:
226
- pass
227
-
228
238
  def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
229
239
  power_defines = False
230
240
  if "power_defines" in kwargs:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: librelane
3
- Version: 3.0.0.dev22
3
+ Version: 3.0.0.dev24
4
4
  Summary: An infrastructure for implementing chip design flows
5
5
  Home-page: https://github.com/librelane/librelane
6
6
  License: Apache-2.0
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
- Requires-Dist: ciel (>=0.16.0)
17
+ Requires-Dist: ciel (>=2.0.3,<3)
18
18
  Requires-Dist: click (>=8,<8.2)
19
19
  Requires-Dist: cloup (>=3.0.5,<4)
20
20
  Requires-Dist: deprecated (>=1.2.10,<2)
@@ -25,7 +25,7 @@ Requires-Dist: lxml (>=4.9.0)
25
25
  Requires-Dist: psutil (>=5.9.0)
26
26
  Requires-Dist: pyyaml (>=5,<7)
27
27
  Requires-Dist: rapidfuzz (>=3.9.0,<4)
28
- Requires-Dist: rich (>=12,<14)
28
+ Requires-Dist: rich (>=12,<15)
29
29
  Requires-Dist: semver (>=3.0.2,<4.0.0)
30
30
  Requires-Dist: yamlcore (>=0.0.2,<0.0.3)
31
31
  Project-URL: Documentation, https://librelane.readthedocs.io
@@ -1,5 +1,5 @@
1
1
  librelane/__init__.py,sha256=EMpoZrRmS_wsweKjhyAg52OXCK7HWQ8o8CVrYaX4ub0,1220
2
- librelane/__main__.py,sha256=MMquJ11yCe3X00XiflcCWZKFF1_G0X3CKD3N59J-45E,14551
2
+ librelane/__main__.py,sha256=Zq2h2ZTQqA0T7qpGFELJ1bzVQnv-951nnhJ0-9WzNaM,14541
3
3
  librelane/__version__.py,sha256=dbE4stCACDmIoxgKksesAkTa-_hi5dW6nPLWw9Pfq3Q,1486
4
4
  librelane/common/__init__.py,sha256=WTSw8kJaR6JJsi1FLUbKAekE7qmXLTYEeoInLRXQdEc,1529
5
5
  librelane/common/cli.py,sha256=xi48GBGHRsYrLGwx40ARwpykHx7GnuHbJjHxjOwtZ5Y,2349
@@ -17,13 +17,13 @@ librelane/common/toolbox.py,sha256=ijR__rVqQ_nJtfm34H-VdSCIeArKns7lVAc1TcTUSsQ,2
17
17
  librelane/common/tpe.py,sha256=Txj0fVscXSDJTYmEKZ2ESFHOeqrhHnaPPiwWBgyx4g8,1285
18
18
  librelane/common/types.py,sha256=oclAQkeluz_iopI_28clHzxvac7gN5moT8Rzipy5mgM,3468
19
19
  librelane/config/__init__.py,sha256=lbJmD5CbrrrnaNdIUWqFIK488ea0uyej3iExh-9mkgE,1107
20
- librelane/config/__main__.py,sha256=6KSXxM4qNE2yJhizUsF1kdMsY1kY7hLHoPoz50POsS8,4532
20
+ librelane/config/__main__.py,sha256=Uhma2IQdvDTJiZs9ZIQA7r9zWSq7fZR-19P9UJWQclA,4476
21
21
  librelane/config/config.py,sha256=bAxB0qpw95YoLGmMjvxAwrX1hcpHRvNhH7wjQdyW-DE,35031
22
22
  librelane/config/flow.py,sha256=RS8uspcrepl8GT5SsWrBQ-kmssO4c15_lrc2nBPVK5M,16482
23
23
  librelane/config/pdk_compat.py,sha256=ofqYuD-MgTcfvPVXpGJo8H1GKzCvN6sxHsK_OqCVXa8,12870
24
24
  librelane/config/preprocessor.py,sha256=ATi29SHz0_OBq1IqUkGxvhHUDKB5z5jO0KqvoQXg8R8,14913
25
- librelane/config/removals.py,sha256=lJ0xpkCqnZAdA_ug4yq0NDjRBFuw4XsdORwymbEVGyQ,2907
26
- librelane/config/variable.py,sha256=5TLqeyLlGciuxzce5_vTUMy1MxZsI2XG2B0o2spGV30,26242
25
+ librelane/config/removals.py,sha256=vxqTuRTJ0jt2TX4KmFZCZPTwghDFkCVjIhF2iReHwJA,2958
26
+ librelane/config/variable.py,sha256=v92bVwy11LgS53gYhU9DBwOUABc2XMGqEglqTORpPfc,26269
27
27
  librelane/container.py,sha256=3KHxs3dUSVUZVYsS6fsA7dD3Q4QEQEzRxgXZZh9dzi0,7554
28
28
  librelane/env_info.py,sha256=vAE9AZ_vDFLt7Srtg4ZywPzE6vgVhCrIvg8PP25-BJ8,10460
29
29
  librelane/examples/spm/config.yaml,sha256=YKBm0lsY3AJZNcxAh1sQ1QMmJeVCpOpil6dw_RgQh4c,633
@@ -89,14 +89,14 @@ librelane/scripts/odbpy/eco_buffer.py,sha256=QOL2J0UJQiVvuGFbpdyAj-RRsPfEL-rT_qr
89
89
  librelane/scripts/odbpy/eco_diode.py,sha256=2LN7fHh9uO9JP3PYIxIwUiP1lyeqdTNF2ADTcY_Bu-g,4281
90
90
  librelane/scripts/odbpy/filter_unannotated.py,sha256=Gvcaj_WNr6TPiHk-36nkMu4betNHZo1g2lD3UcA9hDQ,2950
91
91
  librelane/scripts/odbpy/io_place.py,sha256=LSJIJQDLSOpENyQOg_kVTIbh1AbYLiHIXx0siduo-lg,15589
92
- librelane/scripts/odbpy/ioplace_parser/__init__.py,sha256=TMKTIWwGJfdSr7dJcsoisUuKlbTKJdHV6-0kB77v2P8,887
93
- librelane/scripts/odbpy/ioplace_parser/parse.py,sha256=LDncc8r1nDmcTCVtxqBu7xswiesVX6-snYiIKFB_kxs,5594
92
+ librelane/scripts/odbpy/ioplace_parser/__init__.py,sha256=_xCDqam3PxWO-uhTZ6afdn3dpuu4XlX2T_RaOn7QqJQ,877
93
+ librelane/scripts/odbpy/ioplace_parser/parse.py,sha256=L2GXzNA-gkjyySZcTWXrRRP8rllabE5pGap9dtiFfOo,5584
94
94
  librelane/scripts/odbpy/label_macro_pins.py,sha256=n3o9-_g6HkVP8k49yNnCkQJms9f_ykCE0Rye7bVFtIk,8620
95
95
  librelane/scripts/odbpy/lefutil.py,sha256=XhfWSGHdn96yZWYQAPisgJM0iuY3xw4SW7jmMTzbpZs,3064
96
96
  librelane/scripts/odbpy/placers.py,sha256=mgy_-GYeLDPMG41YAopMTtJyCHP6ucJRk7cJzI9PLRQ,4572
97
97
  librelane/scripts/odbpy/power_utils.py,sha256=al12uMiv8G0yQZOPKXNHYQ1dm2KGlu9xigSuYLEAo_A,14627
98
98
  librelane/scripts/odbpy/random_place.py,sha256=TEsV4LtXQTP8OJvnBh09Siu9fKkwG9UpIkCkQpdXAgU,1649
99
- librelane/scripts/odbpy/reader.py,sha256=5-hpG3TgmKwJtnbEDQoAPejeDx1QyRBRbIMULMkBesM,8539
99
+ librelane/scripts/odbpy/reader.py,sha256=XHHZr3e9Esz4T5j35vYXHsURyRepUEb3CmNG46Uec8I,8541
100
100
  librelane/scripts/odbpy/remove_buffers.py,sha256=f-kGZIPnMtu4gnl2r2CDkng8U8vUMJKJWNV_akOpc38,5460
101
101
  librelane/scripts/odbpy/snap_to_grid.py,sha256=lULRWlcYXvrTBUpemUPlpO2dBnbFeriuG-DlI4KnViE,1743
102
102
  librelane/scripts/odbpy/wire_lengths.py,sha256=pSPhVnLlvcvmgEh89G8nu8DRaZVP66r-4ieVoV3zrm4,2737
@@ -107,10 +107,10 @@ librelane/scripts/openroad/buffer_list.tcl,sha256=sXygy1KRSUS4dZi1UOpBkGGOuXRVLM
107
107
  librelane/scripts/openroad/common/dpl.tcl,sha256=T_rzoZy8i7S9C92TOmiN79w0MCfudafEhkXcHmB1BAM,920
108
108
  librelane/scripts/openroad/common/dpl_cell_pad.tcl,sha256=KWVuj8u1-y3ZUiQr48TAsFv1GSzOCVnAjdqfBjtoQxQ,1066
109
109
  librelane/scripts/openroad/common/grt.tcl,sha256=2qDLSj8lKKEJHH9V9npiSMXQdsIsIHE0DVmbVRStbk4,1132
110
- librelane/scripts/openroad/common/io.tcl,sha256=Osl_8qvBxfXcHlWBsYE9IC0Oisu_SjG1puiyY4ULmyw,22207
111
- librelane/scripts/openroad/common/pdn_cfg.tcl,sha256=KnQAxzlL_261Kp4M02cQ6usZHIRNBj56SAZNn1CqrZc,4552
110
+ librelane/scripts/openroad/common/io.tcl,sha256=1DHtdskRn1yc-jywvUFClHbrPFypKUXdZqOXXJsfouQ,22523
111
+ librelane/scripts/openroad/common/pdn_cfg.tcl,sha256=6Uodl1pO6fckiQnMFbTo3fghrflqXp-MQnQ9ZT5gR64,4555
112
112
  librelane/scripts/openroad/common/resizer.tcl,sha256=OhjpVxw_8IOx5Bmh2_gh_EIHxKaX84NS37Of9Rlchpw,2255
113
- librelane/scripts/openroad/common/set_global_connections.tcl,sha256=M-3OdAbGQXx7BrTyRIuh9c8m0ajnaWgiqrcmuZg68nk,2920
113
+ librelane/scripts/openroad/common/set_global_connections.tcl,sha256=jxafLD-2SLciJYeueobrlJYetnfAfK0P5uMLwhaTQco,2927
114
114
  librelane/scripts/openroad/common/set_layer_adjustments.tcl,sha256=xqAIDXsTa1_JsGmKXf6eG2Rni2EZSilSsHfJAhCl1xY,1037
115
115
  librelane/scripts/openroad/common/set_power_nets.tcl,sha256=_2n2AKl8UTh9-KeUOOwKaeyRw_4zi1Ifgh8oa9HIWc4,1253
116
116
  librelane/scripts/openroad/common/set_rc.tcl,sha256=oJJCQG9RvAltgB5KTFsJcCzVvwUIkXeI7KJehCEWex0,7224
@@ -118,10 +118,10 @@ librelane/scripts/openroad/common/set_routing_layers.tcl,sha256=fCQsIjcFRsHJPFQv
118
118
  librelane/scripts/openroad/cts.tcl,sha256=703n6gGekpOXbRhr390DSBIo4h7qNlHUd-Amai4pGgk,3888
119
119
  librelane/scripts/openroad/cut_rows.tcl,sha256=8RN4_muN1FXkXCU1VGVI_nox3BQNVGVNlQn_21HRCKM,1403
120
120
  librelane/scripts/openroad/dpl.tcl,sha256=U5iTPBf7H4w3cmCM8-yTjLTVr8npwc5G7hVuszljCVc,777
121
- librelane/scripts/openroad/drt.tcl,sha256=CtPVi51t3EEDUB3-UBBrE6faP6bf56TVvJHSsjcwWFw,3108
121
+ librelane/scripts/openroad/drt.tcl,sha256=xIBTKJ1HwcvsVCLZW5nMkK6JV7wIskSw9CTHNEqOXcE,3138
122
122
  librelane/scripts/openroad/dump_rc.tcl,sha256=R0EaQqpu23TABO9b5LwwpuafdcCOvaN7jpH6PiLG2Wg,4365
123
123
  librelane/scripts/openroad/fill.tcl,sha256=djxPglVtei5Wfi5cStdnowVNysXZ331R0rWT5tT1lVk,976
124
- librelane/scripts/openroad/floorplan.tcl,sha256=Jpv7GL7hP8g4VCHYx0pLl11hfGJBx26WoAvEKYMYGvI,5487
124
+ librelane/scripts/openroad/floorplan.tcl,sha256=1l8GMyJaUIbvI7dr6OIpZ3NM5xQEb-MFgRRfapwVvjE,5738
125
125
  librelane/scripts/openroad/gpl.tcl,sha256=WzxlyikUf70Q1FgaE6sIVvquYPZ8RU02_te1VBsAd5U,2614
126
126
  librelane/scripts/openroad/grt.tcl,sha256=r_73hbvc4wMi2EFoPbGTh29Lh5ATT4vVwKjxyPIOFcM,1022
127
127
  librelane/scripts/openroad/gui.tcl,sha256=BhKTcYEo-SajnYtdzXqpzjYbczy0qZ-OvEFlHMjPtlU,1255
@@ -134,19 +134,19 @@ librelane/scripts/openroad/repair_design.tcl,sha256=mSQKIT-uac2gJFia_xMNQtHJKD--
134
134
  librelane/scripts/openroad/repair_design_postgrt.tcl,sha256=sEXdFfH2le-q0ggcsWGgCR-GCFyzPdxk4P3RZyWCnpI,1902
135
135
  librelane/scripts/openroad/rsz_timing_postcts.tcl,sha256=ztDJ__R7f3eK7-xAg9SklGXqL5F1jydGPQDH7X5twNE,2553
136
136
  librelane/scripts/openroad/rsz_timing_postgrt.tcl,sha256=F6ex9Ke85YzS4z9rf8SpqCKjMyzuiQEhYYSJfkN93sM,2699
137
- librelane/scripts/openroad/sta/check_macro_instances.tcl,sha256=RYmQbLySaKekWGWLit1sCvTx6vhtwoqQZ_YhAagg_2g,1776
138
- librelane/scripts/openroad/sta/corner.tcl,sha256=Vt_Qg60GddXs6HUBcgMu5iPE_v93mbH0L-sqVqI7Z9A,15209
137
+ librelane/scripts/openroad/sta/check_macro_instances.tcl,sha256=j8DlW1wkVk5bLbG7R4LL_-YcjetxmJKijXDD_q2fpqs,1797
138
+ librelane/scripts/openroad/sta/corner.tcl,sha256=0YAzHFGbs4zRsB5E7e8zdzFyLuzrpV1w_S2BgrLfqak,15235
139
139
  librelane/scripts/openroad/tapcell.tcl,sha256=4Ouy5U-_ct5Cfy3vuLQudWL0c1xWF_auLsr9rYh6dP4,1177
140
140
  librelane/scripts/openroad/ungpl.tcl,sha256=vhHxou1W3VROwJePoQzmWn0h0d5lQrrt1vofyt-Woek,761
141
141
  librelane/scripts/openroad/write_views.tcl,sha256=-MxTJsB4EF7l5trDaZe-VBFjhfzqRt8F5_DZrADTs0U,892
142
142
  librelane/scripts/pyosys/construct_abc_script.py,sha256=3CCDz5ZTEPpWLco-OvikTmn361-BNitqjQE_-5zHm14,6733
143
- librelane/scripts/pyosys/json_header.py,sha256=2_oBI0HE6BgLYOJUVUPv-Lvz97csLndWLE6q5A8zgYw,2362
144
- librelane/scripts/pyosys/synthesize.py,sha256=4SztMSmcUFAoxahg_Z_oerGb3BMbwecmKRJ_WWGL9jw,16879
145
- librelane/scripts/pyosys/ys_common.py,sha256=mOni8WmKMNuLWsLRNcE15rcqCxGR1kf-9ckvIx-EzHY,4432
143
+ librelane/scripts/pyosys/json_header.py,sha256=C1BmKFRbwMknXV_RVp5QGbAxCwU6ElE6UIGRZceHQpI,2315
144
+ librelane/scripts/pyosys/synthesize.py,sha256=2NZWdtskSRGUGghYLkw-LGdEH_IL9Vfl3NUD2GR3Kdk,16910
145
+ librelane/scripts/pyosys/ys_common.py,sha256=t5LLEYoy4cfCIeEaAo8Nr51rXtlI8ZPe1h_kSbrky5M,3891
146
146
  librelane/scripts/tclsh/hello.tcl,sha256=kkR3akY7QnGHYXsQODYwLkMkUEOgWcNFtzaMTTEV2bY,34
147
147
  librelane/state/__init__.py,sha256=DZ_RyKMr2oj4p5d32u8MmDKfCxR7OEdDw-1HWKTpatA,949
148
148
  librelane/state/__main__.py,sha256=Ici4Ejg1ICUZNSYZRguC3BfEk_wFxsmE0ag0Vv8iY1I,1679
149
- librelane/state/design_format.py,sha256=kOLMn2pqTO8NtTypSvLPwuCSa8Zw5hGKN8UORvV2HHg,6328
149
+ librelane/state/design_format.py,sha256=75-XXzCfk5HUAJQAcdpwiHYkweeR9NwaXKtubCV0dqg,6461
150
150
  librelane/state/state.py,sha256=3CdihPR6lryQMt8ihSef0O2F8-qaqy1w7V0wiwie3nk,11710
151
151
  librelane/steps/__init__.py,sha256=j3JYrdnWM74dYuEvE931oSrQI7FUz-hKWr8Mts8C0wg,1668
152
152
  librelane/steps/__main__.py,sha256=GviXtDLISKJCufKxK3oFPOSMF1GyShZbG5RXpVCYFkk,13376
@@ -157,15 +157,15 @@ librelane/steps/klayout.py,sha256=EFtzu53bWm-Bg_xEovdR7fc1GbWTwqkcivtr1rivHWU,16
157
157
  librelane/steps/magic.py,sha256=Xtsy1KWu8dcNq3pRlqM9WRRxtwbCQJq24IyxC0W8D2o,20254
158
158
  librelane/steps/misc.py,sha256=8ubCvFeFEspXrgnzNWINY5-TXTyalNtlvcX8TSw0qdg,5685
159
159
  librelane/steps/netgen.py,sha256=R9sDWv-9wKMdi2rkuLQdOc4uLlbYhXcKKd6WsZsnLt0,8953
160
- librelane/steps/odb.py,sha256=rEvlmZmMxeAh5bg_xBCiyOpnaqjvZOOmQQeEWDU6j-0,39144
161
- librelane/steps/openroad.py,sha256=LDXVqp9jr9KxhD4oQxjXtijH9JIiaDC7nxdSJvoqKTw,99726
160
+ librelane/steps/odb.py,sha256=9ilEnb8w--T84Eh51cB_sz5fwa-UWa7d7p0Di5rv3BA,39371
161
+ librelane/steps/openroad.py,sha256=YQ_vMfPrTgz843Rhq9MR38sZ5C_-YuFO4Z73QOkTAfA,100144
162
162
  librelane/steps/openroad_alerts.py,sha256=IJyB4piBDCKXhkJswHGMYCRDwbdQsR0GZlrGGDhmW6Q,3364
163
- librelane/steps/pyosys.py,sha256=ASNuA_V-cCEka4I5FX4-2nQ0r3KgDXbxbNrnXpzxll4,23099
163
+ librelane/steps/pyosys.py,sha256=LY7qqxkhjfoyBBR7vdkm7ylabbxMJDwIoYm7mAUbLVY,23348
164
164
  librelane/steps/step.py,sha256=T5z0Nm5z-fq_qj3BIwchnfUobmxX67cEmZ-5dUYT76s,55163
165
165
  librelane/steps/tclstep.py,sha256=YwyiSXAjRIflH2vzYvTzYfN4FyAI8Td9B_CKLkBj08o,10084
166
166
  librelane/steps/verilator.py,sha256=MWx2TpLqYyea9_jSeLG9c2S5ujvYERQZRFNaMhfHxZE,7916
167
- librelane/steps/yosys.py,sha256=LYXd5ntLbnMPEFfJiMcUumgmaqw9ZTr14Ss5Dw4fyyc,12545
168
- librelane-3.0.0.dev22.dist-info/METADATA,sha256=dI4apslJIq4I3W0jfUaH16R--im4PGYtaJ46n0N8nd4,6559
169
- librelane-3.0.0.dev22.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
170
- librelane-3.0.0.dev22.dist-info/entry_points.txt,sha256=GTBvXykNMMFsNKiJFgtEw7P1wb_VZIqVM35EFSpyZQE,263
171
- librelane-3.0.0.dev22.dist-info/RECORD,,
167
+ librelane/steps/yosys.py,sha256=uC72fb1yFXyIxrtcRu5DxxR3hadG19SlGh668yjhWHc,12694
168
+ librelane-3.0.0.dev24.dist-info/METADATA,sha256=maVhK_OcJ7zHWMQsUUmlwqT4bID895Jv6Sx3FpZnzm8,6561
169
+ librelane-3.0.0.dev24.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
170
+ librelane-3.0.0.dev24.dist-info/entry_points.txt,sha256=GTBvXykNMMFsNKiJFgtEw7P1wb_VZIqVM35EFSpyZQE,263
171
+ librelane-3.0.0.dev24.dist-info/RECORD,,