librelane 3.0.0.dev52__tar.gz → 3.0.0rc1__tar.gz

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 (176) hide show
  1. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/PKG-INFO +13 -1
  2. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/Readme.md +12 -0
  3. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/toolbox.py +3 -1
  4. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/config.py +0 -7
  5. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/preprocessor.py +3 -28
  6. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/config.yaml +1 -1
  7. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/classic.py +1 -0
  8. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/pdk_hashes.yaml +1 -1
  9. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/render.py +74 -8
  10. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/common/read.tcl +8 -0
  11. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/def/mag_gds.tcl +3 -2
  12. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/extract_spice.tcl +5 -1
  13. librelane-3.0.0rc1/librelane/scripts/magic/spice_rcx.tcl +72 -0
  14. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/netgen/setup.tcl +11 -0
  15. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/io.tcl +46 -10
  16. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/set_rc.tcl +12 -14
  17. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/cts.tcl +1 -0
  18. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/drt.tcl +41 -1
  19. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/dump_rc.tcl +6 -2
  20. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/grt.tcl +0 -5
  21. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/sta/corner.tcl +61 -50
  22. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/state/design_format.py +18 -0
  23. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/__main__.py +2 -1
  24. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/klayout.py +63 -3
  25. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/magic.py +71 -0
  26. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/netgen.py +5 -0
  27. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/openroad.py +44 -2
  28. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/step.py +2 -4
  29. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/pyproject.toml +1 -1
  30. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/__init__.py +0 -0
  31. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/__main__.py +0 -0
  32. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/__version__.py +0 -0
  33. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/__init__.py +0 -0
  34. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/cli.py +0 -0
  35. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/drc.py +0 -0
  36. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/generic_dict.py +0 -0
  37. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/metrics/__init__.py +0 -0
  38. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/metrics/__main__.py +0 -0
  39. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/metrics/library.py +0 -0
  40. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/metrics/metric.py +0 -0
  41. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/metrics/util.py +0 -0
  42. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/misc.py +0 -0
  43. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/ring_buffer.py +0 -0
  44. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/tcl.py +0 -0
  45. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/tpe.py +0 -0
  46. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/common/types.py +0 -0
  47. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/__init__.py +0 -0
  48. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/__main__.py +0 -0
  49. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/flow.py +0 -0
  50. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/pdk_compat.py +0 -0
  51. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/removals.py +0 -0
  52. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/config/variable.py +0 -0
  53. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/container.py +0 -0
  54. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/env_info.py +0 -0
  55. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/hold_eco_demo/config.yaml +0 -0
  56. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/hold_eco_demo/demo.v +0 -0
  57. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/pin_order.cfg +0 -0
  58. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/src/impl.sdc +0 -0
  59. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/src/signoff.sdc +0 -0
  60. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/src/spm.v +0 -0
  61. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm/verify/spm_tb.v +0 -0
  62. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/SPM_example.v +0 -0
  63. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +0 -0
  64. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/config-tut.json +0 -0
  65. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/config.json +0 -0
  66. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/defines.v +0 -0
  67. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/template.def +0 -0
  68. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +0 -0
  69. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/__init__.py +0 -0
  70. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/builtins.py +0 -0
  71. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/chip.py +0 -0
  72. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/cli.py +0 -0
  73. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/flow.py +0 -0
  74. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/misc.py +0 -0
  75. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/optimizing.py +0 -0
  76. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/sequential.py +0 -0
  77. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/flows/synth_explore.py +0 -0
  78. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/help/__main__.py +0 -0
  79. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/logging/__init__.py +0 -0
  80. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/logging/logger.py +0 -0
  81. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/plugins.py +0 -0
  82. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/py.typed +0 -0
  83. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/base.sdc +0 -0
  84. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/Readme.md +0 -0
  85. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/open_design.py +0 -0
  86. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/stream_out.py +0 -0
  87. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/xml_drc_report_to_json.py +0 -0
  88. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/klayout/xor.drc +0 -0
  89. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/Readme.md +0 -0
  90. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/def/antenna_check.tcl +0 -0
  91. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/def/mag.tcl +0 -0
  92. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/drc.tcl +0 -0
  93. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/gds/drc_batch.tcl +0 -0
  94. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/gds/erase_box.tcl +0 -0
  95. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/gds/extras_mag.tcl +0 -0
  96. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/gds/mag_with_pointers.tcl +0 -0
  97. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/get_bbox.tcl +0 -0
  98. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/lef/extras_maglef.tcl +0 -0
  99. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/lef/maglef.tcl +0 -0
  100. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/lef.tcl +0 -0
  101. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/open.tcl +0 -0
  102. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/magic/wrapper.tcl +0 -0
  103. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/apply_def_template.py +0 -0
  104. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/cell_frequency.py +0 -0
  105. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/check_antenna_properties.py +0 -0
  106. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/contextualize.py +0 -0
  107. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/defutil.py +0 -0
  108. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/diodes.py +0 -0
  109. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/disconnected_pins.py +0 -0
  110. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/eco_buffer.py +0 -0
  111. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/eco_diode.py +0 -0
  112. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/filter_unannotated.py +0 -0
  113. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/io_place.py +0 -0
  114. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/ioplace_parser/__init__.py +0 -0
  115. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/ioplace_parser/parse.py +0 -0
  116. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/label_macro_pins.py +0 -0
  117. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/lefutil.py +0 -0
  118. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/placers.py +0 -0
  119. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/power_utils.py +0 -0
  120. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/random_place.py +0 -0
  121. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/reader.py +0 -0
  122. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/remove_buffers.py +0 -0
  123. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/snap_to_grid.py +0 -0
  124. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/odbpy/wire_lengths.py +0 -0
  125. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/antenna_check.tcl +0 -0
  126. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/antenna_repair.tcl +0 -0
  127. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/buffer_list.tcl +0 -0
  128. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/dpl.tcl +0 -0
  129. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/dpl_cell_pad.tcl +0 -0
  130. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/grt.tcl +0 -0
  131. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/pad_cfg.tcl +0 -0
  132. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/pdn_cfg.tcl +0 -0
  133. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/resizer.tcl +0 -0
  134. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/set_global_connections.tcl +0 -0
  135. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/set_layer_adjustments.tcl +0 -0
  136. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/set_power_nets.tcl +0 -0
  137. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/common/set_routing_layers.tcl +0 -0
  138. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/cut_rows.tcl +0 -0
  139. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/dpl.tcl +0 -0
  140. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/fill.tcl +0 -0
  141. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/floorplan.tcl +0 -0
  142. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/gpl.tcl +0 -0
  143. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/gui.tcl +0 -0
  144. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/insert_buffer.tcl +0 -0
  145. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/ioplacer.tcl +0 -0
  146. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/irdrop.tcl +0 -0
  147. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/pad.tcl +0 -0
  148. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/pdn.tcl +0 -0
  149. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/rcx.tcl +0 -0
  150. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/repair_design.tcl +0 -0
  151. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/repair_design_postgrt.tcl +0 -0
  152. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/rsz_timing_postcts.tcl +0 -0
  153. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/rsz_timing_postgrt.tcl +0 -0
  154. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/sta/check_macro_instances.tcl +0 -0
  155. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/tapcell.tcl +0 -0
  156. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/ungpl.tcl +0 -0
  157. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/write_cdl.tcl +0 -0
  158. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/openroad/write_views.tcl +0 -0
  159. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/pyosys/construct_abc_script.py +0 -0
  160. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/pyosys/json_header.py +0 -0
  161. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/pyosys/synthesize.py +0 -0
  162. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/pyosys/ys_common.py +0 -0
  163. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/scripts/tclsh/hello.tcl +0 -0
  164. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/state/__init__.py +0 -0
  165. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/state/__main__.py +0 -0
  166. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/state/state.py +0 -0
  167. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/__init__.py +0 -0
  168. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/checker.py +0 -0
  169. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/common_variables.py +0 -0
  170. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/misc.py +0 -0
  171. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/odb.py +0 -0
  172. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/openroad_alerts.py +0 -0
  173. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/pyosys.py +0 -0
  174. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/tclstep.py +0 -0
  175. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/verilator.py +0 -0
  176. {librelane-3.0.0.dev52 → librelane-3.0.0rc1}/librelane/steps/yosys.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: librelane
3
- Version: 3.0.0.dev52
3
+ Version: 3.0.0rc1
4
4
  Summary: An infrastructure for implementing chip design flows
5
5
  License-Expression: Apache-2.0
6
6
  Maintainer: Mohamed Gaber
@@ -139,6 +139,18 @@ If you use LibreLane in your research, please cite the following paper.
139
139
  doi={}}
140
140
  ```
141
141
 
142
+ ## Contributing
143
+ Thank you in advance for considering a contribution to LibreLane!
144
+
145
+ Please be sure to read our [contributor's guide](https://librelane.readthedocs.io/en/stable/contributors/index.html).
146
+
147
+ > [!TIP]
148
+ >
149
+ > The `main` branch is the stable branch for LibreLane, i.e., this branch is
150
+ > updated less frequently and only accepts bugfixes.
151
+ >
152
+ > Feature contributions should be directed towards the `dev` branch.
153
+
142
154
  ## License and Legal Info
143
155
 
144
156
  LibreLane is a trademark of the [FOSSi Foundation](https://fossi-foundation.org).
@@ -105,6 +105,18 @@ If you use LibreLane in your research, please cite the following paper.
105
105
  doi={}}
106
106
  ```
107
107
 
108
+ ## Contributing
109
+ Thank you in advance for considering a contribution to LibreLane!
110
+
111
+ Please be sure to read our [contributor's guide](https://librelane.readthedocs.io/en/stable/contributors/index.html).
112
+
113
+ > [!TIP]
114
+ >
115
+ > The `main` branch is the stable branch for LibreLane, i.e., this branch is
116
+ > updated less frequently and only accepts bugfixes.
117
+ >
118
+ > Feature contributions should be directed towards the `dev` branch.
119
+
108
120
  ## License and Legal Info
109
121
 
110
122
  LibreLane is a trademark of the [FOSSi Foundation](https://fossi-foundation.org).
@@ -351,7 +351,9 @@ class Toolbox(object):
351
351
  with tempfile.TemporaryDirectory(prefix="librelane_klayout_tmp_") as d:
352
352
  render_step = KLayout.Render(config, state_in, _config_quiet=True)
353
353
  render_step.start(self, d)
354
- return open(os.path.join(d, "out.png"), "rb").read()
354
+ return open(
355
+ os.path.join(d, f"{config['DESIGN_NAME']}.png"), "rb"
356
+ ).read()
355
357
  except InvalidConfig:
356
358
  warn("PDK is incompatible with KLayout. Unable to generate preview.")
357
359
  return None
@@ -707,12 +707,6 @@ class Config(GenericImmutableDict[str, Any]):
707
707
  if pdk_root is not None:
708
708
  pdkpath = os.path.join(pdk_root, mutable["PDK"])
709
709
 
710
- readable_paths = [
711
- os.path.abspath(design_dir),
712
- ]
713
- if pdkpath != "":
714
- readable_paths.append(os.path.abspath(pdkpath))
715
-
716
710
  mutable.update(
717
711
  preprocess_dict(
718
712
  raw,
@@ -721,7 +715,6 @@ class Config(GenericImmutableDict[str, Any]):
721
715
  scl=mutable[SpecialKeys.scl],
722
716
  pad=mutable.get(SpecialKeys.pad, None),
723
717
  design_dir=design_dir,
724
- readable_paths=readable_paths,
725
718
  )
726
719
  )
727
720
 
@@ -214,7 +214,6 @@ ref_rx = re.compile(r"^\$([A-Za-z_][A-Za-z0-9_\.\[\]]*)")
214
214
  def process_string(
215
215
  value: str,
216
216
  symbols: Mapping[str, Any],
217
- readable_paths: Optional[List[str]] = None,
218
217
  ) -> Valid:
219
218
  global ref_rx
220
219
  EXPR_PREFIX = "expr::"
@@ -271,22 +270,12 @@ def process_string(
271
270
 
272
271
  ## If we're refg, all returns beyond this point must be of type
273
272
  ## List[str]
274
-
275
- # Glob only if readable_paths isn't null
276
- if readable_paths is None:
277
- return [target]
278
-
279
273
  final_abspath = os.path.abspath(concatenated)
280
274
 
281
275
  # Glob only if it doesn't already resolve to a valid file
282
276
  if os.path.exists(final_abspath):
283
277
  return [final_abspath]
284
278
 
285
- in_exposed = [final_abspath.startswith(p) for p in readable_paths]
286
- if True not in in_exposed:
287
- raise PermissionError(
288
- f"'{concatenated}' is not located any path readable to LibreLane"
289
- )
290
279
  files = sorted(glob.glob(final_abspath))
291
280
  files_escaped = [file.replace("$", r"\$") for file in files]
292
281
  files_escaped.sort()
@@ -307,7 +296,6 @@ def process_list_recursive(
307
296
  input: Sequence[Any],
308
297
  ref: List[Any],
309
298
  symbols: Dict[str, Any],
310
- readable_paths: Optional[List[str]],
311
299
  *,
312
300
  key_path: str = "",
313
301
  ):
@@ -320,7 +308,6 @@ def process_list_recursive(
320
308
  value,
321
309
  processed,
322
310
  symbols,
323
- readable_paths,
324
311
  key_path=current_key_path,
325
312
  )
326
313
  elif isinstance(value, Sequence) and not is_string(value):
@@ -329,11 +316,10 @@ def process_list_recursive(
329
316
  value,
330
317
  processed,
331
318
  symbols,
332
- readable_paths,
333
319
  key_path=current_key_path,
334
320
  )
335
321
  elif is_string(value):
336
- processed = process_string(value, symbols, readable_paths)
322
+ processed = process_string(value, symbols)
337
323
  else:
338
324
  processed = value
339
325
 
@@ -346,7 +332,6 @@ def process_dict_recursive(
346
332
  input: Mapping[str, Any],
347
333
  ref: Dict[str, Any],
348
334
  symbols: Dict[str, Any],
349
- readable_paths: Optional[List[str]],
350
335
  *,
351
336
  key_path: str = "",
352
337
  ):
@@ -363,7 +348,6 @@ def process_dict_recursive(
363
348
  value,
364
349
  ref,
365
350
  symbols,
366
- readable_paths,
367
351
  key_path=key_path,
368
352
  )
369
353
  elif key.startswith(SCL_PREFIX):
@@ -375,7 +359,6 @@ def process_dict_recursive(
375
359
  value,
376
360
  ref,
377
361
  symbols,
378
- readable_paths,
379
362
  key_path=key_path,
380
363
  )
381
364
  else:
@@ -384,7 +367,6 @@ def process_dict_recursive(
384
367
  value,
385
368
  processed,
386
369
  symbols,
387
- readable_paths,
388
370
  key_path=current_key_path,
389
371
  )
390
372
 
@@ -394,11 +376,10 @@ def process_dict_recursive(
394
376
  value,
395
377
  processed,
396
378
  symbols,
397
- readable_paths,
398
379
  key_path=current_key_path,
399
380
  )
400
381
  elif is_string(value):
401
- processed = process_string(value, symbols, readable_paths)
382
+ processed = process_string(value, symbols)
402
383
  else:
403
384
  processed = value
404
385
 
@@ -410,11 +391,10 @@ def process_dict_recursive(
410
391
  def process_config_dict(
411
392
  config_in: Mapping[str, Any],
412
393
  exposed_variables: Dict[str, Any],
413
- readable_paths: Optional[List[str]],
414
394
  ) -> Dict[str, Any]:
415
395
  state = dict(exposed_variables)
416
396
  symbols = dict(exposed_variables)
417
- process_dict_recursive(config_in, state, symbols, readable_paths)
397
+ process_dict_recursive(config_in, state, symbols)
418
398
  return state
419
399
 
420
400
 
@@ -434,11 +414,7 @@ def preprocess_dict(
434
414
  pdkpath: Optional[str] = None,
435
415
  scl: Optional[str] = None,
436
416
  pad: Optional[str] = None,
437
- readable_paths: Optional[List[str]] = None,
438
417
  ) -> Dict[str, Any]:
439
- """
440
- If readable_paths are set to None, refg:: will not work
441
- """
442
418
  if None in (pdk, pdkpath, scl):
443
419
  if only_extract_process_info:
444
420
  pdkpath = ""
@@ -460,7 +436,6 @@ def preprocess_dict(
460
436
  preprocessed = process_config_dict(
461
437
  config_dict,
462
438
  base_vars,
463
- readable_paths,
464
439
  )
465
440
  if only_extract_process_info:
466
441
  preprocessed = extract_process_vars(preprocessed)
@@ -28,6 +28,6 @@ pdk::sky130*:
28
28
  MAX_FANOUT_CONSTRAINT: 5
29
29
  pdk::gf180mcu*:
30
30
  CLOCK_PERIOD: 24.0
31
- FP_CORE_UTIL: 40
31
+ FP_CORE_UTIL: 38
32
32
  MAX_FANOUT_CONSTRAINT: 4
33
33
  PL_TARGET_DENSITY: 0.5
@@ -99,6 +99,7 @@ class Classic(SequentialFlow):
99
99
  OpenROAD.IRDropReport,
100
100
  Magic.StreamOut,
101
101
  KLayout.StreamOut,
102
+ KLayout.Render,
102
103
  Magic.WriteLEF,
103
104
  Odb.CheckDesignAntennaProperties,
104
105
  KLayout.XOR,
@@ -1,3 +1,3 @@
1
1
  sky130: 8afc8346a57fe1ab7934ba5a6056ea8b43078e71
2
- gf180mcu: 8afc8346a57fe1ab7934ba5a6056ea8b43078e71
2
+ gf180mcu: 54435919abffb937387ec956209f9cf5fd2dfbee
3
3
  ihp-sg13g2: c4b8b4e5e7a05f375cca3815d51b3a37721fbf5c
@@ -1,4 +1,8 @@
1
1
  #!/usr/bin/env python3
2
+ # Copyright 2025 LibreLane Contributors
3
+ #
4
+ # Adapted from OpenLane
5
+ #
2
6
  # Copyright (c) 2021-2022 Efabless Corporation
3
7
  #
4
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -76,6 +80,42 @@ import click
76
80
  required=True,
77
81
  help="KLayout .map (LEF/DEF layer map) file",
78
82
  )
83
+ @click.option(
84
+ "--grid-visible",
85
+ required=False,
86
+ default=False,
87
+ type=bool,
88
+ )
89
+ @click.option(
90
+ "--grid-show-ruler",
91
+ required=False,
92
+ default=False,
93
+ type=bool,
94
+ )
95
+ @click.option(
96
+ "--text-visible",
97
+ required=False,
98
+ default=False,
99
+ type=bool,
100
+ )
101
+ @click.option(
102
+ "--background-color",
103
+ required=False,
104
+ default=False,
105
+ type=str,
106
+ )
107
+ @click.option(
108
+ "--resolution",
109
+ required=False,
110
+ default=1000,
111
+ type=int,
112
+ )
113
+ @click.option(
114
+ "--oversampling",
115
+ required=False,
116
+ default=0,
117
+ type=int,
118
+ )
79
119
  @click.argument("input")
80
120
  def render(
81
121
  input_lefs: Tuple[str, ...],
@@ -84,6 +124,12 @@ def render(
84
124
  lyp: str,
85
125
  lym: str,
86
126
  input: str,
127
+ grid_visible: bool,
128
+ grid_show_ruler: bool,
129
+ text_visible: bool,
130
+ background_color: str,
131
+ resolution: int,
132
+ oversampling: int,
87
133
  ):
88
134
  try:
89
135
  gds = input.endswith(".gds")
@@ -100,18 +146,38 @@ def render(
100
146
  layout_options.lefdef_config.read_lef_with_def = False
101
147
  layout_options.lefdef_config.lef_files = list(input_lefs)
102
148
 
103
- view = pya.LayoutView()
104
- view.load_layer_props(lyp)
149
+ lv = pya.LayoutView()
150
+
151
+ lv.set_config("grid-visible", str(grid_visible).lower())
152
+ lv.set_config("grid-show-ruler", str(grid_show_ruler).lower())
153
+ lv.set_config("text-visible", str(text_visible).lower())
154
+ background_color = "#FFFFFF" if background_color == "white" else "#000000"
155
+ lv.set_config("background-color", background_color)
105
156
 
106
157
  if gds:
107
- view.load_layout(input)
158
+ lv.load_layout(input)
108
159
  else:
109
- view.load_layout(input, layout_options, lyt)
110
- view.max_hier()
111
- pixels = view.get_pixels_with_options(1000, 1000)
160
+ lv.load_layout(input, layout_options, lyt)
161
+
162
+ lv.max_hier()
163
+
164
+ # Get aspect ratio
165
+ top_cell = lv.active_cellview().layout().top_cell()
166
+ top_bbox = top_cell.dbbox()
167
+ aspect_ratio = top_bbox.width() / top_bbox.height()
168
+
169
+ width = resolution
170
+ height = int(width / aspect_ratio)
171
+
172
+ lv.load_layer_props(lyp)
173
+
174
+ lv.save_image_with_options(
175
+ output,
176
+ width,
177
+ height,
178
+ oversampling=oversampling,
179
+ )
112
180
 
113
- with open(output, "wb") as f:
114
- f.write(pixels.to_png_data())
115
181
  except Exception as e:
116
182
  print(e)
117
183
  exit(1)
@@ -147,3 +147,11 @@ proc read_def {} {
147
147
  puts "> def read $def_read_args"
148
148
  def read {*}$def_read_args
149
149
  }
150
+
151
+ proc read_pdk_spice {} {
152
+ set spice_files_in $::env(CELL_SPICE_MODELS)
153
+ foreach spice_file $spice_files_in {
154
+ puts "> spice read $spice_file"
155
+ readspice $spice_file
156
+ }
157
+ }
@@ -56,6 +56,8 @@ read_def
56
56
  load $::env(DESIGN_NAME)
57
57
  select top cell
58
58
 
59
+ units microns
60
+
59
61
  if { $::env(MAGIC_ZEROIZE_ORIGIN) } {
60
62
  # assuming scalegrid 1 2
61
63
  # makes origin zero based on the minimum enclosing box
@@ -73,8 +75,7 @@ if { $::env(MAGIC_ZEROIZE_ORIGIN) } {
73
75
  # file. Shapes can extend outside the block boundary.
74
76
  # magic "lef write -hide" doesn't produce nice results in this
75
77
  # case for shapes outside the boundary.
76
- box [lindex $::env(DIE_AREA) 0]um [lindex $::env(DIE_AREA) 1]um [lindex $::env(DIE_AREA) 2]um [lindex $::env(DIE_AREA) 3]um
77
- property FIXED_BBOX [box values]
78
+ property FIXED_BBOX [lindex $::env(DIE_AREA) 0]um [lindex $::env(DIE_AREA) 1]um [lindex $::env(DIE_AREA) 2]um [lindex $::env(DIE_AREA) 3]um
78
79
  }
79
80
 
80
81
  select top cell
@@ -19,10 +19,11 @@ set f [open $::env(STEP_DIR)/cif_scale.txt "w"]
19
19
  puts $f [expr {((round([magic::cif scale output] * 10000)) / 10000.0) * 1}]
20
20
  close $f
21
21
 
22
+ source $::env(SCRIPTS_DIR)/magic/common/read.tcl
23
+
22
24
  if { $::env(MAGIC_EXT_USE_GDS) } {
23
25
  gds read $::env(CURRENT_GDS)
24
26
  } else {
25
- source $::env(SCRIPTS_DIR)/magic/common/read.tcl
26
27
  read_tech_lef
27
28
  read_pdk_lef
28
29
  read_macro_lef
@@ -31,6 +32,9 @@ if { $::env(MAGIC_EXT_USE_GDS) } {
31
32
  read_def
32
33
  }
33
34
 
35
+ # annotate stdcell port order
36
+ read_pdk_spice
37
+
34
38
  if { [info exists ::env(MAGIC_EXT_ABSTRACT_CELLS)] } {
35
39
  set cells [cellname list allcells]
36
40
  set matching_cells ""
@@ -0,0 +1,72 @@
1
+ # Copyright 2025 LibreLane Contributors
2
+ #
3
+ # Adapted from OpenLane
4
+ #
5
+ # Copyright 2023 Efabless Corporation
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ # we do always want to read the GDS for this
20
+ gds read $::env(CURRENT_GDS)
21
+
22
+ load $::env(DESIGN_NAME)
23
+
24
+ set backup $::env(PWD)
25
+ set extdir $::env(STEP_DIR)/extraction_full
26
+ set netlist $::env(STEP_DIR)/$::env(DESIGN_NAME).rcx.spice
27
+
28
+ file mkdir $extdir
29
+ cd $extdir
30
+
31
+ # flatten
32
+ select top cell
33
+ flatten flat
34
+ load flat
35
+ cellname delete $::env(DESIGN_NAME)
36
+ cellname rename flat $::env(DESIGN_NAME)
37
+ select top cell
38
+
39
+ # configure parasitics extraction
40
+ puts "capacitance extraction corner: $::env(MAGIC_RCX_EXTRACT_STYLE)"
41
+ extract style $::env(MAGIC_RCX_EXTRACT_STYLE)
42
+
43
+ extract do local
44
+ if { $::env(MAGIC_RCX_DO_CAPACITANCE) } {
45
+ puts "enabling capacitance"
46
+ extract do capacitance
47
+ }
48
+ if { $::env(MAGIC_RCX_DO_RESISTANCE) } {
49
+ puts "enabling resistance"
50
+ extract do resistance
51
+ }
52
+ extract do coupling
53
+ extract do adjust
54
+ extract do unique
55
+ extract warn all
56
+
57
+ # perform the SPICE extraction itself
58
+ extract all
59
+
60
+ # merge the extracted data into a single SPICE netlist
61
+ puts "capacitance threshold: $::env(MAGIC_RCX_CTHRESH)"
62
+ # "ext2spice lvs here" is used to configure default parameters, via Tim Edwards on fossi-chat.org matrix in
63
+ # #ngspice:
64
+ # > "I use ext2spice lvs as a shorthand for "set ext2spice parameters to something sane", after which I
65
+ # > re-establish the options that I want."
66
+ ext2spice lvs
67
+ ext2spice cthresh $::env(MAGIC_RCX_CTHRESH)
68
+ ext2spice extresist on
69
+ ext2spice -f ngspice -o $netlist $::env(DESIGN_NAME).ext
70
+
71
+ cd $backup
72
+ feedback save $::env(STEP_DIR)/feedback.txt
@@ -26,3 +26,14 @@ if { [info exists ::env(LVS_FLATTEN_CELLS)] } {
26
26
  }
27
27
  }
28
28
  }
29
+
30
+ if { [info exists ::env(LVS_IGNORE_CELLS)] } {
31
+ foreach cell $::env(LVS_IGNORE_CELLS) {
32
+ if { [lsearch $cells1 "$cell"] >= 0 } {
33
+ ignore class "-circuit1 $cell"
34
+ }
35
+ if { [lsearch $cells2 "$cell"] >= 0 } {
36
+ ignore class "-circuit2 $cell"
37
+ }
38
+ }
39
+ }
@@ -18,6 +18,49 @@
18
18
  source $::env(_TCL_ENV_IN)
19
19
  source $::env(SCRIPTS_DIR)/openroad/common/set_global_connections.tcl
20
20
 
21
+ namespace eval lln {
22
+ proc get_corner_names {} {
23
+ # returns: names as a Tcl list, compatible with both OpenSTA 2 and 3
24
+ if {[string length [namespace which sta::scenes]] != 0} {
25
+ # scenes are bridged as a list of strings
26
+ return [sta::scenes]
27
+ } else {
28
+ # corners are not bridged as strings
29
+ set result [list]
30
+ foreach corner [sta::corners] {
31
+ lappend result [$corner name]
32
+ }
33
+ return $result
34
+ }
35
+ }
36
+ proc get_corner_dict {} {
37
+ # returns: Tcl dictionary from corner names to whatever object is
38
+ # interpreted as a corner for internal commands that expect corners:
39
+ # - in OpenSTA 3, that's the scene's name again
40
+ # - in OpenSTA 2, that's an opaque Tcl pointer
41
+ set result [dict create]
42
+ if {[string length [namespace which sta::scenes]] != 0} {
43
+ foreach scene [sta::scenes] {
44
+ dict set result $scene $scene
45
+ }
46
+ } else {
47
+ foreach corner [sta::corners] {
48
+ dict set result [$corner name] $corner
49
+ }
50
+ }
51
+ return $result
52
+ }
53
+
54
+ proc set_sta_cmd_corner {corner_name} {
55
+ if {[string length [namespace which sta::set_cmd_scene]] != 0} {
56
+ sta::set_cmd_scene $corner_name
57
+ } else {
58
+ set corner_object [sta::find_corner $corner_name]
59
+ sta::set_cmd_corner $corner_object
60
+ }
61
+ }
62
+ };
63
+
21
64
  proc string_in_file {file_path substring} {
22
65
  set f [open $file_path r]
23
66
  set data [read $f]
@@ -532,9 +575,7 @@ proc write_views {args} {
532
575
  }
533
576
 
534
577
  if { [info exists ::env(SAVE_SDF)] } {
535
- set corners [sta::corners]
536
- if { [llength $corners] > 1 } {
537
- } else {
578
+ if { [llength [lln::get_corner_names]] <= 1 } {
538
579
  puts "Writing SDF to '$::env(SAVE_SDF)'…"
539
580
  write_sdf -include_typ -divider . $::env(SAVE_SDF)
540
581
  }
@@ -543,11 +584,8 @@ proc write_views {args} {
543
584
 
544
585
  proc write_sdfs {} {
545
586
  if { [info exists ::env(_SDF_SAVE_DIR)] } {
546
- set corners [sta::corners]
547
-
548
587
  puts "Writing SDF files for all corners…"
549
- foreach corner $corners {
550
- set corner_name [$corner name]
588
+ foreach corner_name [lln::get_corner_names] {
551
589
  set target $::env(_SDF_SAVE_DIR)/$::env(DESIGN_NAME)__$corner_name.sdf
552
590
  write_sdf -include_typ -divider . -corner $corner_name $target
553
591
  }
@@ -560,10 +598,8 @@ proc write_libs {} {
560
598
  # This is to avoid OpenSTA writing a context-dependent timing model
561
599
  set_clock_latency -source -max 0 [all_clocks]
562
600
  set_clock_latency -source -min 0 [all_clocks]
563
- set corners [sta::corners]
564
601
  puts "Writing timing models for all corners…"
565
- foreach corner $corners {
566
- set corner_name [$corner name]
602
+ foreach corner_name [lln::get_corner_names] {
567
603
  set target $::env(_LIB_SAVE_DIR)/$::env(DESIGN_NAME)__$corner_name.lib
568
604
  puts "Writing timing models for the $corner_name corner to $target…"
569
605
  write_timing_model -corner $corner_name $target
@@ -24,7 +24,7 @@ proc log_cmd_rc {cmd args} {
24
24
  }
25
25
 
26
26
  proc set_layers_custom_rc {args} {
27
- # Returns: All corners for which RC values were found
27
+ # Returns: All corner names for which RC values were found
28
28
  set i "0"
29
29
  set tc_key "_LAYER_RC_$i"
30
30
  set custom_corner_rc [list]
@@ -41,9 +41,8 @@ proc set_layers_custom_rc {args} {
41
41
  -resistance $res_value
42
42
  incr i
43
43
  set tc_key "_LAYER_RC_$i"
44
- set corner [sta::find_corner $corner_name]
45
- if { [lsearch $custom_corner_rc $corner] == -1 } {
46
- lappend custom_corner_rc $corner
44
+ if { [lsearch $custom_corner_rc $corner_name] == -1 } {
45
+ lappend custom_corner_rc $corner_name
47
46
  }
48
47
  }
49
48
  return $custom_corner_rc
@@ -63,9 +62,8 @@ proc set_via_custom_r {args} {
63
62
  -corner $corner_name
64
63
  incr i
65
64
  set tc_key "_VIA_R_$i"
66
- set corner [sta::find_corner $corner_name]
67
- if { [lsearch $custom_corner_r $corner] == -1 } {
68
- lappend custom_corner_r $corner
65
+ if { [lsearch $custom_corner_r $corner_name] == -1 } {
66
+ lappend custom_corner_r $corner_name
69
67
  }
70
68
  }
71
69
  return $custom_corner_r
@@ -77,7 +75,7 @@ proc set_layers_default_rc {corners} {
77
75
  lassign [est::dblayer_wire_rc $layer] layer_wire_res_ohm_m layer_wire_cap_farad_m
78
76
  set layer_wire_res_per_unit_distance [expr $layer_wire_res_ohm_m * [sta::unit_scale distance] / [sta::unit_scale resistance]]
79
77
  set layer_wire_cap_per_unit_distance [expr $layer_wire_cap_farad_m * [sta::unit_scale distance] / [sta::unit_scale capacitance]]
80
- foreach corner "$corners" {
78
+ foreach corner $corners {
81
79
  log_cmd_rc set_layer_rc \
82
80
  -layer $layer_name\
83
81
  -corner $corner\
@@ -132,9 +130,9 @@ proc set_wire_rc_wrapper {args} {
132
130
  }
133
131
 
134
132
  if { [info exists flags(-use_corners)] } {
135
- foreach corner [sta::corners] {
136
- log_cmd_rc set_wire_rc {*}$clock_args -corner [$corner name]
137
- log_cmd_rc set_wire_rc {*}$signal_args -corner [$corner name]
133
+ foreach corner [lln::get_corner_names] {
134
+ log_cmd_rc set_wire_rc {*}$clock_args -corner $corner
135
+ log_cmd_rc set_wire_rc {*}$signal_args -corner $corner
138
136
  }
139
137
  } else {
140
138
  log_cmd_rc set_wire_rc {*}$clock_args
@@ -163,8 +161,8 @@ proc set_diff {setA setB} {
163
161
 
164
162
  set corners_with_custom_layer_rc [set_layers_custom_rc]
165
163
  set corners_with_custom_via_r [set_via_custom_r]
166
- set corners_without_custom_layer_rc [set_diff [sta::corners] $corners_with_custom_layer_rc]
167
- set corners_without_custom_via_r [set_diff [sta::corners] $corners_with_custom_via_r]
164
+ set corners_without_custom_layer_rc [set_diff [lln::get_corner_names] $corners_with_custom_layer_rc]
165
+ set corners_without_custom_via_r [set_diff [lln::get_corner_names] $corners_with_custom_via_r]
168
166
 
169
167
  # If ANY CORNERS have custom RC values set, set the tech LEF values for the
170
168
  # remaining corners.
@@ -175,7 +173,7 @@ set corners_without_custom_via_r [set_diff [sta::corners] $corners_with_custom_v
175
173
  # This is because, technically, while both behaviors SHOULD be identical, they
176
174
  # aren't because of roundoff errors emblematic of IEEE 754.
177
175
  if { [llength $corners_with_custom_layer_rc] } {
178
- log_cmd_rc set_layers_default_rc [lmap corner $corners_without_custom_layer_rc "\$corner name"]
176
+ log_cmd_rc set_layers_default_rc $corners_without_custom_layer_rc
179
177
  }
180
178
  if { [llength $corners_with_custom_via_r] } {
181
179
  log_cmd_rc set_vias_default_r $corners_without_custom_via_r
@@ -72,6 +72,7 @@ append_if_exists_argument arg_list CTS_MACRO_CLUSTERING_MAX_DIAMETER -macro_clus
72
72
  append_if_flag arg_list CTS_DISABLE_POST_PROCESSING -post_cts_disable
73
73
  append_if_flag arg_list CTS_OBSTRUCTION_AWARE -obstruction_aware
74
74
  append_if_flag arg_list CTS_BALANCE_LEVELS -balance_levels
75
+ append_if_exists_argument arg_list CTS_APPLY_NDR -apply_ndr
75
76
 
76
77
  if { $::env(CTS_DISTANCE_BETWEEN_BUFFERS) != 0 } {
77
78
  lappend arg_list -distance_between_buffers $::env(CTS_DISTANCE_BETWEEN_BUFFERS)