librelane 2.4.0.dev11__tar.gz → 2.4.0.dev13__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.
Potentially problematic release.
This version of librelane might be problematic. Click here for more details.
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/PKG-INFO +1 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/__init__.py +1 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/drc.py +1 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/misc.py +23 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/__main__.py +1 -4
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/flow.py +66 -30
- librelane-2.4.0.dev13/librelane/help/__main__.py +39 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/def/mag_gds.tcl +0 -2
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/drc.tcl +0 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/gds/extras_mag.tcl +0 -2
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/gds/mag_with_pointers.tcl +0 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/lef/extras_maglef.tcl +0 -2
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/lef/maglef.tcl +0 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/wrapper.tcl +2 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/power_utils.py +8 -6
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/reader.py +2 -2
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/state/state.py +11 -3
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/__main__.py +1 -2
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/magic.py +24 -14
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/odb.py +1 -4
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/openroad.py +1 -4
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/pyproject.toml +2 -1
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/Readme.md +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/__main__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/__version__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/cli.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/generic_dict.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/metrics/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/metrics/__main__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/metrics/library.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/metrics/metric.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/metrics/util.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/ring_buffer.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/tcl.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/toolbox.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/tpe.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/common/types.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/config.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/flow.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/pdk_compat.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/preprocessor.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/removals.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/config/variable.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/container.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/env_info.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/config.yaml +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/pin_order.cfg +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/src/impl.sdc +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/src/signoff.sdc +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/src/spm.v +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm/verify/spm_tb.v +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/SPM_example.v +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/config-tut.json +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/config.json +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/defines.v +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/template.def +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/builtins.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/classic.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/cli.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/misc.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/optimizing.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/sequential.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/flows/synth_explore.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/logging/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/logging/logger.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/open_pdks_rev +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/plugins.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/py.typed +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/base.sdc +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/Readme.md +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/open_design.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/render.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/stream_out.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/xml_drc_report_to_json.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/xor.drc +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/Readme.md +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/common/read.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/def/antenna_check.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/def/mag.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/extract_spice.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/gds/drc_batch.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/gds/erase_box.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/get_bbox.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/lef.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/open.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/netgen/setup.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/apply_def_template.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/cell_frequency.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/check_antenna_properties.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/contextualize.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/defutil.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/diodes.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/disconnected_pins.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/eco_buffer.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/eco_diode.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/filter_unannotated.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/io_place.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/ioplace_parser/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/ioplace_parser/parse.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/label_macro_pins.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/lefutil.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/placers.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/random_place.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/remove_buffers.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/snap_to_grid.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/wire_lengths.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/antenna_check.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/antenna_repair.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/basic_mp.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/buffer_list.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/dpl.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/dpl_cell_pad.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/grt.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/io.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/pdn_cfg.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/resizer.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_global_connections.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_layer_adjustments.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_power_nets.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_rc.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_routing_layers.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/cts.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/cut_rows.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/dpl.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/drt.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/fill.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/floorplan.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/gpl.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/grt.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/gui.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/insert_buffer.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/ioplacer.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/irdrop.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/pdn.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/rcx.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/repair_design.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/repair_design_postgrt.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/rsz_timing_postcts.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/rsz_timing_postgrt.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/sta/check_macro_instances.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/sta/corner.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/tapcell.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/write_views.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/pyosys/construct_abc_script.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/pyosys/json_header.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/pyosys/synthesize.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/pyosys/ys_common.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/tclsh/hello.tcl +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/state/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/state/__main__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/state/design_format.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/__init__.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/checker.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/common_variables.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/cvc_rv.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/klayout.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/misc.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/netgen.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/openroad_alerts.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/pyosys.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/step.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/tclstep.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/verilator.py +0 -0
- {librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/steps/yosys.py +0 -0
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
import io
|
|
14
15
|
import os
|
|
15
16
|
import re
|
|
16
17
|
import glob
|
|
@@ -21,6 +22,7 @@ import pathlib
|
|
|
21
22
|
import unicodedata
|
|
22
23
|
from math import inf
|
|
23
24
|
from typing import (
|
|
25
|
+
IO,
|
|
24
26
|
Any,
|
|
25
27
|
Generator,
|
|
26
28
|
Iterable,
|
|
@@ -378,7 +380,7 @@ def _get_process_limit() -> int:
|
|
|
378
380
|
return int(os.getenv("_OPENLANE_MAX_CORES", os.cpu_count() or 1))
|
|
379
381
|
|
|
380
382
|
|
|
381
|
-
def gzopen(filename, mode="rt"):
|
|
383
|
+
def gzopen(filename: AnyPath, mode="rt") -> IO[Any]:
|
|
382
384
|
"""
|
|
383
385
|
This method (tries to?) emulate the gzopen from the Linux Standard Base,
|
|
384
386
|
specifically this part:
|
|
@@ -388,6 +390,11 @@ def gzopen(filename, mode="rt"):
|
|
|
388
390
|
for reading directly from the file without any decompression.
|
|
389
391
|
|
|
390
392
|
gzip.open does not have this behavior.
|
|
393
|
+
|
|
394
|
+
:param filename: The full path to the uncompressed or gzipped file.
|
|
395
|
+
:param mode: "r", "rb", "w", "wb", "x", "xb", "a" or "ab" for
|
|
396
|
+
binary mode, or "rt", "wt", "xt" or "at" for text mode.
|
|
397
|
+
:returns: An I/O wrapper that may very slightly based on the mode.
|
|
391
398
|
"""
|
|
392
399
|
try:
|
|
393
400
|
g = gzip.open(filename, mode=mode)
|
|
@@ -400,3 +407,18 @@ def gzopen(filename, mode="rt"):
|
|
|
400
407
|
except gzip.BadGzipFile:
|
|
401
408
|
g.close()
|
|
402
409
|
return open(filename, mode=mode)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def count_occurences(fp: io.TextIOWrapper, pattern: str = "") -> int:
|
|
413
|
+
"""
|
|
414
|
+
Counts the occurences of a certain string in a stream, line-by-line, without
|
|
415
|
+
necessarily loading the entire file into memory.
|
|
416
|
+
|
|
417
|
+
Equivalent to: ``grep -c 'pattern' <file>`` (but without regex support).
|
|
418
|
+
|
|
419
|
+
:param fp: the text stream
|
|
420
|
+
:param pattern: the substring to search for. if set to "", it will simply
|
|
421
|
+
count the lines in the file.
|
|
422
|
+
:returns: the number of matching lines
|
|
423
|
+
"""
|
|
424
|
+
return sum(pattern in line for line in fp)
|
|
@@ -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
|
|
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,
|
|
@@ -375,7 +375,7 @@ class Flow(ABC):
|
|
|
375
375
|
self.progress_bar = FlowProgressBar(self.name)
|
|
376
376
|
|
|
377
377
|
@classmethod
|
|
378
|
-
def get_help_md(Self, myst_anchors: bool =
|
|
378
|
+
def get_help_md(Self, myst_anchors: bool = False) -> str: # pragma: no cover
|
|
379
379
|
"""
|
|
380
380
|
:returns: rendered Markdown help for this Flow
|
|
381
381
|
"""
|
|
@@ -415,10 +415,10 @@ class Flow(ABC):
|
|
|
415
415
|
flow_config_vars = Self.config_vars
|
|
416
416
|
|
|
417
417
|
if len(flow_config_vars):
|
|
418
|
+
config_var_anchors = f"({slugify(Self.__name__, lower=True)}-config-vars)="
|
|
418
419
|
result += textwrap.dedent(
|
|
419
420
|
f"""
|
|
420
|
-
|
|
421
|
-
|
|
421
|
+
{config_var_anchors * myst_anchors}
|
|
422
422
|
#### Flow-specific Configuration Variables
|
|
423
423
|
|
|
424
424
|
| Variable Name | Type | Description | Default | Units |
|
|
@@ -435,18 +435,14 @@ class Flow(ABC):
|
|
|
435
435
|
if len(Self.Steps):
|
|
436
436
|
result += "#### Included Steps\n"
|
|
437
437
|
for step in Self.Steps:
|
|
438
|
-
|
|
439
|
-
name = step.long_name
|
|
440
|
-
elif hasattr(step, "name"):
|
|
441
|
-
name = step.name
|
|
442
|
-
else:
|
|
443
|
-
name = step.id
|
|
438
|
+
imp_id = step.get_implementation_id()
|
|
444
439
|
if myst_anchors:
|
|
445
|
-
result += (
|
|
446
|
-
f"* [`{step.id}`](./step_config_vars.md#{slugify(name)})\n"
|
|
447
|
-
)
|
|
440
|
+
result += f"* [`{step.id}`](./step_config_vars.md#step-{slugify(imp_id, lower=True)})\n"
|
|
448
441
|
else:
|
|
449
|
-
|
|
442
|
+
variant_str = ""
|
|
443
|
+
if imp_id != step.id:
|
|
444
|
+
variant_str = f" (implementation: `{imp_id}`)"
|
|
445
|
+
result += f"* `{step.id}`{variant_str}\n"
|
|
450
446
|
|
|
451
447
|
return result
|
|
452
448
|
|
|
@@ -824,7 +820,6 @@ class Flow(ABC):
|
|
|
824
820
|
DesignFormat.POWERED_NETLIST: (os.path.join("verilog", "gl"), "v"),
|
|
825
821
|
DesignFormat.DEF: ("def", "def"),
|
|
826
822
|
DesignFormat.LEF: ("lef", "lef"),
|
|
827
|
-
DesignFormat.SDF: (os.path.join("sdf", "multicorner"), "sdf"),
|
|
828
823
|
DesignFormat.SPEF: (os.path.join("spef", "multicorner"), "spef"),
|
|
829
824
|
DesignFormat.LIB: (os.path.join("lib", "multicorner"), "lib"),
|
|
830
825
|
DesignFormat.GDS: ("gds", "gds"),
|
|
@@ -883,38 +878,67 @@ class Flow(ABC):
|
|
|
883
878
|
file_path, os.path.join(to_dir, file), follow_symlinks=True
|
|
884
879
|
)
|
|
885
880
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
881
|
+
def find_one(pattern):
|
|
882
|
+
result = glob.glob(pattern)
|
|
883
|
+
if len(result) == 0:
|
|
884
|
+
return None
|
|
885
|
+
return result[0]
|
|
890
886
|
|
|
891
|
-
|
|
887
|
+
signoff_dir = os.path.join(path, "signoff", self.config["DESIGN_NAME"])
|
|
888
|
+
openlane_signoff_dir = os.path.join(signoff_dir, "openlane-signoff")
|
|
889
|
+
mkdirp(openlane_signoff_dir)
|
|
890
|
+
|
|
891
|
+
## resolved.json
|
|
892
892
|
shutil.copyfile(
|
|
893
893
|
self.config_resolved_path,
|
|
894
|
-
os.path.join(
|
|
894
|
+
os.path.join(openlane_signoff_dir, "resolved.json"),
|
|
895
895
|
follow_symlinks=True,
|
|
896
896
|
)
|
|
897
897
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
898
|
+
## metrics
|
|
899
|
+
with open(os.path.join(signoff_dir, "metrics.csv"), "w", encoding="utf8") as f:
|
|
900
|
+
last_state.metrics_to_csv(f)
|
|
901
|
+
|
|
902
|
+
## flow logs
|
|
903
|
+
mkdirp(openlane_signoff_dir)
|
|
904
|
+
copy_dir_contents(self.run_dir, openlane_signoff_dir, "*.log")
|
|
901
905
|
|
|
902
|
-
|
|
906
|
+
### step-specific signoff logs and reports
|
|
903
907
|
for step in self.step_objects:
|
|
904
908
|
reports_dir = os.path.join(step.step_dir, "reports")
|
|
905
909
|
step_imp_id = step.get_implementation_id()
|
|
910
|
+
if step_imp_id == "Magic.DRC":
|
|
911
|
+
if drc_rpt := find_one(os.path.join(reports_dir, "*.rpt")):
|
|
912
|
+
shutil.copyfile(
|
|
913
|
+
drc_rpt, os.path.join(openlane_signoff_dir, "drc.rpt")
|
|
914
|
+
)
|
|
915
|
+
if drc_xml := find_one(os.path.join(reports_dir, "*.xml")):
|
|
916
|
+
# Despite the name, this is the Magic DRC report simply
|
|
917
|
+
# converted into a KLayout-compatible format. Confusing!
|
|
918
|
+
drc_xml_out = os.path.join(openlane_signoff_dir, "drc.klayout.xml")
|
|
919
|
+
with open(drc_xml, encoding="utf8") as i, open(
|
|
920
|
+
drc_xml_out, "w", encoding="utf8"
|
|
921
|
+
) as o:
|
|
922
|
+
o.write(
|
|
923
|
+
"<!-- Despite the name, this is the Magic DRC report in KLayout format. -->\n"
|
|
924
|
+
)
|
|
925
|
+
shutil.copyfileobj(i, o)
|
|
926
|
+
if step_imp_id == "Netgen.LVS":
|
|
927
|
+
if lvs_rpt := find_one(os.path.join(reports_dir, "*.rpt")):
|
|
928
|
+
shutil.copyfile(
|
|
929
|
+
lvs_rpt, os.path.join(openlane_signoff_dir, "lvs.rpt")
|
|
930
|
+
)
|
|
906
931
|
if step_imp_id.endswith("DRC") or step_imp_id.endswith("LVS"):
|
|
907
|
-
|
|
908
|
-
copy_dir_contents(reports_dir, signoff_folder)
|
|
909
|
-
if step_imp_id.endswith("LVS"):
|
|
910
|
-
copy_dir_contents(step.step_dir, signoff_folder, "*.log")
|
|
932
|
+
copy_dir_contents(step.step_dir, openlane_signoff_dir, "*.log")
|
|
911
933
|
if step_imp_id.endswith("CheckAntennas"):
|
|
912
934
|
if os.path.exists(reports_dir):
|
|
913
935
|
copy_dir_contents(
|
|
914
|
-
reports_dir,
|
|
936
|
+
reports_dir, openlane_signoff_dir, "antenna_summary.rpt"
|
|
915
937
|
)
|
|
916
938
|
if step_imp_id.endswith("STAPostPNR"):
|
|
917
|
-
timing_report_folder = os.path.join(
|
|
939
|
+
timing_report_folder = os.path.join(
|
|
940
|
+
openlane_signoff_dir, "timing-reports"
|
|
941
|
+
)
|
|
918
942
|
mkdirp(timing_report_folder)
|
|
919
943
|
copy_dir_contents(step.step_dir, timing_report_folder, "*summary.rpt")
|
|
920
944
|
for dir in os.listdir(step.step_dir):
|
|
@@ -925,6 +949,18 @@ class Flow(ABC):
|
|
|
925
949
|
mkdirp(target)
|
|
926
950
|
copy_dir_contents(dir_path, target, "*.rpt")
|
|
927
951
|
|
|
952
|
+
# 3. SDF
|
|
953
|
+
# (This one, as with many things in the Efabless format, is special)
|
|
954
|
+
if sdf := last_state[DesignFormat.SDF]:
|
|
955
|
+
assert isinstance(sdf, dict), "SDF is not a dictionary"
|
|
956
|
+
for corner, view in sdf.items():
|
|
957
|
+
assert isinstance(view, Path), "SDF state out returned multiple paths"
|
|
958
|
+
target_dir = os.path.join(signoff_dir, "sdf", corner)
|
|
959
|
+
mkdirp(target_dir)
|
|
960
|
+
shutil.copyfile(
|
|
961
|
+
view, os.path.join(target_dir, f"{self.config['DESIGN_NAME']}.sdf")
|
|
962
|
+
)
|
|
963
|
+
|
|
928
964
|
@deprecated(
|
|
929
965
|
version="2.0.0a46",
|
|
930
966
|
reason="Use .progress_bar.set_max_stage_count",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright 2025 LibreLane Contributors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from ..common.cli import formatter_settings
|
|
15
|
+
from ..flows import Flow
|
|
16
|
+
from ..steps import Step
|
|
17
|
+
from ..logging import console
|
|
18
|
+
|
|
19
|
+
import cloup
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@cloup.command(formatter_settings=formatter_settings)
|
|
23
|
+
@cloup.argument("step_or_flow")
|
|
24
|
+
@cloup.pass_context
|
|
25
|
+
def cli(ctx, step_or_flow):
|
|
26
|
+
"""
|
|
27
|
+
Displays rich help for the step or flow in question.
|
|
28
|
+
"""
|
|
29
|
+
if TargetFlow := Flow.factory.get(step_or_flow):
|
|
30
|
+
TargetFlow.display_help()
|
|
31
|
+
elif TargetStep := Step.factory.get(step_or_flow):
|
|
32
|
+
TargetStep.display_help()
|
|
33
|
+
else:
|
|
34
|
+
console.log(f"Unknown Flow or Step '{step_or_flow}'.")
|
|
35
|
+
ctx.exit(-1)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
cli()
|
|
@@ -17,7 +17,6 @@ import utl
|
|
|
17
17
|
|
|
18
18
|
import re
|
|
19
19
|
import json
|
|
20
|
-
import functools
|
|
21
20
|
from dataclasses import dataclass
|
|
22
21
|
from typing import Dict, List, Optional
|
|
23
22
|
|
|
@@ -49,11 +48,14 @@ class Design(object):
|
|
|
49
48
|
def get_verilog_net_name_by_bit(self, top_module: str, target_bit: int):
|
|
50
49
|
yosys_design_object = self.yosys_dict["modules"][top_module]
|
|
51
50
|
if top_module not in self.verilog_net_names_by_bit_by_module:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
# check git history for a version of this loop that is drunk on power
|
|
52
|
+
netname_by_bit = {}
|
|
53
|
+
|
|
54
|
+
for netname, info in yosys_design_object["netnames"].items():
|
|
55
|
+
for bit in info["bits"]:
|
|
56
|
+
netname_by_bit[bit] = netname
|
|
57
|
+
|
|
58
|
+
self.verilog_net_names_by_bit_by_module[top_module] = netname_by_bit
|
|
57
59
|
return self.verilog_net_names_by_bit_by_module[top_module][target_bit]
|
|
58
60
|
|
|
59
61
|
def get_pins(self, module_name: str) -> Dict[str, odb.dbMTerm]:
|
|
@@ -20,7 +20,7 @@ import sys
|
|
|
20
20
|
import json
|
|
21
21
|
import locale
|
|
22
22
|
import inspect
|
|
23
|
-
import
|
|
23
|
+
from functools import wraps
|
|
24
24
|
from decimal import Decimal
|
|
25
25
|
from fnmatch import fnmatch
|
|
26
26
|
from typing import Callable, Dict
|
|
@@ -188,7 +188,7 @@ class OdbReader(object):
|
|
|
188
188
|
|
|
189
189
|
|
|
190
190
|
def click_odb(function):
|
|
191
|
-
@
|
|
191
|
+
@wraps(function)
|
|
192
192
|
def wrapper(input_db, input_lefs, config_path, **kwargs):
|
|
193
193
|
reader = OdbReader(input_db, config_path=config_path)
|
|
194
194
|
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
|
+
import io
|
|
16
17
|
import os
|
|
18
|
+
import csv
|
|
17
19
|
import sys
|
|
18
20
|
import json
|
|
19
21
|
import shutil
|
|
@@ -214,14 +216,20 @@ class State(GenericImmutableDict[str, StateElement]):
|
|
|
214
216
|
self._walk(self, path, visitor)
|
|
215
217
|
metrics_csv_path = os.path.join(path, "metrics.csv")
|
|
216
218
|
with open(metrics_csv_path, "w", encoding="utf8") as f:
|
|
217
|
-
|
|
218
|
-
for metric in self.metrics:
|
|
219
|
-
f.write(f"{metric},{self.metrics[metric]}\n")
|
|
219
|
+
self.metrics_to_csv(f)
|
|
220
220
|
|
|
221
221
|
metrics_json_path = os.path.join(path, "metrics.json")
|
|
222
222
|
with open(metrics_json_path, "w", encoding="utf8") as f:
|
|
223
223
|
f.write(self.metrics.dumps())
|
|
224
224
|
|
|
225
|
+
def metrics_to_csv(
|
|
226
|
+
self, fp: io.TextIOWrapper, metrics_object: Optional[Dict[str, Any]] = None
|
|
227
|
+
):
|
|
228
|
+
w = csv.writer(fp)
|
|
229
|
+
w.writerow(("Metric", "Value"))
|
|
230
|
+
for entry in (metrics_object or self.metrics).items():
|
|
231
|
+
w.writerow(entry)
|
|
232
|
+
|
|
225
233
|
def validate(self):
|
|
226
234
|
"""
|
|
227
235
|
Ensures that all paths exist in a State.
|
|
@@ -15,7 +15,6 @@ import os
|
|
|
15
15
|
import shlex
|
|
16
16
|
import shutil
|
|
17
17
|
import datetime
|
|
18
|
-
import functools
|
|
19
18
|
import subprocess
|
|
20
19
|
from functools import partial
|
|
21
20
|
from typing import IO, Any, Dict, Optional, Sequence, Union
|
|
@@ -239,7 +238,7 @@ def eject(ctx, output, state_in, config, id):
|
|
|
239
238
|
found_stdin_data = found_stdin.read()
|
|
240
239
|
raise Stop()
|
|
241
240
|
|
|
242
|
-
step.run_subprocess =
|
|
241
|
+
step.run_subprocess = partial(
|
|
243
242
|
step.run_subprocess,
|
|
244
243
|
_popen_callable=popen_substitute,
|
|
245
244
|
)
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import os
|
|
15
15
|
import re
|
|
16
16
|
import shutil
|
|
17
|
-
import functools
|
|
18
17
|
import subprocess
|
|
19
18
|
from signal import SIGKILL
|
|
20
19
|
from decimal import Decimal
|
|
@@ -34,7 +33,8 @@ from .tclstep import TclStep
|
|
|
34
33
|
from ..state import DesignFormat, State
|
|
35
34
|
|
|
36
35
|
from ..config import Variable
|
|
37
|
-
from ..common import get_script_dir, DRC as DRCObject, Path, mkdirp
|
|
36
|
+
from ..common import get_script_dir, DRC as DRCObject, Path, mkdirp, count_occurences
|
|
37
|
+
from ..logging import warn
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class MagicOutputProcessor(OutputProcessor):
|
|
@@ -464,6 +464,12 @@ class SpiceExtraction(MagicStep):
|
|
|
464
464
|
"Extracts a SPICE netlist based on black-boxed standard cells and macros (basically, anything with a LEF) rather than transistors. An error will be thrown if both this and `MAGIC_EXT_USE_GDS` is set to ``True``.",
|
|
465
465
|
default=False,
|
|
466
466
|
),
|
|
467
|
+
Variable(
|
|
468
|
+
"MAGIC_FEEDBACK_CONVERSION_THRESHOLD",
|
|
469
|
+
int,
|
|
470
|
+
"If Magic provides more feedback items than this threshold, conversion to KLayout databases is skipped (as something has gone horribly wrong.)",
|
|
471
|
+
default=10000,
|
|
472
|
+
),
|
|
467
473
|
]
|
|
468
474
|
|
|
469
475
|
def get_script_path(self):
|
|
@@ -481,22 +487,29 @@ class SpiceExtraction(MagicStep):
|
|
|
481
487
|
|
|
482
488
|
views_updates, metrics_updates = super().run(state_in, env=env, **kwargs)
|
|
483
489
|
|
|
484
|
-
cif_scale = Decimal(open(os.path.join(self.step_dir, "cif_scale.txt")).read())
|
|
485
490
|
feedback_path = os.path.join(self.step_dir, "feedback.txt")
|
|
491
|
+
with open(feedback_path, encoding="utf8") as f:
|
|
492
|
+
illegal_overlap_count = count_occurences(f, "Illegal overlap")
|
|
493
|
+
|
|
494
|
+
metrics_updates["magic__illegal_overlap__count"] = illegal_overlap_count
|
|
495
|
+
threshold = self.config["MAGIC_FEEDBACK_CONVERSION_THRESHOLD"]
|
|
496
|
+
if illegal_overlap_count > threshold:
|
|
497
|
+
warn(
|
|
498
|
+
f"Not converting the feedback to the KLayout database format: {illegal_overlap_count} > MAGIC_FEEDBACK_CONVERSION_THRESHOLD ({threshold}). You may manually increase the threshold, but it might take forever."
|
|
499
|
+
)
|
|
500
|
+
return views_updates, metrics_updates
|
|
501
|
+
|
|
502
|
+
cif_scale = Decimal(open(os.path.join(self.step_dir, "cif_scale.txt")).read())
|
|
486
503
|
try:
|
|
487
504
|
se_feedback, _ = DRCObject.from_magic_feedback(
|
|
488
505
|
open(feedback_path, encoding="utf8"),
|
|
489
506
|
cif_scale,
|
|
490
507
|
self.config["DESIGN_NAME"],
|
|
491
508
|
)
|
|
492
|
-
illegal_overlap_count =
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
for v in se_feedback.violations.values()
|
|
497
|
-
if "Illegal overlap" in v.description
|
|
498
|
-
],
|
|
499
|
-
0,
|
|
509
|
+
illegal_overlap_count = sum(
|
|
510
|
+
len(v.bounding_boxes)
|
|
511
|
+
for v in se_feedback.violations.values()
|
|
512
|
+
if "Illegal overlap" in v.description
|
|
500
513
|
)
|
|
501
514
|
with open(os.path.join(self.step_dir, "feedback.xml"), "wb") as f:
|
|
502
515
|
se_feedback.to_klayout_xml(f)
|
|
@@ -505,9 +518,6 @@ class SpiceExtraction(MagicStep):
|
|
|
505
518
|
self.warn(
|
|
506
519
|
f"Failed to convert SPICE extraction feedback to KLayout database format: {e}"
|
|
507
520
|
)
|
|
508
|
-
metrics_updates["magic__illegal_overlap__count"] = (
|
|
509
|
-
open(feedback_path, encoding="utf8").read().count("Illegal overlap")
|
|
510
|
-
)
|
|
511
521
|
return views_updates, metrics_updates
|
|
512
522
|
|
|
513
523
|
|
|
@@ -17,7 +17,6 @@ import json
|
|
|
17
17
|
import shutil
|
|
18
18
|
from math import inf
|
|
19
19
|
from decimal import Decimal
|
|
20
|
-
from functools import reduce
|
|
21
20
|
from abc import abstractmethod
|
|
22
21
|
from dataclasses import dataclass
|
|
23
22
|
from typing import Dict, List, Literal, Optional, Tuple
|
|
@@ -414,9 +413,7 @@ class ManualMacroPlacement(OdbpyStep):
|
|
|
414
413
|
)
|
|
415
414
|
shutil.copyfile(cfg_ref, cfg_file)
|
|
416
415
|
elif macros := self.config.get("MACROS"):
|
|
417
|
-
instance_count =
|
|
418
|
-
lambda x, y: x + len(y.instances), macros.values(), 0
|
|
419
|
-
)
|
|
416
|
+
instance_count = sum(len(m.instances) for m in macros.values())
|
|
420
417
|
if instance_count >= 1:
|
|
421
418
|
with open(cfg_file, "w") as f:
|
|
422
419
|
for module, macro in macros.items():
|
|
@@ -19,7 +19,6 @@ import io
|
|
|
19
19
|
import os
|
|
20
20
|
import re
|
|
21
21
|
import json
|
|
22
|
-
import functools
|
|
23
22
|
import subprocess
|
|
24
23
|
from enum import Enum
|
|
25
24
|
from math import inf
|
|
@@ -1147,9 +1146,7 @@ def get_psm_error_count(rpt: io.TextIOWrapper) -> int:
|
|
|
1147
1146
|
|
|
1148
1147
|
sio.seek(0)
|
|
1149
1148
|
violations = yaml.load(sio, Loader=yaml.SafeLoader) or []
|
|
1150
|
-
return
|
|
1151
|
-
lambda acc, current: acc + len(current["srcs"]), violations, 0
|
|
1152
|
-
)
|
|
1149
|
+
return sum(len(violation["srcs"]) for violation in violations)
|
|
1153
1150
|
|
|
1154
1151
|
|
|
1155
1152
|
@Step.factory.register()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "librelane"
|
|
3
|
-
version = "2.4.0.
|
|
3
|
+
version = "2.4.0.dev13"
|
|
4
4
|
description = "An infrastructure for implementing chip design flows"
|
|
5
5
|
# Technically, maintainer. We cannot use the maintainers field until
|
|
6
6
|
# poetry-core>=2.0.0 which requires Python version 3.9+. This field does
|
|
@@ -65,6 +65,7 @@ librelane = "librelane.__main__:cli"
|
|
|
65
65
|
"librelane.steps" = "librelane.steps.__main__:cli"
|
|
66
66
|
"librelane.config" = "librelane.config.__main__:cli"
|
|
67
67
|
"librelane.state" = "librelane.state.__main__:cli"
|
|
68
|
+
"librelane.help" = "librelane.help.__main__:cli"
|
|
68
69
|
"librelane.env_info" = "librelane:env_info_cli"
|
|
69
70
|
|
|
70
71
|
[build-system]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/klayout/xml_drc_report_to_json.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/magic/def/antenna_check.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/apply_def_template.py
RENAMED
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/check_antenna_properties.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/disconnected_pins.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/filter_unannotated.py
RENAMED
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/ioplace_parser/__init__.py
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/odbpy/ioplace_parser/parse.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/antenna_check.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/antenna_repair.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/dpl_cell_pad.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/pdn_cfg.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/resizer.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_power_nets.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/common/set_rc.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/insert_buffer.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/repair_design.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/repair_design_postgrt.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/rsz_timing_postcts.tcl
RENAMED
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/openroad/rsz_timing_postgrt.tcl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{librelane-2.4.0.dev11 → librelane-2.4.0.dev13}/librelane/scripts/pyosys/construct_abc_script.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|