librelane 3.0.4__tar.gz → 3.1.0.dev2__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.
- {librelane-3.0.4 → librelane-3.1.0.dev2}/PKG-INFO +1 -1
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/toolbox.py +7 -1
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/config.py +4 -4
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/flow.py +40 -11
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/pdk_compat.py +3 -3
- librelane-3.1.0.dev2/librelane/pdk_hashes.yaml +3 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/common/read.tcl +24 -45
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/drc.tcl +4 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/power_utils.py +9 -2
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/io.tcl +0 -14
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/pad_cfg.tcl +30 -13
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/pdn_cfg.tcl +1 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/repair_design.tcl +5 -2
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/pyosys/json_header.py +5 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/pyosys/synthesize.py +15 -6
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/common_variables.py +6 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/klayout.py +12 -9
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/odb.py +2 -1
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/openroad.py +17 -2
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/pyosys.py +8 -3
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/verilator.py +5 -1
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/yosys.py +5 -4
- {librelane-3.0.4 → librelane-3.1.0.dev2}/pyproject.toml +1 -1
- librelane-3.0.4/librelane/pdk_hashes.yaml +0 -3
- {librelane-3.0.4 → librelane-3.1.0.dev2}/Readme.md +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/__version__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/cli.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/drc.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/generic_dict.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/metrics/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/metrics/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/metrics/library.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/metrics/metric.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/metrics/util.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/misc.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/ring_buffer.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/tcl.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/tpe.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/common/types.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/preprocessor.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/removals.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/config/variable.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/container.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/env_info.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/hold_eco_demo/config.yaml +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/hold_eco_demo/demo.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/config.yaml +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/pin_order.cfg +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/src/impl.sdc +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/src/signoff.sdc +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/src/spm.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm/verify/spm_tb.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/SPM_example.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/base_sdc_file.sdc +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/config-tut.json +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/config.json +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/defines.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/template.def +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/examples/spm-user_project_wrapper/user_project_wrapper.v +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/builtins.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/chip.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/classic.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/cli.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/flow.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/misc.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/optimizing.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/sequential.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/flows/synth_explore.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/help/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/logging/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/logging/logger.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/plugins.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/py.typed +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/base.sdc +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/Readme.md +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/insert_cell.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/open_design.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/render.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/stream_out.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/xml_drc_report_to_json.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/klayout/xor.drc +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/Readme.md +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/def/antenna_check.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/def/mag.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/def/mag_gds.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/extract_spice.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/gds/drc_batch.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/gds/erase_box.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/gds/extras_mag.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/gds/mag_with_pointers.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/get_bbox.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/lef/extras_maglef.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/lef/maglef.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/lef.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/open.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/spice_rcx.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/magic/wrapper.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/netgen/setup.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/apply_def_template.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/cell_frequency.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/check_antenna_properties.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/contextualize.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/defutil.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/diodes.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/disconnected_pins.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/eco_buffer.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/eco_diode.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/filter_unannotated.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/io_place.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/ioplace_parser/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/ioplace_parser/parse.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/label_macro_pins.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/lefutil.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/placers.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/random_place.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/reader.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/remove_buffers.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/snap_to_grid.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/odbpy/wire_lengths.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/antenna_check.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/antenna_repair.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/buffer_list.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/dpl.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/dpl_cell_pad.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/grt.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/resizer.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/set_global_connections.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/set_layer_adjustments.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/set_power_nets.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/set_rc.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/common/set_routing_layers.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/cts.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/cut_rows.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/dpl.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/drt.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/dump_rc.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/fill.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/floorplan.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/gpl.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/grt.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/gui.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/insert_buffer.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/ioplacer.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/irdrop.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/pad.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/pdn.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/rcx.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/repair_design_postgrt.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/rsz_timing_postcts.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/rsz_timing_postgrt.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/sta/check_macro_instances.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/sta/corner.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/tapcell.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/ungpl.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/write_cdl.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/openroad/write_views.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/pyosys/construct_abc_script.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/pyosys/ys_common.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/scripts/tclsh/hello.tcl +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/state/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/state/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/state/design_format.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/state/state.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/__init__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/__main__.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/checker.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/magic.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/misc.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/netgen.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/openroad_alerts.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/step.py +0 -0
- {librelane-3.0.4 → librelane-3.1.0.dev2}/librelane/steps/tclstep.py +0 -0
|
@@ -232,10 +232,16 @@ class Toolbox(object):
|
|
|
232
232
|
|
|
233
233
|
timing_corner = timing_corner or config["DEFAULT_CORNER"]
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
# Filter the cell libs
|
|
236
|
+
all_libs: List[Path] = self.filter_views(
|
|
237
|
+
config, config["CELL_LIBS"], timing_corner
|
|
238
|
+
)
|
|
236
239
|
if len(all_libs) == 0:
|
|
237
240
|
warn(f"No SCL lib files found for {timing_corner}.")
|
|
238
241
|
|
|
242
|
+
# Add optional I/O pad libs
|
|
243
|
+
all_libs += self.filter_views(config, config["PAD_LIBS"], timing_corner)
|
|
244
|
+
|
|
239
245
|
all_netlists: List[Path] = []
|
|
240
246
|
all_spefs: List[Tuple[str, Path]] = []
|
|
241
247
|
|
|
@@ -495,10 +495,10 @@ class Config(GenericImmutableDict[str, Any]):
|
|
|
495
495
|
:param pdk: A process design kit to use. Required unless specified via the
|
|
496
496
|
"PDK" key in a configuration object.
|
|
497
497
|
|
|
498
|
-
:param pdk_root: Required if
|
|
498
|
+
:param pdk_root: Required if Ciel is not installed.
|
|
499
499
|
|
|
500
|
-
If
|
|
501
|
-
|
|
500
|
+
If Ciel is installed, this value can be used to optionally override
|
|
501
|
+
Ciel's default.
|
|
502
502
|
|
|
503
503
|
:param scl: A standard cell library to use. If not specified, the PDK's
|
|
504
504
|
default standard cell library will be used instead.
|
|
@@ -713,7 +713,7 @@ class Config(GenericImmutableDict[str, Any]):
|
|
|
713
713
|
pdk=pdk,
|
|
714
714
|
pdkpath=pdkpath,
|
|
715
715
|
scl=mutable[SpecialKeys.scl],
|
|
716
|
-
pad=mutable.get(SpecialKeys.pad,
|
|
716
|
+
pad=mutable.get(SpecialKeys.pad, pad),
|
|
717
717
|
design_dir=design_dir,
|
|
718
718
|
)
|
|
719
719
|
)
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import os
|
|
19
19
|
|
|
20
20
|
from decimal import Decimal
|
|
21
|
-
from typing import List, Optional, Dict, Sequence, Union, Tuple
|
|
21
|
+
from typing import List, Optional, Dict, Sequence, Union, Tuple, Literal
|
|
22
22
|
|
|
23
23
|
from .variable import Variable, Macro
|
|
24
24
|
from ..common import Path, get_script_dir
|
|
@@ -39,6 +39,12 @@ pdk_variables = [
|
|
|
39
39
|
"Specifies the default standard cell library to be used under the specified PDK. Must be a valid C identifier, i.e., matches the regular expression `[_a-zA-Z][_a-zA-Z0-9]+`.",
|
|
40
40
|
pdk=True,
|
|
41
41
|
),
|
|
42
|
+
Variable(
|
|
43
|
+
"PAD_CELL_LIBRARY",
|
|
44
|
+
Optional[str],
|
|
45
|
+
"Specifies the default pad cell library to be used under the specified PDK. Must be a valid C identifier, i.e., matches the regular expression `[_a-zA-Z][_a-zA-Z0-9]+`.",
|
|
46
|
+
pdk=True,
|
|
47
|
+
),
|
|
42
48
|
Variable(
|
|
43
49
|
"VDD_PIN",
|
|
44
50
|
str,
|
|
@@ -127,9 +133,10 @@ scl_variables = [
|
|
|
127
133
|
deprecated_names=["DECAP_CELL"],
|
|
128
134
|
),
|
|
129
135
|
Variable(
|
|
130
|
-
"
|
|
136
|
+
"CELL_LIBS",
|
|
131
137
|
Dict[str, List[Path]],
|
|
132
138
|
"A map from corner patterns to a list of associated liberty files. Exactly one entry must match the `DEFAULT_CORNER`.",
|
|
139
|
+
deprecated_names=["LIB"],
|
|
133
140
|
pdk=True,
|
|
134
141
|
),
|
|
135
142
|
Variable(
|
|
@@ -427,9 +434,10 @@ option_variables = [
|
|
|
427
434
|
|
|
428
435
|
pad_variables = [
|
|
429
436
|
Variable(
|
|
430
|
-
"
|
|
431
|
-
Optional[List[Path]],
|
|
432
|
-
"
|
|
437
|
+
"PAD_LIBS",
|
|
438
|
+
Optional[Dict[str, List[Path]]],
|
|
439
|
+
"A map from corner patterns to a list of associated liberty files. Exactly one entry must match the `DEFAULT_CORNER`.",
|
|
440
|
+
default={},
|
|
433
441
|
pdk=True,
|
|
434
442
|
),
|
|
435
443
|
Variable(
|
|
@@ -438,6 +446,12 @@ pad_variables = [
|
|
|
438
446
|
"Path(s) to IO pad LEF file(s).",
|
|
439
447
|
pdk=True,
|
|
440
448
|
),
|
|
449
|
+
Variable(
|
|
450
|
+
"PAD_GDS",
|
|
451
|
+
Optional[List[Path]],
|
|
452
|
+
"Path(s) to IO pad GDS file(s).",
|
|
453
|
+
pdk=True,
|
|
454
|
+
),
|
|
441
455
|
Variable(
|
|
442
456
|
"PAD_VERILOG_MODELS",
|
|
443
457
|
Optional[List[Path]],
|
|
@@ -456,12 +470,6 @@ pad_variables = [
|
|
|
456
470
|
description="A circuit-design language view of the io pad library.",
|
|
457
471
|
pdk=True,
|
|
458
472
|
),
|
|
459
|
-
Variable(
|
|
460
|
-
"PAD_LIBS",
|
|
461
|
-
Optional[Dict[str, List[Path]]],
|
|
462
|
-
"A map from corner patterns to a list of associated liberty files. Exactly one entry must match the `DEFAULT_CORNER`.",
|
|
463
|
-
pdk=True,
|
|
464
|
-
),
|
|
465
473
|
Variable(
|
|
466
474
|
"PAD_CORNER",
|
|
467
475
|
Optional[List[str]],
|
|
@@ -535,6 +543,27 @@ pad_variables = [
|
|
|
535
543
|
units="µm",
|
|
536
544
|
pdk=True,
|
|
537
545
|
),
|
|
546
|
+
Variable(
|
|
547
|
+
"PAD_ROTATION_HORIZONTAL",
|
|
548
|
+
Optional[Literal["R0", "MY", "R90", "MXR90", "R180", "MX", "R270", "MYR90"]],
|
|
549
|
+
"Rotation to apply to the horizontal sites to ensure pads are placed correctly.",
|
|
550
|
+
default="R0",
|
|
551
|
+
pdk=True,
|
|
552
|
+
),
|
|
553
|
+
Variable(
|
|
554
|
+
"PAD_ROTATION_VERTICAL",
|
|
555
|
+
Optional[Literal["R0", "MY", "R90", "MXR90", "R180", "MX", "R270", "MYR90"]],
|
|
556
|
+
"Rotation to apply to the vertical sites to ensure pads are placed correctly.",
|
|
557
|
+
default="R0",
|
|
558
|
+
pdk=True,
|
|
559
|
+
),
|
|
560
|
+
Variable(
|
|
561
|
+
"PAD_ROTATION_CORNER",
|
|
562
|
+
Optional[Literal["R0", "MY", "R90", "MXR90", "R180", "MX", "R270", "MYR90"]],
|
|
563
|
+
"Rotation to apply to the corner sites to ensure pads are placed correctly.",
|
|
564
|
+
default="R0",
|
|
565
|
+
pdk=True,
|
|
566
|
+
),
|
|
538
567
|
]
|
|
539
568
|
|
|
540
569
|
flow_common_variables = pdk_variables + scl_variables + option_variables + pad_variables
|
|
@@ -203,9 +203,9 @@ def migrate_old_config(config: Mapping[str, Any]) -> Dict[str, Any]:
|
|
|
203
203
|
corner = f"*_{pvt}"
|
|
204
204
|
lib_sta[corner] = lib_list
|
|
205
205
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
)
|
|
206
|
+
if (new["PDK"].startswith("sky130") or new["PDK"].startswith("gf180mcu")) and (
|
|
207
|
+
"LIB" not in config and "CELL_LIBS" not in config
|
|
208
|
+
):
|
|
209
209
|
process_sta("LIB_SYNTH")
|
|
210
210
|
process_sta("LIB_SLOWEST")
|
|
211
211
|
process_sta("LIB_FASTEST")
|
|
@@ -56,34 +56,37 @@ proc read_pad_lef {} {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
proc
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
proc _read_gds {env_name} {
|
|
60
|
+
# Pre-check
|
|
61
|
+
if { ![info exist ::env($env_name)] } {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Save options
|
|
66
|
+
set old [list]
|
|
67
|
+
lappend old [gds rescale]
|
|
68
|
+
lappend old [gds readonly]
|
|
62
69
|
gds rescale false
|
|
63
70
|
gds readonly true
|
|
64
|
-
|
|
71
|
+
|
|
72
|
+
# Read GDS
|
|
73
|
+
set gds_files_in $::env($env_name)
|
|
65
74
|
foreach gds_file $gds_files_in {
|
|
66
75
|
puts "> gds read $gds_file"
|
|
67
76
|
gds read $gds_file
|
|
68
77
|
}
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
|
|
79
|
+
# Restore options
|
|
80
|
+
gds rescale [lindex $old 0]
|
|
81
|
+
gds readonly [lindex $old 1]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
proc read_pdk_gds {} {
|
|
85
|
+
_read_gds CELL_GDS
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
proc read_macro_gds {} {
|
|
74
|
-
|
|
75
|
-
set old_readonly [gds readonly]
|
|
76
|
-
gds rescale false
|
|
77
|
-
gds readonly true
|
|
78
|
-
if { [info exist ::env(MACRO_GDS_FILES)] } {
|
|
79
|
-
set gds_files_in $::env(MACRO_GDS_FILES)
|
|
80
|
-
foreach gds_file $gds_files_in {
|
|
81
|
-
puts "> gds read $gds_file"
|
|
82
|
-
gds read $gds_file
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
gds rescale $old_rescale
|
|
86
|
-
gds readonly $old_readonly
|
|
89
|
+
_read_gds MACRO_GDS_FILES
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
proc read_macro_gds_blackbox {} {
|
|
@@ -104,35 +107,11 @@ proc read_macro_gds_blackbox {} {
|
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
proc read_extra_gds {} {
|
|
107
|
-
|
|
108
|
-
set old_readonly [gds readonly]
|
|
109
|
-
gds rescale false
|
|
110
|
-
gds readonly true
|
|
111
|
-
if { [info exist ::env(EXTRA_GDS)] } {
|
|
112
|
-
set gds_files_in $::env(EXTRA_GDS)
|
|
113
|
-
foreach gds_file $gds_files_in {
|
|
114
|
-
puts "> gds read $gds_file"
|
|
115
|
-
gds read $gds_file
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
gds rescale $old_rescale
|
|
119
|
-
gds readonly $old_readonly
|
|
110
|
+
_read_gds EXTRA_GDS
|
|
120
111
|
}
|
|
121
112
|
|
|
122
113
|
proc read_pad_gds {} {
|
|
123
|
-
|
|
124
|
-
set old_readonly [gds readonly]
|
|
125
|
-
gds rescale false
|
|
126
|
-
gds readonly true
|
|
127
|
-
if { [info exist ::env(PAD_GDS)] } {
|
|
128
|
-
set gds_files_in $::env(PAD_GDS)
|
|
129
|
-
foreach gds_file $gds_files_in {
|
|
130
|
-
puts "> gds read $gds_file"
|
|
131
|
-
gds read $gds_file
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
gds rescale $old_rescale
|
|
135
|
-
gds readonly $old_readonly
|
|
114
|
+
_read_gds PAD_GDS
|
|
136
115
|
}
|
|
137
116
|
|
|
138
117
|
proc read_def {} {
|
|
@@ -33,6 +33,10 @@ if { [info exists ::env(MAGIC_DRC_MAGLEFS)] } {
|
|
|
33
33
|
gds noduplicates true
|
|
34
34
|
gds readonly true
|
|
35
35
|
|
|
36
|
+
# Enable maskhints so that DRC rules against generated layers are run
|
|
37
|
+
# against the closest possible version to what's actually in the GDS
|
|
38
|
+
gds maskhints true
|
|
39
|
+
|
|
36
40
|
# Flatten cells
|
|
37
41
|
if { [info exists ::env(MAGIC_GDS_FLATGLOB)] } {
|
|
38
42
|
foreach {gds_flatglob} $::env(MAGIC_GDS_FLATGLOB) {
|
|
@@ -52,8 +52,15 @@ class Design(object):
|
|
|
52
52
|
netname_by_bit = {}
|
|
53
53
|
|
|
54
54
|
for netname, info in yosys_design_object["netnames"].items():
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
assert len(info["bits"]) > 0
|
|
56
|
+
# Single bit net, return name directly
|
|
57
|
+
if len(info["bits"]) == 1:
|
|
58
|
+
netname_by_bit[info["bits"][0]] = netname
|
|
59
|
+
# Append bit index to signal name
|
|
60
|
+
else:
|
|
61
|
+
offset = info.get("offset", 0)
|
|
62
|
+
for index, bit in enumerate(info["bits"]):
|
|
63
|
+
netname_by_bit[bit] = f"{netname}[{offset + index}]"
|
|
57
64
|
|
|
58
65
|
self.verilog_net_names_by_bit_by_module[top_module] = netname_by_bit
|
|
59
66
|
return self.verilog_net_names_by_bit_by_module[top_module][target_bit]
|
|
@@ -235,13 +235,6 @@ proc read_timing_info {args} {
|
|
|
235
235
|
read_liberty -corner $corner_name $extra_lib
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
-
|
|
239
|
-
if { [info exists ::env(PAD_LIBS) ] } {
|
|
240
|
-
foreach lib $::env(PAD_LIBS) {
|
|
241
|
-
puts "Reading gpio pad timing for the '$corner_name' corner at '$lib'…"
|
|
242
|
-
read_liberty -corner $corner_name $lib
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
238
|
|
|
246
239
|
set blackbox_wildcard {/// sta-blackbox}
|
|
247
240
|
foreach nl $::env(_CURRENT_CORNER_NETLISTS) {
|
|
@@ -343,13 +336,6 @@ proc read_pnr_libs {args} {
|
|
|
343
336
|
read_liberty -corner $corner_name $extra_lib
|
|
344
337
|
}
|
|
345
338
|
}
|
|
346
|
-
|
|
347
|
-
if { [info exists ::env(PAD_LIBS) ] } {
|
|
348
|
-
foreach pad_lib $::env(PAD_LIBS) {
|
|
349
|
-
puts "Reading gpio pad timing library for the '$corner_name' corner at '$pad_lib'…"
|
|
350
|
-
read_liberty -corner $corner_name $pad_lib
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
339
|
}
|
|
354
340
|
}
|
|
355
341
|
|
|
@@ -20,6 +20,11 @@ puts "\[INFO\] Generating padring…"
|
|
|
20
20
|
set block [ord::get_db_block]
|
|
21
21
|
set units [$block getDefUnits]
|
|
22
22
|
|
|
23
|
+
# Round a micrometer value to nanometer
|
|
24
|
+
proc round_um_nm {value} {
|
|
25
|
+
return [expr double(round($value * 1000)) / 1000]
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
# Pad Placement Algorithm
|
|
24
29
|
#
|
|
25
30
|
# For all sides:
|
|
@@ -74,7 +79,10 @@ make_io_sites \
|
|
|
74
79
|
-horizontal_site $::env(PAD_SITE_NAME) \
|
|
75
80
|
-vertical_site $::env(PAD_SITE_NAME) \
|
|
76
81
|
-corner_site $::env(PAD_CORNER_SITE_NAME) \
|
|
77
|
-
-offset $::env(PAD_EDGE_SPACING)
|
|
82
|
+
-offset $::env(PAD_EDGE_SPACING) \
|
|
83
|
+
-rotation_horizontal $::env(PAD_ROTATION_HORIZONTAL) \
|
|
84
|
+
-rotation_vertical $::env(PAD_ROTATION_VERTICAL) \
|
|
85
|
+
-rotation_corner $::env(PAD_ROTATION_CORNER)
|
|
78
86
|
|
|
79
87
|
set sides {PAD_SOUTH PAD_EAST PAD_NORTH PAD_WEST}
|
|
80
88
|
set vertical_sides [list PAD_EAST PAD_WEST]
|
|
@@ -125,15 +133,15 @@ foreach side $sides {
|
|
|
125
133
|
|
|
126
134
|
set space_between_pads [expr $space_for_fill / ([llength $::env($side)] + 1)]
|
|
127
135
|
puts "space_between_pads: $space_between_pads"
|
|
128
|
-
|
|
129
|
-
# Round to
|
|
130
|
-
set
|
|
131
|
-
puts "
|
|
136
|
+
|
|
137
|
+
# Round to PAD_SPACING_MULTIPLE
|
|
138
|
+
set space_between_pads_multiple [round_um_nm [expr floor($space_between_pads / $::env(PAD_SPACING_MULTIPLE)) * $::env(PAD_SPACING_MULTIPLE)]]
|
|
139
|
+
puts "space_between_pads_multiple: $space_between_pads_multiple"
|
|
132
140
|
|
|
133
141
|
# The spacing for the pads on the side (the remaining space)
|
|
134
|
-
set space_side [expr
|
|
142
|
+
set space_side [round_um_nm [expr ($space_for_fill - $space_between_pads_multiple * ([llength $::env($side)] - 1)) / 2]]
|
|
135
143
|
|
|
136
|
-
if { $space_side !=
|
|
144
|
+
if { $space_side != [round_um_nm [expr floor($space_side / $pad_site_width) * $pad_site_width]] } {
|
|
137
145
|
puts "\[Error\] The remaining area for the pads on the side ($space_side) is not divisible by the minimum site width (minimum filler: $pad_site_width)."
|
|
138
146
|
exit 1
|
|
139
147
|
}
|
|
@@ -150,7 +158,7 @@ foreach side $sides {
|
|
|
150
158
|
# For all instances
|
|
151
159
|
foreach inst_name $::env($side) {
|
|
152
160
|
if { [set inst [$block findInst $inst_name]] == "NULL" } {
|
|
153
|
-
puts stderr "\[ERROR\] No instance $
|
|
161
|
+
puts stderr "\[ERROR\] No instance $inst_name found."
|
|
154
162
|
exit 1
|
|
155
163
|
}
|
|
156
164
|
set master_name [[$inst getMaster] getName]
|
|
@@ -163,7 +171,7 @@ foreach side $sides {
|
|
|
163
171
|
place_pad -row [dict get $row_names $side] -location $cur_pos $inst_name -master $master_name
|
|
164
172
|
|
|
165
173
|
# Increment current position
|
|
166
|
-
set cur_pos [expr $cur_pos + $
|
|
174
|
+
set cur_pos [expr $cur_pos + $space_between_pads_multiple + $width]
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
|
|
@@ -175,10 +183,18 @@ place_corners $::env(PAD_CORNER)
|
|
|
175
183
|
puts "\[INFO\] Placing filler cells…"
|
|
176
184
|
|
|
177
185
|
# Place filler cells
|
|
178
|
-
place_io_fill -row IO_NORTH {*}$::env(PAD_FILLERS)
|
|
179
|
-
place_io_fill -row IO_SOUTH {*}$::env(PAD_FILLERS)
|
|
180
|
-
place_io_fill -row IO_WEST {*}$::env(PAD_FILLERS)
|
|
181
|
-
place_io_fill -row IO_EAST {*}$::env(PAD_FILLERS)
|
|
186
|
+
if {!$::env(PAD_TRIM_ROWS) || ($::env(PAD_NORTH) ne "")} { place_io_fill -row IO_NORTH {*}$::env(PAD_FILLERS) }
|
|
187
|
+
if {!$::env(PAD_TRIM_ROWS) || ($::env(PAD_SOUTH) ne "")} { place_io_fill -row IO_SOUTH {*}$::env(PAD_FILLERS) }
|
|
188
|
+
if {!$::env(PAD_TRIM_ROWS) || ($::env(PAD_WEST) ne "")} { place_io_fill -row IO_WEST {*}$::env(PAD_FILLERS) }
|
|
189
|
+
if {!$::env(PAD_TRIM_ROWS) || ($::env(PAD_EAST) ne "")} { place_io_fill -row IO_EAST {*}$::env(PAD_FILLERS) }
|
|
190
|
+
|
|
191
|
+
puts "\[INFO\] Deleting corner cells (if required)…"
|
|
192
|
+
|
|
193
|
+
# Delete corner cells if required
|
|
194
|
+
if {$::env(PAD_TRIM_ROWS) && ($::env(PAD_NORTH) eq "") && ($::env(PAD_WEST) eq "")} { odb::dbInst_destroy [$block findInst IO_CORNER_NORTH_WEST_INST] }
|
|
195
|
+
if {$::env(PAD_TRIM_ROWS) && ($::env(PAD_NORTH) eq "") && ($::env(PAD_EAST) eq "")} { odb::dbInst_destroy [$block findInst IO_CORNER_NORTH_EAST_INST] }
|
|
196
|
+
if {$::env(PAD_TRIM_ROWS) && ($::env(PAD_SOUTH) eq "") && ($::env(PAD_WEST) eq "")} { odb::dbInst_destroy [$block findInst IO_CORNER_SOUTH_WEST_INST] }
|
|
197
|
+
if {$::env(PAD_TRIM_ROWS) && ($::env(PAD_SOUTH) eq "") && ($::env(PAD_EAST) eq "")} { odb::dbInst_destroy [$block findInst IO_CORNER_SOUTH_EAST_INST] }
|
|
182
198
|
|
|
183
199
|
puts "\[INFO\] Connecting ring signals…"
|
|
184
200
|
|
|
@@ -243,3 +259,4 @@ if { [info exists ::env(PAD_PLACE_IO_TERMINALS)] } {
|
|
|
243
259
|
# Remove io rows to avoid causing confusion with the other tools
|
|
244
260
|
puts "\[INFO\] Removing I/O rows…"
|
|
245
261
|
remove_io_rows
|
|
262
|
+
|
|
@@ -139,6 +139,7 @@ if { $::env(PDN_CORE_RING) == 1 } {
|
|
|
139
139
|
append_if_flag arg_list PDN_CORE_RING_ALLOW_OUT_OF_DIE -allow_out_of_die
|
|
140
140
|
append_if_flag arg_list PDN_CORE_RING_CONNECT_TO_PADS -connect_to_pads
|
|
141
141
|
append_if_equals arg_list PDN_EXTEND_TO "boundary" -extend_to_boundary
|
|
142
|
+
append_if_exists_argument arg_list PDN_CORE_RING_CONNECT_TO_PAD_LAYERS -connect_to_pad_layers
|
|
142
143
|
|
|
143
144
|
set pdn_core_vertical_layer $::env(PDN_VERTICAL_LAYER)
|
|
144
145
|
set pdn_core_horizontal_layer $::env(PDN_HORIZONTAL_LAYER)
|
|
@@ -33,12 +33,15 @@ if { $::env(DESIGN_REPAIR_REMOVE_BUFFERS) } {
|
|
|
33
33
|
remove_buffers
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
# Use SYNTH_BUFFER_CELL as buffer, since OpenROAD may select a hold/delay buffer
|
|
37
|
+
# See: https://github.com/librelane/librelane/pull/961
|
|
38
|
+
|
|
36
39
|
if { $::env(DESIGN_REPAIR_BUFFER_INPUT_PORTS) } {
|
|
37
|
-
buffer_ports -inputs
|
|
40
|
+
buffer_ports -inputs -buffer_cell [lindex [split $::env(SYNTH_BUFFER_CELL) "/"] 0]
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
if { $::env(DESIGN_REPAIR_BUFFER_OUTPUT_PORTS) } {
|
|
41
|
-
buffer_ports -outputs
|
|
44
|
+
buffer_ports -outputs -buffer_cell [lindex [split $::env(SYNTH_BUFFER_CELL) "/"] 0]
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
set arg_list [list]
|
|
@@ -157,6 +157,7 @@ def librelane_synth(
|
|
|
157
157
|
):
|
|
158
158
|
|
|
159
159
|
d.run_pass("hierarchy", "-check", "-top", top, "-nokeep_prints", "-nokeep_asserts")
|
|
160
|
+
d.run_pass("chformal", "-remove")
|
|
160
161
|
librelane_proc(d, report_dir)
|
|
161
162
|
|
|
162
163
|
if keep_hierarchy_min_cost:
|
|
@@ -251,12 +252,20 @@ def synthesize(
|
|
|
251
252
|
extra = json.load(open(extra_in))
|
|
252
253
|
|
|
253
254
|
includes = config.get("VERILOG_INCLUDE_DIRS") or []
|
|
254
|
-
defines = (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
255
|
+
defines = (
|
|
256
|
+
(config.get("VERILOG_DEFINES") or [])
|
|
257
|
+
+ [
|
|
258
|
+
f"PDK_{config['PDK'].replace('-','_')}",
|
|
259
|
+
f"SCL_{config['STD_CELL_LIBRARY']}",
|
|
260
|
+
"__librelane__",
|
|
261
|
+
"__pnr__",
|
|
262
|
+
]
|
|
263
|
+
+ (
|
|
264
|
+
[f"PAD_{config['PAD_CELL_LIBRARY']}"]
|
|
265
|
+
if "PAD_CELL_LIBRARY" in config
|
|
266
|
+
else []
|
|
267
|
+
)
|
|
268
|
+
)
|
|
260
269
|
|
|
261
270
|
blackbox_models = extra["blackbox_models"]
|
|
262
271
|
libs = extra["libs_synth"]
|
|
@@ -263,6 +263,12 @@ pdn_variables = [
|
|
|
263
263
|
default=False,
|
|
264
264
|
pdk=True,
|
|
265
265
|
),
|
|
266
|
+
Variable(
|
|
267
|
+
"PDN_CORE_RING_CONNECT_TO_PAD_LAYERS",
|
|
268
|
+
Optional[List[str]],
|
|
269
|
+
"Restrict the pad pins layers to this list.",
|
|
270
|
+
pdk=True,
|
|
271
|
+
),
|
|
266
272
|
Variable(
|
|
267
273
|
"PDN_CORE_RING_ALLOW_OUT_OF_DIE",
|
|
268
274
|
bool,
|
|
@@ -171,7 +171,7 @@ class Render(KLayoutStep):
|
|
|
171
171
|
id = "KLayout.Render"
|
|
172
172
|
name = "Render Image (w/ KLayout)"
|
|
173
173
|
|
|
174
|
-
inputs = [
|
|
174
|
+
inputs = []
|
|
175
175
|
outputs = []
|
|
176
176
|
|
|
177
177
|
config_vars = KLayoutStep.config_vars + [
|
|
@@ -216,10 +216,14 @@ class Render(KLayoutStep):
|
|
|
216
216
|
def run(self, state_in: State, **kwargs) -> Tuple[ViewsUpdate, MetricsUpdate]:
|
|
217
217
|
views_updates: ViewsUpdate = {}
|
|
218
218
|
|
|
219
|
-
input_view = state_in
|
|
219
|
+
input_view = state_in.get(DesignFormat.DEF)
|
|
220
|
+
|
|
220
221
|
if gds := state_in.get(DesignFormat.GDS):
|
|
221
222
|
input_view = gds
|
|
222
223
|
|
|
224
|
+
if input_view is None:
|
|
225
|
+
raise StepError(f"{id} requires at least one of LEF or GDS as input.")
|
|
226
|
+
|
|
223
227
|
assert isinstance(input_view, Path)
|
|
224
228
|
|
|
225
229
|
klayout_render = os.path.join(
|
|
@@ -434,7 +438,7 @@ class DRC(KLayoutStep):
|
|
|
434
438
|
Unlike most steps, the KLayout scripts vary quite wildly by PDK. If a PDK
|
|
435
439
|
is not supported by this step, it will simply be skipped.
|
|
436
440
|
|
|
437
|
-
Currently,
|
|
441
|
+
Currently, sky130, gf180mcu and ihp-sg13 are supported.
|
|
438
442
|
"""
|
|
439
443
|
|
|
440
444
|
id = "KLayout.DRC"
|
|
@@ -455,7 +459,7 @@ class DRC(KLayoutStep):
|
|
|
455
459
|
),
|
|
456
460
|
Variable(
|
|
457
461
|
"KLAYOUT_DRC_OPTIONS",
|
|
458
|
-
Optional[Dict[str, Union[
|
|
462
|
+
Optional[Dict[str, Union[int, bool, str]]],
|
|
459
463
|
"Options passed directly to the KLayout DRC runset. They vary from one PDK to another.",
|
|
460
464
|
pdk=True,
|
|
461
465
|
),
|
|
@@ -513,9 +517,6 @@ class DRC(KLayoutStep):
|
|
|
513
517
|
if threads != "1":
|
|
514
518
|
opts.extend(
|
|
515
519
|
[
|
|
516
|
-
"-rd",
|
|
517
|
-
f"thr={threads}",
|
|
518
|
-
# Use "threads" if possible
|
|
519
520
|
"-rd",
|
|
520
521
|
f"threads={threads}",
|
|
521
522
|
]
|
|
@@ -602,6 +603,8 @@ class DRC(KLayoutStep):
|
|
|
602
603
|
"-rd",
|
|
603
604
|
f"seal={seal}",
|
|
604
605
|
"-rd",
|
|
606
|
+
f"thr={threads}",
|
|
607
|
+
"-rd",
|
|
605
608
|
f"threads={threads}",
|
|
606
609
|
],
|
|
607
610
|
env=env,
|
|
@@ -658,7 +661,7 @@ class DRC(KLayoutStep):
|
|
|
658
661
|
opts.extend(
|
|
659
662
|
[
|
|
660
663
|
"-rd",
|
|
661
|
-
f"
|
|
664
|
+
f"threads={threads}",
|
|
662
665
|
]
|
|
663
666
|
)
|
|
664
667
|
|
|
@@ -727,7 +730,7 @@ class DRC(KLayoutStep):
|
|
|
727
730
|
opts.extend(
|
|
728
731
|
[
|
|
729
732
|
"-rd",
|
|
730
|
-
f"
|
|
733
|
+
f"threads={threads}",
|
|
731
734
|
]
|
|
732
735
|
)
|
|
733
736
|
|
|
@@ -972,7 +972,8 @@ class CellFrequencyTables(OdbpyStep):
|
|
|
972
972
|
kwargs, env = self.extract_env(kwargs)
|
|
973
973
|
|
|
974
974
|
env_copy = env.copy()
|
|
975
|
-
lib_list = self.toolbox.filter_views(self.config, self.config["
|
|
975
|
+
lib_list = self.toolbox.filter_views(self.config, self.config["CELL_LIBS"])
|
|
976
|
+
lib_list += self.toolbox.filter_views(self.config, self.config["PAD_LIBS"])
|
|
976
977
|
env_copy["_PNR_LIBS"] = TclStep.value_to_tcl(lib_list)
|
|
977
978
|
super().run_subprocess(
|
|
978
979
|
[
|
|
@@ -317,7 +317,8 @@ class OpenROADStep(TclStep):
|
|
|
317
317
|
def prepare_env(self, env: dict, state: State) -> dict:
|
|
318
318
|
env = super().prepare_env(env, state)
|
|
319
319
|
|
|
320
|
-
lib_list = self.toolbox.filter_views(self.config, self.config["
|
|
320
|
+
lib_list = self.toolbox.filter_views(self.config, self.config["CELL_LIBS"])
|
|
321
|
+
lib_list += self.toolbox.filter_views(self.config, self.config["PAD_LIBS"])
|
|
321
322
|
lib_list += self.toolbox.get_macro_views(self.config, DesignFormat.LIB)
|
|
322
323
|
|
|
323
324
|
env["_SDC_IN"] = self.config["PNR_SDC_FILE"] or self.config["FALLBACK_SDC"]
|
|
@@ -1266,6 +1267,19 @@ class PadRing(OpenROADStep):
|
|
|
1266
1267
|
Optional[List[str]],
|
|
1267
1268
|
"The pad instance names for the west pad row.",
|
|
1268
1269
|
),
|
|
1270
|
+
Variable(
|
|
1271
|
+
"PAD_SPACING_MULTIPLE",
|
|
1272
|
+
Decimal,
|
|
1273
|
+
"The spacing between the pad cells will be a multiple of this value. Please ensure that the remaining space on the sides is divisible by the minimum site width.",
|
|
1274
|
+
default=1,
|
|
1275
|
+
units="µm",
|
|
1276
|
+
),
|
|
1277
|
+
Variable(
|
|
1278
|
+
"PAD_TRIM_ROWS",
|
|
1279
|
+
bool,
|
|
1280
|
+
"If any of `PAD_[SOUTH|EAST|NORTH|WEST]` is empty, skip io fill for those rows and delete the corners with two neighbouring empty rows.",
|
|
1281
|
+
default=False,
|
|
1282
|
+
),
|
|
1269
1283
|
]
|
|
1270
1284
|
|
|
1271
1285
|
def get_script_path(self):
|
|
@@ -2239,7 +2253,8 @@ class IRDropReport(OpenROADStep):
|
|
|
2239
2253
|
elif len(spefs_in) < 1:
|
|
2240
2254
|
raise StepException("No SPEF file found for the default corner.")
|
|
2241
2255
|
|
|
2242
|
-
libs_in = self.toolbox.filter_views(self.config, self.config["
|
|
2256
|
+
libs_in = self.toolbox.filter_views(self.config, self.config["CELL_LIBS"])
|
|
2257
|
+
libs_in += self.toolbox.filter_views(self.config, self.config["PAD_LIBS"])
|
|
2243
2258
|
|
|
2244
2259
|
if self.config["VSRC_LOC_FILES"] is None:
|
|
2245
2260
|
self.warn(
|