librelane 3.0.4__tar.gz → 3.0.6__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 (178) hide show
  1. {librelane-3.0.4 → librelane-3.0.6}/PKG-INFO +2 -2
  2. {librelane-3.0.4 → librelane-3.0.6}/librelane/__main__.py +1 -1
  3. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/metrics/__main__.py +16 -143
  4. librelane-3.0.6/librelane/common/metrics/compare.py +156 -0
  5. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/pyosys.py +0 -12
  6. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/yosys.py +0 -12
  7. {librelane-3.0.4 → librelane-3.0.6}/pyproject.toml +2 -2
  8. {librelane-3.0.4 → librelane-3.0.6}/Readme.md +0 -0
  9. {librelane-3.0.4 → librelane-3.0.6}/librelane/__init__.py +0 -0
  10. {librelane-3.0.4 → librelane-3.0.6}/librelane/__version__.py +0 -0
  11. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/__init__.py +0 -0
  12. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/cli.py +0 -0
  13. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/drc.py +0 -0
  14. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/generic_dict.py +0 -0
  15. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/metrics/__init__.py +0 -0
  16. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/metrics/library.py +0 -0
  17. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/metrics/metric.py +0 -0
  18. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/metrics/util.py +0 -0
  19. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/misc.py +0 -0
  20. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/ring_buffer.py +0 -0
  21. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/tcl.py +0 -0
  22. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/toolbox.py +0 -0
  23. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/tpe.py +0 -0
  24. {librelane-3.0.4 → librelane-3.0.6}/librelane/common/types.py +0 -0
  25. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/__init__.py +0 -0
  26. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/__main__.py +0 -0
  27. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/config.py +0 -0
  28. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/flow.py +0 -0
  29. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/pdk_compat.py +0 -0
  30. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/preprocessor.py +0 -0
  31. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/removals.py +0 -0
  32. {librelane-3.0.4 → librelane-3.0.6}/librelane/config/variable.py +0 -0
  33. {librelane-3.0.4 → librelane-3.0.6}/librelane/container.py +0 -0
  34. {librelane-3.0.4 → librelane-3.0.6}/librelane/env_info.py +0 -0
  35. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/hold_eco_demo/config.yaml +0 -0
  36. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/hold_eco_demo/demo.v +0 -0
  37. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/config.yaml +0 -0
  38. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/pin_order.cfg +0 -0
  39. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/src/impl.sdc +0 -0
  40. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/src/signoff.sdc +0 -0
  41. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/src/spm.v +0 -0
  42. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm/verify/spm_tb.v +0 -0
  43. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/SPM_example.v +0 -0
  44. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +0 -0
  45. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/config-tut.json +0 -0
  46. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/config.json +0 -0
  47. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/defines.v +0 -0
  48. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/template.def +0 -0
  49. {librelane-3.0.4 → librelane-3.0.6}/librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +0 -0
  50. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/__init__.py +0 -0
  51. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/builtins.py +0 -0
  52. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/chip.py +0 -0
  53. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/classic.py +0 -0
  54. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/cli.py +0 -0
  55. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/flow.py +0 -0
  56. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/misc.py +0 -0
  57. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/optimizing.py +0 -0
  58. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/sequential.py +0 -0
  59. {librelane-3.0.4 → librelane-3.0.6}/librelane/flows/synth_explore.py +0 -0
  60. {librelane-3.0.4 → librelane-3.0.6}/librelane/help/__main__.py +0 -0
  61. {librelane-3.0.4 → librelane-3.0.6}/librelane/logging/__init__.py +0 -0
  62. {librelane-3.0.4 → librelane-3.0.6}/librelane/logging/logger.py +0 -0
  63. {librelane-3.0.4 → librelane-3.0.6}/librelane/pdk_hashes.yaml +0 -0
  64. {librelane-3.0.4 → librelane-3.0.6}/librelane/plugins.py +0 -0
  65. {librelane-3.0.4 → librelane-3.0.6}/librelane/py.typed +0 -0
  66. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/base.sdc +0 -0
  67. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/Readme.md +0 -0
  68. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/insert_cell.py +0 -0
  69. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/open_design.py +0 -0
  70. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/render.py +0 -0
  71. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/stream_out.py +0 -0
  72. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/xml_drc_report_to_json.py +0 -0
  73. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/klayout/xor.drc +0 -0
  74. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/Readme.md +0 -0
  75. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/common/read.tcl +0 -0
  76. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/def/antenna_check.tcl +0 -0
  77. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/def/mag.tcl +0 -0
  78. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/def/mag_gds.tcl +0 -0
  79. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/drc.tcl +0 -0
  80. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/extract_spice.tcl +0 -0
  81. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/gds/drc_batch.tcl +0 -0
  82. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/gds/erase_box.tcl +0 -0
  83. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/gds/extras_mag.tcl +0 -0
  84. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/gds/mag_with_pointers.tcl +0 -0
  85. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/get_bbox.tcl +0 -0
  86. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/lef/extras_maglef.tcl +0 -0
  87. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/lef/maglef.tcl +0 -0
  88. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/lef.tcl +0 -0
  89. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/open.tcl +0 -0
  90. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/spice_rcx.tcl +0 -0
  91. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/magic/wrapper.tcl +0 -0
  92. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/netgen/setup.tcl +0 -0
  93. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/apply_def_template.py +0 -0
  94. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/cell_frequency.py +0 -0
  95. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/check_antenna_properties.py +0 -0
  96. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/contextualize.py +0 -0
  97. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/defutil.py +0 -0
  98. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/diodes.py +0 -0
  99. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/disconnected_pins.py +0 -0
  100. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/eco_buffer.py +0 -0
  101. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/eco_diode.py +0 -0
  102. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/filter_unannotated.py +0 -0
  103. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/io_place.py +0 -0
  104. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/ioplace_parser/__init__.py +0 -0
  105. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/ioplace_parser/parse.py +0 -0
  106. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/label_macro_pins.py +0 -0
  107. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/lefutil.py +0 -0
  108. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/placers.py +0 -0
  109. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/power_utils.py +0 -0
  110. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/random_place.py +0 -0
  111. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/reader.py +0 -0
  112. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/remove_buffers.py +0 -0
  113. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/snap_to_grid.py +0 -0
  114. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/odbpy/wire_lengths.py +0 -0
  115. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/antenna_check.tcl +0 -0
  116. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/antenna_repair.tcl +0 -0
  117. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/buffer_list.tcl +0 -0
  118. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/dpl.tcl +0 -0
  119. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/dpl_cell_pad.tcl +0 -0
  120. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/grt.tcl +0 -0
  121. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/io.tcl +0 -0
  122. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/pad_cfg.tcl +0 -0
  123. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/pdn_cfg.tcl +0 -0
  124. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/resizer.tcl +0 -0
  125. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/set_global_connections.tcl +0 -0
  126. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/set_layer_adjustments.tcl +0 -0
  127. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/set_power_nets.tcl +0 -0
  128. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/set_rc.tcl +0 -0
  129. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/common/set_routing_layers.tcl +0 -0
  130. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/cts.tcl +0 -0
  131. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/cut_rows.tcl +0 -0
  132. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/dpl.tcl +0 -0
  133. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/drt.tcl +0 -0
  134. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/dump_rc.tcl +0 -0
  135. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/fill.tcl +0 -0
  136. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/floorplan.tcl +0 -0
  137. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/gpl.tcl +0 -0
  138. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/grt.tcl +0 -0
  139. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/gui.tcl +0 -0
  140. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/insert_buffer.tcl +0 -0
  141. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/ioplacer.tcl +0 -0
  142. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/irdrop.tcl +0 -0
  143. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/pad.tcl +0 -0
  144. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/pdn.tcl +0 -0
  145. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/rcx.tcl +0 -0
  146. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/repair_design.tcl +0 -0
  147. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/repair_design_postgrt.tcl +0 -0
  148. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/rsz_timing_postcts.tcl +0 -0
  149. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/rsz_timing_postgrt.tcl +0 -0
  150. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/sta/check_macro_instances.tcl +0 -0
  151. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/sta/corner.tcl +0 -0
  152. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/tapcell.tcl +0 -0
  153. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/ungpl.tcl +0 -0
  154. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/write_cdl.tcl +0 -0
  155. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/openroad/write_views.tcl +0 -0
  156. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/pyosys/construct_abc_script.py +0 -0
  157. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/pyosys/json_header.py +0 -0
  158. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/pyosys/synthesize.py +0 -0
  159. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/pyosys/ys_common.py +0 -0
  160. {librelane-3.0.4 → librelane-3.0.6}/librelane/scripts/tclsh/hello.tcl +0 -0
  161. {librelane-3.0.4 → librelane-3.0.6}/librelane/state/__init__.py +0 -0
  162. {librelane-3.0.4 → librelane-3.0.6}/librelane/state/__main__.py +0 -0
  163. {librelane-3.0.4 → librelane-3.0.6}/librelane/state/design_format.py +0 -0
  164. {librelane-3.0.4 → librelane-3.0.6}/librelane/state/state.py +0 -0
  165. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/__init__.py +0 -0
  166. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/__main__.py +0 -0
  167. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/checker.py +0 -0
  168. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/common_variables.py +0 -0
  169. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/klayout.py +0 -0
  170. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/magic.py +0 -0
  171. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/misc.py +0 -0
  172. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/netgen.py +0 -0
  173. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/odb.py +0 -0
  174. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/openroad.py +0 -0
  175. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/openroad_alerts.py +0 -0
  176. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/step.py +0 -0
  177. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/tclstep.py +0 -0
  178. {librelane-3.0.4 → librelane-3.0.6}/librelane/steps/verilator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: librelane
3
- Version: 3.0.4
3
+ Version: 3.0.6
4
4
  Summary: An infrastructure for implementing chip design flows
5
5
  License-Expression: Apache-2.0
6
6
  Maintainer: Mohamed Gaber
@@ -23,7 +23,7 @@ Requires-Dist: lxml (>=4.9.0)
23
23
  Requires-Dist: psutil (>=5.9.0)
24
24
  Requires-Dist: pyyaml (>=5,<7)
25
25
  Requires-Dist: rapidfuzz (>=3.9.0,<4)
26
- Requires-Dist: rich (>=12,<15)
26
+ Requires-Dist: rich (>=12,<16)
27
27
  Requires-Dist: semver (>=3.0.2,<4)
28
28
  Requires-Dist: yamlcore (>=0.0.2,<0.1.0)
29
29
  Project-URL: Bug Tracker, https://github.com/librelane/librelane/issues
@@ -94,7 +94,7 @@ def run(
94
94
  )
95
95
  ctx.exit(1)
96
96
  elif isinstance(meta.flow, list):
97
- TargetFlow = SequentialFlow.make(meta.flow)
97
+ TargetFlow = SequentialFlow.Make(meta.flow)
98
98
  if meta.substituting_steps is not None:
99
99
  if meta.flow is None:
100
100
  err("config_file has substituting_steps set with no flow.")
@@ -1,3 +1,7 @@
1
+ # Copyright 2026 LibreLane Contributors
2
+ #
3
+ # Adapted from OpenLane 2
4
+ #
1
5
  # Copyright 2023 Efabless Corporation
2
6
  #
3
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,42 +24,16 @@ import tarfile
20
24
  import tempfile
21
25
  from io import BytesIO
22
26
  from decimal import Decimal
23
- from typing import Optional, Set, Tuple
27
+ from typing import Optional, Tuple
24
28
 
25
29
  import cloup
26
30
  import httpx
27
31
 
28
32
  from .util import MetricDiff, TableVerbosity
33
+ from .compare import compare_metric_directories, default_filter_set
29
34
  from ..misc import Filter, get_httpx_session, mkdirp
30
35
  from ..cli import formatter_settings, IntEnumChoice
31
36
 
32
- default_filter_set = [
33
- "design__*__area",
34
- "design__max_*",
35
- "design__lvs_error__count",
36
- "antenna__violating*",
37
- "clock__*",
38
- "ir__*",
39
- "power__*",
40
- "timing__*_vio__*",
41
- "timing*wns*",
42
- "timing*tns*",
43
- "*error*",
44
- "!*__iter:*",
45
- ]
46
-
47
- # passing_filter_set = [
48
- # "design__*__area",
49
- # "route__wirelength__max",
50
- # "design__instance__utilization",
51
- # "antenna__violating*",
52
- # "timing__*__ws",
53
- # "clock__skew__*",
54
- # "ir__*",
55
- # "power__*",
56
- # "!*__iter:*",
57
- # ]
58
-
59
37
 
60
38
  @cloup.group(
61
39
  no_args_is_help=True,
@@ -141,130 +119,25 @@ def compare(
141
119
  cli.add_command(compare)
142
120
 
143
121
 
144
- def _compare_metric_folders(
145
- filter_wildcards: Tuple[str, ...],
146
- table_verbosity: TableVerbosity,
147
- path_a: str,
148
- path_b: str,
149
- significant_figures: int,
150
- ) -> Tuple[str, str]: # (summary, table)
151
- a: Set[Tuple[str, str, str]] = set()
152
- b: Set[Tuple[str, str, str]] = set()
153
-
154
- def add_designs(in_dir: str, to_set: Set[Tuple[str, str, str]]):
155
- for file in os.listdir(in_dir):
156
- basename = os.path.basename(file)
157
- if not basename.endswith(".metrics.json"):
158
- continue
159
- basename = basename[: -len(".metrics.json")]
160
-
161
- # We have to rsplit, since ihp-sg13g2 contains a "-"
162
- parts = basename.rsplit("-", maxsplit=2)
163
- if len(parts) != 3:
164
- raise ValueError(
165
- f"Invalid filename {basename}: not in the format {{pdk}}-{{scl}}-{{design_name}}"
166
- )
167
- pdk, scl, design = parts
168
- to_set.add((pdk, scl, design))
169
-
170
- add_designs(path_a, a)
171
- add_designs(path_b, b)
172
-
173
- not_in_a = b - a
174
- not_in_b = a - b
175
- common = a.intersection(b)
176
- difference_report = ""
177
- for tup in not_in_a:
178
- pdk, scl, design = tup
179
- difference_report += f"* Results for a new test, `{'/'.join(tup)}`, detected.\n"
180
- for tup in not_in_b:
181
- pdk, scl, design = tup
182
- difference_report += (
183
- f"* ‼️ Results for `{'/'.join(tup)}` appear to be missing!\n"
184
- )
185
-
186
- final_filters = []
187
- for wildcard in filter_wildcards:
188
- if wildcard == "DEFAULT":
189
- final_filters += default_filter_set
190
- else:
191
- final_filters.append(wildcard)
192
-
193
- filter = Filter(final_filters)
194
- critical_change_report = ""
195
- tables = ""
196
- total_critical = 0
197
- for pdk, scl, design in sorted(common):
198
- metrics_a = json.load(
199
- open(
200
- os.path.join(path_a, f"{pdk}-{scl}-{design}.metrics.json"),
201
- encoding="utf8",
202
- ),
203
- parse_float=Decimal,
204
- )
205
-
206
- metrics_b = json.load(
207
- open(
208
- os.path.join(path_b, f"{pdk}-{scl}-{design}.metrics.json"),
209
- encoding="utf8",
210
- ),
211
- parse_float=Decimal,
212
- )
213
-
214
- diff = MetricDiff.from_metrics(
215
- metrics_a,
216
- metrics_b,
217
- significant_figures,
218
- filter=filter,
219
- )
220
-
221
- stats = diff.stats()
222
-
223
- total_critical += stats.critical
224
- if stats.critical > 0:
225
- critical_change_report += f" * `{pdk}/{scl}/{design}` \n"
226
- if table_verbosity != "NONE":
227
- rendered = diff.render_md(("corner", ""), table_verbosity)
228
- if rendered.strip() != "":
229
- tables += f"<details><summary><code>{pdk}/{scl}/{design}</code></summary>\n{rendered}\n</details>\n\n"
230
-
231
- if total_critical == 0:
232
- critical_change_report = (
233
- "* No changes to critical metrics were detected in analyzed designs.\n"
234
- + critical_change_report
235
- )
236
- else:
237
- critical_change_report = (
238
- "* **Changes to critical metrics were detected in the following designs:**\n"
239
- + critical_change_report
240
- )
241
-
242
- report = ""
243
- report += difference_report
244
- report += critical_change_report
245
-
246
- return report, tables.strip()
247
-
248
-
249
122
  @cloup.command(no_args_is_help=True)
250
123
  @common_opts
251
- @cloup.argument("metric_folders", nargs=2)
124
+ @cloup.argument("metric_directories", nargs=2)
252
125
  def compare_multiple(
253
126
  filter_wildcards: Tuple[str, ...],
254
127
  table_verbosity: TableVerbosity,
255
- metric_folders: Tuple[str, str],
128
+ metric_directories: Tuple[str, str],
256
129
  table_out: Optional[str],
257
130
  significant_figures: int,
258
131
  ):
259
132
  """
260
- Creates a small summary/report of the differences between two folders with
133
+ Creates a small summary/report of the differences between two directories with
261
134
  metrics files.
262
135
 
263
136
  The metrics files must be named in the format ``{pdk}-{scl}-{design}.metrics.json``.
264
137
  All other files are ignored.
265
138
  """
266
- path_a, path_b = metric_folders
267
- summary, tables = _compare_metric_folders(
139
+ path_a, path_b = metric_directories
140
+ summary, tables = compare_metric_directories(
268
141
  filter_wildcards, table_verbosity, path_a, path_b, significant_figures
269
142
  )
270
143
  print(summary)
@@ -309,7 +182,7 @@ cli.add_command(compare_multiple)
309
182
  help="A GitHub token to use to query the API and fetch the metrics. Not strictly required, but helps avoid rate-limiting.",
310
183
  )
311
184
  @common_opts
312
- @cloup.argument("metric_folder", nargs=1)
185
+ @cloup.argument("metric_directory", nargs=1)
313
186
  def compare_remote(
314
187
  filter_wildcards: Tuple[str, ...],
315
188
  table_verbosity: TableVerbosity,
@@ -317,13 +190,13 @@ def compare_remote(
317
190
  metric_repo: str,
318
191
  commit: Optional[str],
319
192
  token: str,
320
- metric_folder: str,
193
+ metric_directory: str,
321
194
  table_out: Optional[str],
322
195
  significant_figures: int,
323
196
  branch: str,
324
197
  ):
325
198
  """
326
- Creates a small summary/report of the differences between a folder and
199
+ Creates a small summary/report of the differences between a directory and
327
200
  a set of metrics stored in --metric-repo. Requires Internet access and
328
201
  access to GitHub.
329
202
 
@@ -379,11 +252,11 @@ def compare_remote(
379
252
  with open(final_path, "wb") as f:
380
253
  f.write(io.read())
381
254
 
382
- summary, tables = _compare_metric_folders(
255
+ summary, tables = compare_metric_directories(
383
256
  filter_wildcards,
384
257
  table_verbosity,
385
258
  d,
386
- metric_folder,
259
+ metric_directory,
387
260
  significant_figures,
388
261
  )
389
262
  print(summary)
@@ -0,0 +1,156 @@
1
+ # Copyright 2026 LibreLane Contributors
2
+ #
3
+ # Adapted from OpenLane 2
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
+ import os
19
+ import json
20
+ from decimal import Decimal
21
+ from typing import Set, Tuple
22
+
23
+ from .util import MetricDiff, TableVerbosity
24
+ from ..misc import Filter
25
+
26
+ default_filter_set = [
27
+ "design__*__area",
28
+ "design__max_*",
29
+ "design__lvs_error__count",
30
+ "antenna__violating*",
31
+ "clock__*",
32
+ "ir__*",
33
+ "power__*",
34
+ "timing__*_vio__*",
35
+ "timing*wns*",
36
+ "timing*tns*",
37
+ "*error*",
38
+ "!*__iter:*",
39
+ ]
40
+
41
+ # passing_filter_set = [
42
+ # "design__*__area",
43
+ # "route__wirelength__max",
44
+ # "design__instance__utilization",
45
+ # "antenna__violating*",
46
+ # "timing__*__ws",
47
+ # "clock__skew__*",
48
+ # "ir__*",
49
+ # "power__*",
50
+ # "!*__iter:*",
51
+ # ]
52
+
53
+
54
+ def compare_metric_directories(
55
+ filter_wildcards: Tuple[str, ...],
56
+ table_verbosity: TableVerbosity,
57
+ path_a: str,
58
+ path_b: str,
59
+ significant_figures: int,
60
+ ) -> Tuple[str, str]: # (summary, table)
61
+ a: Set[Tuple[str, str, str]] = set()
62
+ b: Set[Tuple[str, str, str]] = set()
63
+
64
+ def add_designs(in_dir: str, to_set: Set[Tuple[str, str, str]]):
65
+ for file in os.listdir(in_dir):
66
+ basename = os.path.basename(file)
67
+ if not basename.endswith(".metrics.json"):
68
+ continue
69
+ basename = basename[: -len(".metrics.json")]
70
+
71
+ # We have to rsplit, since ihp-sg13g2 contains a "-"
72
+ parts = basename.rsplit("-", maxsplit=2)
73
+ if len(parts) != 3:
74
+ raise ValueError(
75
+ f"Invalid filename {basename}: not in the format {{pdk}}-{{scl}}-{{design_name}}"
76
+ )
77
+ pdk, scl, design = parts
78
+ to_set.add((pdk, scl, design))
79
+
80
+ add_designs(path_a, a)
81
+ add_designs(path_b, b)
82
+
83
+ not_in_a = b - a
84
+ not_in_b = a - b
85
+ common = a.intersection(b)
86
+ difference_report = ""
87
+ for tup in not_in_a:
88
+ pdk, scl, design = tup
89
+ difference_report += f"* Results for a new test, `{'/'.join(tup)}`, detected.\n"
90
+ for tup in not_in_b:
91
+ pdk, scl, design = tup
92
+ difference_report += (
93
+ f"* ‼️ Results for `{'/'.join(tup)}` appear to be missing!\n"
94
+ )
95
+
96
+ final_filters = []
97
+ for wildcard in filter_wildcards:
98
+ if wildcard == "DEFAULT":
99
+ final_filters += default_filter_set
100
+ else:
101
+ final_filters.append(wildcard)
102
+
103
+ filter = Filter(final_filters)
104
+ critical_change_report = ""
105
+ tables = ""
106
+ total_critical = 0
107
+ for pdk, scl, design in sorted(common):
108
+ metrics_a = json.load(
109
+ open(
110
+ os.path.join(path_a, f"{pdk}-{scl}-{design}.metrics.json"),
111
+ encoding="utf8",
112
+ ),
113
+ parse_float=Decimal,
114
+ )
115
+
116
+ metrics_b = json.load(
117
+ open(
118
+ os.path.join(path_b, f"{pdk}-{scl}-{design}.metrics.json"),
119
+ encoding="utf8",
120
+ ),
121
+ parse_float=Decimal,
122
+ )
123
+
124
+ diff = MetricDiff.from_metrics(
125
+ metrics_a,
126
+ metrics_b,
127
+ significant_figures,
128
+ filter=filter,
129
+ )
130
+
131
+ stats = diff.stats()
132
+
133
+ total_critical += stats.critical
134
+ if stats.critical > 0:
135
+ critical_change_report += f" * `{pdk}/{scl}/{design}` \n"
136
+ if table_verbosity != "NONE":
137
+ rendered = diff.render_md(("corner", ""), table_verbosity)
138
+ if rendered.strip() != "":
139
+ tables += f"<details><summary><code>{pdk}/{scl}/{design}</code></summary>\n{rendered}\n</details>\n\n"
140
+
141
+ if total_critical == 0:
142
+ critical_change_report = (
143
+ "* No changes to critical metrics were detected in analyzed designs.\n"
144
+ + critical_change_report
145
+ )
146
+ else:
147
+ critical_change_report = (
148
+ "* **Changes to critical metrics were detected in the following designs:**\n"
149
+ + critical_change_report
150
+ )
151
+
152
+ report = ""
153
+ report += difference_report
154
+ report += critical_change_report
155
+
156
+ return report, tables.strip()
@@ -194,18 +194,6 @@ class PyosysStep(Step):
194
194
  deprecated_names=["FULL_ADDER_MAP"],
195
195
  pdk=True,
196
196
  ),
197
- Variable(
198
- "SYNTH_MUX_MAP",
199
- Optional[Path],
200
- "A path to a file containing the mux mapping for Yosys.",
201
- pdk=True,
202
- ),
203
- Variable(
204
- "SYNTH_MUX4_MAP",
205
- Optional[Path],
206
- "A path to a file containing the mux4 mapping for Yosys.",
207
- pdk=True,
208
- ),
209
197
  Variable(
210
198
  "SYNTH_CLOCKGATE_MIN_WIDTH",
211
199
  Optional[int],
@@ -196,18 +196,6 @@ class YosysStep(TclStep):
196
196
  deprecated_names=["FULL_ADDER_MAP"],
197
197
  pdk=True,
198
198
  ),
199
- Variable(
200
- "SYNTH_MUX_MAP",
201
- Optional[Path],
202
- "A path to a file containing the mux mapping for Yosys.",
203
- pdk=True,
204
- ),
205
- Variable(
206
- "SYNTH_MUX4_MAP",
207
- Optional[Path],
208
- "A path to a file containing the mux4 mapping for Yosys.",
209
- pdk=True,
210
- ),
211
199
  Variable(
212
200
  "YOSYS_LOG_LEVEL",
213
201
  Literal["ALL", "WARNING", "ERROR"],
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "librelane"
3
- version = "3.0.4"
3
+ version = "3.0.6"
4
4
  description = "An infrastructure for implementing chip design flows"
5
5
  maintainers = [
6
6
  {name = "Mohamed Gaber", email = "donn@fossi-foundation.org"},
@@ -13,7 +13,7 @@ dependencies = [
13
13
  "click>=8,<8.3",
14
14
  "cloup>=3.0.5,<4",
15
15
  "pyyaml>=5,<7",
16
- "rich>=12,<15",
16
+ "rich>=12,<16",
17
17
  "ciel>=2.3.1,<3",
18
18
  "lxml>=4.9.0",
19
19
  "deprecated>=1.2.10,<2",
File without changes
File without changes