mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
Migrate to a more current version of OpenROAD (#433)
* Initial Set Of Changes + Made openroad binary customizable with OPENROAD_BIN env var: defaults to `openroad` + OL Install allows for customizable flow.tcl for testing + OR Issue now explicitly requires input and output defs as arguments + Updated routing commands - Removed standalone tritonroute - Removed CTS sqr_cap/sqr_rest options (no longer supported) * Partial Merge Of The-OpenROAD-Project/OpenLane#472 Co-authored-by: Osama Hammad <osama21@aucegypt.edu> * Fixed Docker Environment `import opendbpy` -> `opendb` eigen is an archive now Removed Diamond Search Height Completely * Remove Minimum Distance, FP w/ layer numbers (per discussion with @osamahammad21) * Update PDK ~ Install new version of Git to handle Open_PDK's cloning woes ~ Update Commit Hash With Fixes To `download.sh` ~ Address The-OpenROAD-Project/OpenLane#475 while I'm here * Update OpenROAD, Remove Standalone OpenSTA * Remove Standalone OpenDP * Update TritonRoute Invocation + Random Seed Specified + Removed deprecated values from .params file (Not gonna remove .params file just yet) + Updated or_issue.py to handle incomplete file paths * update report layer usage * Makefile Tweaks - Decreased duplication ~ Now using long flags (See #476) * Updates to run_designs, OR commit * number of grt antenna repairer iterations * Update Magic & Netgen for LVS Issue - Remove blabla from completeTestSet pending RTimothyEdwards/netgen#21 + Update Magic and Netgen to same versions as master + Update Readme to replace efabless links with OpenLane ones * Update Magic/Netgen to Latest Versions - Remove usb_cdc_core from fastestTestSet pending RTimothyEdwards/netgen#21 Co-authored-by: Osama Hammad <osama21@aucegypt.edu>
This commit is contained in:
2
.github/test_sets/completeTestSet
vendored
2
.github/test_sets/completeTestSet
vendored
@@ -1 +1 @@
|
||||
wbqspiflash des BM64 aes_cipher picorv32a chacha PPU y_huff blabla ldpcenc salsa20 aes_core sha512 genericfir aes aes128 aes192
|
||||
wbqspiflash des BM64 aes_cipher picorv32a chacha PPU y_huff ldpcenc salsa20 aes_core sha512 genericfir aes aes128 aes192
|
||||
2
.github/test_sets/completeTestSet3
vendored
2
.github/test_sets/completeTestSet3
vendored
@@ -1 +1 @@
|
||||
blabla ldpcenc salsa20 aes_core
|
||||
ldpcenc salsa20 aes_core
|
||||
2
.github/test_sets/fastestTestSet
vendored
2
.github/test_sets/fastestTestSet
vendored
@@ -1 +1 @@
|
||||
spm APU usb xtea usb_cdc_core zipdiv digital_pll_sky130_fd_sc_hd s44 inverter manual_macro_placement_test
|
||||
spm APU usb xtea zipdiv digital_pll_sky130_fd_sc_hd s44 inverter manual_macro_placement_test
|
||||
2
.github/test_sets/fastestTestSet1
vendored
2
.github/test_sets/fastestTestSet1
vendored
@@ -1 +1 @@
|
||||
spm digital_pll_sky130_fd_sc_hd xtea
|
||||
spm digital_pll_sky130_fd_sc_hd
|
||||
2
.github/test_sets/fastestTestSet2
vendored
2
.github/test_sets/fastestTestSet2
vendored
@@ -1 +1 @@
|
||||
usb_cdc_core zipdiv
|
||||
zipdiv xtea
|
||||
@@ -22,6 +22,6 @@ You can invoke `python3 ./ol_install.py`. This tool copies the skeleton and inst
|
||||
|
||||
The tools will all be installed with `/opt/openlane` as a prefix. You'll find all the repos in `/opt/openlane/build/repos` and a list of versions in `/opt/openlane/build/versions`.
|
||||
|
||||
**DO NOTE:** We expect you to bring your own OpenROAD and Opendbpy. You will have to build OpenROAD from source and make Opendbpy available to Python somehow. The repository https://github.com/donn/OpenROAD has a `build_opendbpy.sh` script for your convenience.
|
||||
**DO NOTE:** We expect you to bring your own OpenROAD.
|
||||
|
||||
After the installer is done, you can invoke `sh /opt/openlane/openlane <args>` to use OpenLane, where args are the same arguments you'd pass on to `flow.tcl`.
|
||||
|
||||
49
Makefile
49
Makefile
@@ -50,13 +50,16 @@ INSTALL_SRAM ?= disabled
|
||||
|
||||
IMAGE_NAME ?= efabless/openlane:current
|
||||
TEST_DESIGN ?= spm
|
||||
DESIGN_LIST ?= spm
|
||||
BENCHMARK ?= regression_results/benchmark_results/SW_HD.csv
|
||||
REGRESSION_TAG ?= TEST_SW_HD
|
||||
FASTEST_TEST_SET_TAG ?= FASTEST_TEST_SET
|
||||
PRINT_REM_DESIGNS_TIME ?= 0
|
||||
|
||||
SKYWATER_COMMIT ?= 00bdbcf4a3aa922cc1f4a0d0cd8b80dbd73149d3
|
||||
OPEN_PDKS_COMMIT ?= d8c159536699c9b4a08b650bddf791a9d48152f9
|
||||
OPEN_PDKS_COMMIT ?= 1d93a6bd9d6e481acfdf88f26aa3bb0600303d98
|
||||
|
||||
ENV_COMMAND ?= docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME)
|
||||
|
||||
ifndef PDK_ROOT
|
||||
$(error PDK_ROOT is undefined, please export it before running make)
|
||||
@@ -128,7 +131,7 @@ build-pdk: $(PDK_ROOT)/open_pdks $(PDK_ROOT)/skywater-pdk
|
||||
sleep 5 && \
|
||||
rm -rf $(PDK_ROOT)/sky130A) || \
|
||||
true
|
||||
docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME) sh -c " cd $(PDK_ROOT)/open_pdks && \
|
||||
$(ENV_COMMAND) sh -c " cd $(PDK_ROOT)/open_pdks && \
|
||||
./configure --enable-sky130-pdk=$(PDK_ROOT)/skywater-pdk/libraries --with-sky130-local-path=$(PDK_ROOT) && \
|
||||
cd sky130 && \
|
||||
make veryclean && \
|
||||
@@ -170,25 +173,45 @@ mount:
|
||||
cd $(OPENLANE_DIR) && \
|
||||
docker run -it --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME)
|
||||
|
||||
.PHONY: regression
|
||||
MISC_REGRESSION_ARGS=
|
||||
.PHONY: regression regression_test
|
||||
regression_test: MISC_REGRESSION_ARGS=--benchmark $(BENCHMARK)
|
||||
regression_test: regression
|
||||
regression:
|
||||
cd $(OPENLANE_DIR) && \
|
||||
docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME) sh -c "python3 run_designs.py -dts -dl -tar logs reports -html -t $(REGRESSION_TAG) -th $(THREADS) -p $(PRINT_REM_DESIGNS_TIME)"
|
||||
$(ENV_COMMAND) sh -c "\
|
||||
python3 run_designs.py --delete\
|
||||
--defaultTestSet\
|
||||
--tarList logs reports\
|
||||
--htmlExtract\
|
||||
--tag $(REGRESSION_TAG)\
|
||||
--threads $(THREADS)\
|
||||
--print $(PRINT_REM_DESIGNS_TIME)\
|
||||
$(MISC_REGRESSION_ARGS)\
|
||||
"
|
||||
|
||||
.PHONY: regression_test
|
||||
regression_test:
|
||||
DLTAG=custom_design_List
|
||||
.PHONY: test_design_list fastest_test_set
|
||||
fastest_test_set: DESIGN_LIST=$(shell cat .github/test_sets/fastestTestSet)
|
||||
fastest_test_set: DLTAG=$(FASTEST_TEST_SET_TAG)
|
||||
fastest_test_set: test_design_list
|
||||
test_design_list:
|
||||
cd $(OPENLANE_DIR) && \
|
||||
docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME) sh -c "python3 run_designs.py -dts -dl -tar logs reports -html -t $(REGRESSION_TAG) -b $(BENCHMARK) -th $(THREADS) -p $(PRINT_REM_DESIGNS_TIME)"
|
||||
|
||||
.PHONY: fastest_test_set
|
||||
fastest_test_set:
|
||||
cd $(OPENLANE_DIR) && \
|
||||
docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME) sh -c "python3 run_designs.py -d $(shell cat .github/test_sets/fastestTestSet) -dl -tar logs reports -html -t $(FASTEST_TEST_SET_TAG) -b $(BENCHMARK) -th $(THREADS) -p $(PRINT_REM_DESIGNS_TIME)"
|
||||
$(ENV_COMMAND) sh -c "\
|
||||
python3 run_designs.py --delete\
|
||||
--designs $(DESIGN_LIST)\
|
||||
--tarList logs reports\
|
||||
--htmlExtract\
|
||||
--tag $(DLTAG)\
|
||||
--benchmark $(BENCHMARK)\
|
||||
--threads $(THREADS)\
|
||||
--print $(PRINT_REM_DESIGNS_TIME)\
|
||||
"
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
cd $(OPENLANE_DIR) && \
|
||||
docker run --rm -v $(OPENLANE_DIR):/openLANE_flow -v $(PDK_ROOT):$(PDK_ROOT) -e PDK_ROOT=$(PDK_ROOT) $(DOCKER_UID_OPTIONS) $(IMAGE_NAME) sh -c "./flow.tcl -design $(TEST_DESIGN) -tag openlane_test -disable_output -overwrite"
|
||||
$(ENV_COMMAND) sh -c "./flow.tcl -design $(TEST_DESIGN) -tag openlane_test -disable_output -overwrite"
|
||||
@[ -f $(OPENLANE_DIR)/designs/$(TEST_DESIGN)/runs/openlane_test/results/magic/$(TEST_DESIGN).gds ] && \
|
||||
echo "Basic test passed" || \
|
||||
echo "Basic test failed"
|
||||
|
||||
18
README.md
18
README.md
@@ -10,7 +10,7 @@
|
||||
|
||||
OpenLANE is an automated RTL to GDSII flow based on several components including OpenROAD, Yosys, Magic, Netgen, Fault, OpenPhySyn, CVC, SPEF-Extractor, CU-GR, Klayout and custom methodology scripts for design exploration and optimization. The flow performs full ASIC implementation steps from RTL all the way down to GDSII - this capability will be released in the coming weeks with completed SoC design examples that have been sent to SkyWater for fabrication.
|
||||
|
||||
You can find the latest release of OpenLANE [here](https://github.com/efabless/openlane/releases).
|
||||
You can find the latest release of OpenLANE [here](https://github.com/The-OpenROAD-Project/OpenLane/releases).
|
||||
|
||||
This documentation is also available at [ReadTheDocs](https://openlane.readthedocs.io/).
|
||||
|
||||
@@ -39,8 +39,7 @@ This documentation is also available at [ReadTheDocs](https://openlane.readthedo
|
||||
- [Videos And Tutorials](#videos-and-tutorials)
|
||||
|
||||
# Prerequisites
|
||||
|
||||
- Docker 19.03.12+
|
||||
- Docker 19.03.12+
|
||||
|
||||
## Dockerless Install
|
||||
Please see [LOCAL_INSTALL.md](./LOCAL_INSTALL.md).
|
||||
@@ -49,7 +48,7 @@ Please see [LOCAL_INSTALL.md](./LOCAL_INSTALL.md).
|
||||
You can start setting up the skywater-pdk and openlane by running:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/efabless/openlane.git
|
||||
git clone https://github.com/The-OpenROAD-Project/OpenLane.git
|
||||
cd openlane/
|
||||
make openlane
|
||||
# Default PDK_ROOT is $(pwd)/pdks. If you want to install the PDK at a differnt location, uncomment the next line.
|
||||
@@ -68,7 +67,7 @@ To run the regression test, which tests the flow against all available designs u
|
||||
make regression_test
|
||||
```
|
||||
|
||||
Your results will be compared with: [sky130_fd_sc_hd](https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HD.csv).
|
||||
Your results will be compared with: [sky130_fd_sc_hd](https://github.com/The-OpenROAD-Project/OpenLane/blob/master/regression_results/benchmark_results/SW_HD.csv).
|
||||
|
||||
After running you'll find a directory added under [./regression_results/](./regression_results) it will contain all the reports needed for you to know whether you've been successful or not. Check [this](./regression_results/README.md#output) for more details.
|
||||
|
||||
@@ -128,7 +127,7 @@ This should install the latest openlane docker container, and re-install the pdk
|
||||
To setup openlane you can pull the docker container following these instructions:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/efabless/openlane.git
|
||||
git clone https://github.com/The-OpenROAD-Project/OpenLane.git
|
||||
docker pull efabless/openlane:current
|
||||
```
|
||||
|
||||
@@ -176,7 +175,7 @@ Use the following example to check the overall setup:
|
||||
|
||||
To run OpenLANE on multiple designs at the same time, check this [section](#regression-and-design-configurations-exploration).
|
||||
|
||||
Having trouble running the flow? check [FAQs](https://github.com/efabless/openlane/wiki)
|
||||
Having trouble running the flow? check [FAQs](https://github.com/The-OpenROAD-Project/OpenLane/wiki)
|
||||
|
||||
## Command line arguments
|
||||
|
||||
@@ -545,10 +544,9 @@ To check the original author list of OpenLANE, check [this][33].
|
||||
# Additional Material
|
||||
|
||||
## Papers
|
||||
|
||||
- Ahmed Ghazy and Mohamed Shalan, "OpenLane: The Open-Source Digital ASIC Implementation Flow", Article No.21, Workshop on Open-Source EDA Technology (WOSET), 2020. [Paper](https://github.com/woset-workshop/woset-workshop.github.io/blob/master/PDFs/2020/a21.pdf)
|
||||
- M. Shalan and T. Edwards, "Building OpenLANE: A 130nm OpenROAD-based Tapeout- Proven Flow : Invited Paper," 2020 IEEE/ACM International Conference On Computer Aided Design (ICCAD), San Diego, CA, USA, 2020, pp. 1-6.
|
||||
- R. Timothy Edwards, M. Shalan and M. Kassem, "Real Silicon using Open Source EDA," in IEEE Design & Test, doi: 10.1109/MDAT.2021.3050000.
|
||||
- M. Shalan and T. Edwards, "Building OpenLANE: A 130nm OpenROAD-based Tapeout- Proven Flow : Invited Paper," 2020 IEEE/ACM International Conference On Computer Aided Design (ICCAD), San Diego, CA, USA, 2020, pp. 1-6. [Paper](https://ieeexplore.ieee.org/document/9256623/)
|
||||
- R. Timothy Edwards, M. Shalan and M. Kassem, "Real Silicon using Open Source EDA," in IEEE Design & Test, doi: 10.1109/MDAT.2021.3050000. [Paper](https://ieeexplore.ieee.org/document/9336682)
|
||||
|
||||
## Videos and Tutorials
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/tclsh8.5
|
||||
#!/usr/bin/tclsh
|
||||
# Copyright 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -72,7 +72,7 @@ These variables are optional that can be specified in the design configuration f
|
||||
| `FP_IO_HLENGTH` | The length of the horizontal IOs in microns. <br> (Default: `4`) |
|
||||
| `FP_IO_VTHICKNESS_MULT` | A multiplier for vertical pin thickness. Base thickness is the pins layer minwidth <br> (Default: `2`) |
|
||||
| `FP_IO_HTHICKNESS_MULT` | A multiplier for horizontal pin thickness. Base thickness is the pins layer minwidth <br> (Default: `2`) |
|
||||
| `FP_IO_MIN_DISTANCE` | The minmimum distance between the IOs in microns. <br> (Default: `5`) |
|
||||
| `FP_IO_MIN_DISTANCE` | This option has been removed and has no effect. |
|
||||
| `BOTTOM_MARGIN_MULT` | The core margin, in multiples of site heights, from the bottom boundary. <br> (Default: `4`) |
|
||||
| `TOP_MARGIN_MULT` | The core margin, in multiples of site heights, from the top boundary. <br> (Default: `4`) |
|
||||
| `LEFT_MARGIN_MULT` | The core margin, in multiples of site widths, from the left boundary. <br> (Default: `12`) |
|
||||
@@ -113,10 +113,10 @@ These variables are optional that can be specified in the design configuration f
|
||||
| `LIB_RESIZER_OPT` | Points to the lib file, corresponding to the slowest corner, for max delay calculation during resizer optimizations. This is copy of `LIB_SLOWEST`. <br> Default: `$::env(TMP_DIR)/resizer.lib` |
|
||||
| `DONT_USE_CELLS` | The list of cells to not use during resizer optimizations. <br> Default: the contents of `DRC_EXCLUDE_CELL_LIST`. |
|
||||
| `PL_ESTIMATE_PARASITICS` | Specifies whether or not to run STA after global placement using OpenROAD's estimate_parasitics -placement and generates reports under `logs/placement`. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `PL_DIAMOND_SEARCH_HEIGHT` | Specifies the diamond search height used for legalizing the cells during detailed placement. The search width is calculated internally as `heigh*5`. For designs that contain big macros, increasing this value to above 400 will allow for more search space and more potentail for successful legalization. <br> (Default: `100`) |
|
||||
| `PL_OPTIMIZE_MIRRORING` | Specifies whether or not to run an optimize_mirroring pass whenever detailed placement happens. This pass will mirror the cells whenever possible to optimize the design. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `PL_RESIZER_BUFFER_INPUT_PORTS` | Specifies whether or not to insert buffers on input ports whenever resizer optimizations are run. For this to be used, `PL_RESIZER_DESIGN_OPTIMIZATIONS` must be set to 1. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `PL_RESIZER_BUFFER_OUTPUT_PORTS` | Specifies whether or not to insert buffers on output ports whenever resizer optimizations are run. For this to be used, `PL_RESIZER_DESIGN_OPTIMIZATIONS` must be set to 1. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `PL_DIAMOND_SEARCH_HEIGHT` | This option has been removed and has no effect. |
|
||||
|
||||
### CTS
|
||||
|
||||
@@ -147,6 +147,7 @@ These variables are optional that can be specified in the design configuration f
|
||||
| `GLB_RT_UNIDIRECTIONAL` | Allow unidirectional routing. 0 = false, 1 = true <br> (Default: `1`) |
|
||||
| `GLB_RT_ALLOW_CONGESTION` | Allow congestion in the resultign guides. 0 = false, 1 = true <br> (Default: `0`) |
|
||||
| `GLB_RT_OVERFLOW_ITERS` | The maximum number of iterations waiting for the overflow to reach the desired value. <br> (Default: `50`) |
|
||||
| `GLB_RT_ANT_ITERS` | The maximum number of iterations for global router repair_antenna. This option is only available in `DIODE_INSERTION_STRATEGY` = `3`. <br> (Default: `3`) |
|
||||
| `GLB_RT_TILES` | The size of the GCELL used by Fastroute during global routing. <br> (Default: `15`) |
|
||||
| `GLB_RT_ESTIMATE_PARASITICS` | Specifies whether or not to run STA after global routing using OpenROAD's estimate_parasitics -global_routing and generates reports under `logs/routing`. 1 = Enabled, 0 = Disabled. <br> (Default: `1`) |
|
||||
| `ROUTING_CORES` | Specifies the number of threads to be used in TritonRoute. <br> (Default: `4`) |
|
||||
@@ -154,7 +155,7 @@ These variables are optional that can be specified in the design configuration f
|
||||
| `GLB_RT_OBS` | Specifies custom obstruction to be added prior to global routing. Comma separated list of layer and coordinates: `layer llx lly urx ury`.<br> (Example: `li1 0 100 1000 300, met5 0 0 1000 500`) <br> (Default: unset) |
|
||||
| `ROUTING_OPT_ITERS` | Specifies the maximum number of optimization iterations during Detailed Routing in TritonRoute. <br> (Default: `64`) |
|
||||
| `GLOBAL_ROUTER` | Specifies which global router to use. Values: `fastroute` or `cugr`. <br> (Default: `fastroute`) |
|
||||
| `DETAILED_ROUTER` | Specifies which detailed router to use. Values: `tritonroute`, `tritonroute_or`, or `drcu`. <br> (Default: `tritonroute`) |
|
||||
| `DETAILED_ROUTER` | Specifies which detailed router to use. Values: `tritonroute`, `tritonroute_or` (identical to `tritonroute`, deprecated) or `drcu`. <br> (Default: `tritonroute`)|
|
||||
|
||||
### Magic
|
||||
|
||||
|
||||
@@ -49,5 +49,6 @@ set ::env(RIGHT_MARGIN_MULT) 12
|
||||
|
||||
set ::env(FP_HORIZONTAL_HALO) 10
|
||||
set ::env(FP_VERTICAL_HALO) $::env(FP_HORIZONTAL_HALO)
|
||||
set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) 1
|
||||
|
||||
set ::env(DESIGN_IS_CORE) 1
|
||||
|
||||
@@ -24,7 +24,6 @@ set ::env(PL_OPENPHYSYN_OPTIMIZATIONS) 0
|
||||
set ::env(PSN_ENABLE_RESIZING) 1
|
||||
set ::env(PSN_ENABLE_PIN_SWAP) 1
|
||||
set ::env(PL_ESTIMATE_PARASITICS) 1
|
||||
set ::env(PL_DIAMOND_SEARCH_HEIGHT) 100
|
||||
set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 1
|
||||
set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1
|
||||
set ::env(PL_RESIZER_MAX_WIRE_LENGTH) 0
|
||||
|
||||
@@ -21,12 +21,11 @@ set ::env(GLB_RT_L3_ADJUSTMENT) 0
|
||||
set ::env(GLB_RT_L4_ADJUSTMENT) 0
|
||||
set ::env(GLB_RT_L5_ADJUSTMENT) 0
|
||||
set ::env(GLB_RT_L6_ADJUSTMENT) 0; # We go up to 6 here because the lowest met layer we've dealt with was met5, starting from li1. This might need to be adjusted.
|
||||
set ::env(GLB_RT_UNIDIRECTIONAL) 1
|
||||
set ::env(GLB_RT_ALLOW_CONGESTION) 0
|
||||
set ::env(GLB_RT_OVERFLOW_ITERS) 50
|
||||
set ::env(GLB_RT_MINLAYER) 1
|
||||
set ::env(GLB_RT_MAXLAYER) 6
|
||||
set ::env(GLB_RT_TILES) 15 ; # openroads fastroute default value
|
||||
set ::env(GLB_RT_ANT_ITERS) 3
|
||||
|
||||
set ::env(GLB_RT_ESTIMATE_PARASITICS) 1
|
||||
|
||||
|
||||
33
dependencies/tool_metadata.py
vendored
33
dependencies/tool_metadata.py
vendored
@@ -106,17 +106,6 @@ Tool(
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"opendp",
|
||||
install_command="\
|
||||
mkdir -p ./build &&\
|
||||
cd ./build &&\
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX .. &&\
|
||||
make -j$(nproc) &&\
|
||||
make install\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"openphysyn",
|
||||
install_command="\
|
||||
@@ -140,17 +129,6 @@ Tool(
|
||||
skip=True
|
||||
)
|
||||
|
||||
Tool(
|
||||
"opensta",
|
||||
install_command="\
|
||||
mkdir -p ./build &&\
|
||||
cd ./build &&\
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$PREFIX/bin .. &&\
|
||||
make -j$(nproc) &&\
|
||||
cp ../app/sta $PREFIX/bin\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"padring",
|
||||
install_command="\
|
||||
@@ -161,17 +139,6 @@ Tool(
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"tritonroute",
|
||||
install_command="\
|
||||
mkdir -p build &&\
|
||||
cd build &&\
|
||||
cmake .. &&\
|
||||
make -j$(nproc) &&\
|
||||
cp TritonRoute $PREFIX/bin\
|
||||
"
|
||||
)
|
||||
|
||||
Tool(
|
||||
"qflow", # We just want vlog_to_verilog though
|
||||
install_command="\
|
||||
|
||||
@@ -10,7 +10,7 @@ set ::env(CLOCK_PORT) ""
|
||||
|
||||
|
||||
set ::env(PL_SKIP_INITIAL_PLACEMENT) 1
|
||||
set ::env(PL_RANDOM_GLB_PLACEMENT) 1
|
||||
set ::env(PL_RANDOM_GLB_PLACEMENT) 0
|
||||
|
||||
set ::env(FP_SIZING) absolute
|
||||
set ::env(DIE_AREA) "0 0 34.165 54.885"
|
||||
|
||||
@@ -3,6 +3,17 @@ set ::ground_nets $::env(GND_PIN)
|
||||
|
||||
set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
|
||||
|
||||
set pdngen::global_connections {
|
||||
VPWR {
|
||||
{inst_name .* pin_name VPWR}
|
||||
{inst_name .* pin_name VPB}
|
||||
}
|
||||
VGND {
|
||||
{inst_name .* pin_name VGND}
|
||||
{inst_name .* pin_name VNB}
|
||||
}
|
||||
}
|
||||
|
||||
pdngen::specify_grid stdcell {
|
||||
name grid
|
||||
rails {
|
||||
@@ -12,6 +23,7 @@ pdngen::specify_grid stdcell {
|
||||
met4 {width $::env(FP_PDN_VWIDTH) pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
|
||||
}
|
||||
connect {{met1 met4}}
|
||||
pins {met4}
|
||||
}
|
||||
|
||||
set ::halo 0
|
||||
|
||||
@@ -6,6 +6,7 @@ set ::env(VERILOG_FILES) [glob ./designs/spm/src/*.v]
|
||||
set ::env(CLOCK_PERIOD) "10.000"
|
||||
set ::env(CLOCK_PORT) "clk"
|
||||
set ::env(CELL_PAD) 4
|
||||
set ::env(RUN_SPEF_EXTRACTION) 0
|
||||
|
||||
# set ::env(FP_PIN_ORDER_CFG) $::env(OPENLANE_ROOT)/designs/spm/pin_order.cfg
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ RUN alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 60
|
||||
RUN pip3.6 install --no-cache-dir --upgrade pip
|
||||
RUN pip install --no-cache-dir \
|
||||
matplotlib \
|
||||
jinja2 \
|
||||
"jinja2<3.0.0" \
|
||||
pandas \
|
||||
install \
|
||||
XlsxWriter
|
||||
@@ -75,6 +75,11 @@ ADD ./klayout.tar.gz /
|
||||
RUN yum localinstall -y /build/klayout-*.rpm
|
||||
|
||||
# install TclX package for Tcl to handle process interrupts
|
||||
|
||||
# Update GIT
|
||||
RUN yum install -y https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm && \
|
||||
yum install -y git
|
||||
|
||||
RUN yum install -y tclx
|
||||
ARG CACHE_INVALIDATOR=1
|
||||
RUN echo "$CACHE_INVALIDATOR"
|
||||
@@ -85,12 +90,11 @@ COPY ./.tclshrc /root
|
||||
|
||||
ADD ./openLANE_flow.tar.gz $OPENLANE_ROOT
|
||||
|
||||
|
||||
# install opendb python
|
||||
RUN cd $OPENROAD/OpenDB_python/ && \
|
||||
python3 setup.py install && \
|
||||
rm -rf $OPENROAD/OpenDB_python
|
||||
|
||||
WORKDIR $OPENLANE_ROOT
|
||||
|
||||
ENV OPENROAD_BIN openroad
|
||||
|
||||
RUN git config --global user.name "OpenLane User"
|
||||
RUN git config --global user.email "openlane.user@localhost"
|
||||
|
||||
CMD /bin/bash
|
||||
|
||||
@@ -4,7 +4,7 @@ DOCKERFILE_PATH ?= ./Dockerfile
|
||||
IMAGE_NAME ?= efabless/openlane:current
|
||||
#ROOT = sudo
|
||||
|
||||
TOOLS = klayout opendp route cugr drcu opensta yosys antmicro_yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
TOOLS = klayout cugr drcu yosys antmicro_yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
|
||||
TOOL_BUILD_TARGETS = $(foreach tool,$(TOOLS),build-$(tool))
|
||||
TOOL_EXPORT_TARGETS_PHONY = $(foreach tool,$(TOOLS),export-$(tool))
|
||||
|
||||
@@ -39,7 +39,7 @@ make build-<tool>
|
||||
The following are the available tools:
|
||||
|
||||
```bash
|
||||
klayout replace opendp route cugr drcu opensta yosys antmicro_yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
klayout cugr drcu yosys magic openroad_app padring netgen vlogtoverilog openphysyn cvc
|
||||
```
|
||||
|
||||
### Rebuilding
|
||||
|
||||
@@ -31,7 +31,7 @@ RUN yum install -y mesa-libGLU-devel csh wget tcl-devel tk-devel libX11-devel ca
|
||||
# git clone magic components
|
||||
# Upstream is git://opencircuitdesign.com/magic, but servers are not stable enough for CI.
|
||||
ARG MAGIC_REPO=https://github.com/rtimothyedwards/magic
|
||||
ARG MAGIC_COMMIT=e403e9201778179e70a7e7a7067bc96aa781bb2d
|
||||
ARG MAGIC_COMMIT=958d6f16701c1ee25e27440381b5c2c37b5fee7c
|
||||
RUN git clone ${MAGIC_REPO} magic_21012020
|
||||
|
||||
WORKDIR magic_21012020
|
||||
|
||||
@@ -26,7 +26,7 @@ RUN yum install -y csh wget tcl-devel tk-devel libX11-devel cairo-devel ncurses-
|
||||
# git clone netgen components
|
||||
# Upstream is git://opencircuitdesign.com/netgen, but servers are not stable enough for CI.
|
||||
ARG NETGEN_REPO=https://github.com/rtimothyedwards/netgen
|
||||
ARG NETGEN_COMMIT=01b2484be3008f89aa5e87fd265c79ef0c83e9a6
|
||||
ARG NETGEN_COMMIT=738c1f7b3705bca2f1cc66fbc1cfb20f12d49a06
|
||||
RUN git clone ${NETGEN_REPO} netgen_21012021
|
||||
|
||||
WORKDIR netgen_21012021
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# syntax = docker/dockerfile:1.0-experimental
|
||||
FROM centos:centos7 as build
|
||||
|
||||
|
||||
# install gcc 6
|
||||
RUN yum -y install centos-release-scl && \
|
||||
yum -y install devtoolset-7 devtoolset-7-libatomic-devel
|
||||
ENV CC=/opt/rh/devtoolset-7/root/usr/bin/gcc \
|
||||
CPP=/opt/rh/devtoolset-7/root/usr/bin/cpp \
|
||||
CXX=/opt/rh/devtoolset-7/root/usr/bin/g++ \
|
||||
PATH=/opt/rh/devtoolset-7/root/usr/bin:$PATH \
|
||||
LD_LIBRARY_PATH=/opt/rh/devtoolset-7/root/usr/lib64:/opt/rh/devtoolset-7/root/usr/lib:/opt/rh/devtoolset-7/root/usr/lib64/dyninst:/opt/rh/devtoolset-7/root/usr/lib/dyninst:/opt/rh/devtoolset-7/root/usr/lib64:/opt/rh/devtoolset-7/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
# Common development tools and libraries (kitchen sink approach)
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
|
||||
RUN yum -y install wget zlib-devel
|
||||
|
||||
RUN wget https://cmake.org/files/v3.9/cmake-3.9.0-Linux-x86_64.sh && \
|
||||
chmod +x cmake-3.9.0-Linux-x86_64.sh && \
|
||||
./cmake-3.9.0-Linux-x86_64.sh --skip-license --prefix=/usr/local
|
||||
|
||||
|
||||
# download public key for github.com
|
||||
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
|
||||
ARG OPENDP_REPO=https://github.com/kareefardi/OpenDP
|
||||
ARG OPENDP_COMMIT=a8b63757bc393ca7c9841a0999e00deabf675f4f
|
||||
RUN git clone --recursive ${OPENDP_REPO}
|
||||
WORKDIR /OpenDP
|
||||
RUN git checkout ${OPENDP_COMMIT}
|
||||
|
||||
RUN mkdir /OpenDP/build
|
||||
WORKDIR /OpenDP/build
|
||||
|
||||
RUN cmake ..
|
||||
|
||||
RUN make && \
|
||||
make install
|
||||
|
||||
RUN mkdir -p /build/bin/ && \
|
||||
cp opendp /build/bin
|
||||
|
||||
RUN mkdir -p /build/version
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/opendp.version
|
||||
RUN git rev-parse HEAD >> /build/version/opendp.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
|
||||
@@ -16,8 +16,7 @@ FROM centos:centos7 AS base-dependencies
|
||||
|
||||
# Install Development Environment
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum group install -y "Development Tools" \
|
||||
&& yum install -y https://repo.ius.io/ius-release-el7.rpm \
|
||||
RUN yum install -y https://repo.ius.io/ius-release-el7.rpm \
|
||||
&& yum install -y centos-release-scl \
|
||||
&& yum install -y wget devtoolset-8 \
|
||||
devtoolset-8-libatomic-devel tcl-devel tcl tk libstdc++ tk-devel pcre-devel \
|
||||
@@ -80,8 +79,9 @@ RUN yum -y install zlib-devel
|
||||
|
||||
|
||||
# eigen required by replace, TritonMacroPlace
|
||||
RUN git clone https://gitlab.com/libeigen/eigen --branch=3.3 \
|
||||
RUN mkdir -p eigen \
|
||||
&& cd eigen \
|
||||
&& curl -L https://gitlab.com/libeigen/eigen/-/archive/3.3/eigen-3.3.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& cmake .. \
|
||||
@@ -114,10 +114,10 @@ RUN git clone -b v1.8.1 https://github.com/gabime/spdlog \
|
||||
&& cmake .. \
|
||||
&& make install -j
|
||||
|
||||
ARG OPENROAD_APP_REPO=https://github.com/donn/OpenROAD
|
||||
ARG OPENROAD_APP_COMMIT=0c586ccc11128f067a9e0c843be7384e21b01f55
|
||||
RUN git clone --recursive ${OPENROAD_APP_REPO} OpenROAD_10012020
|
||||
WORKDIR /OpenROAD_10012020/
|
||||
ARG OPENROAD_APP_REPO=https://github.com/The-OpenROAD-Project/OpenROAD
|
||||
ARG OPENROAD_APP_COMMIT=4d4d7205fd0292dbf3fae55fad9109b3f0bd5786
|
||||
RUN git clone ${OPENROAD_APP_REPO} OpenROAD_Repo
|
||||
WORKDIR /OpenROAD_Repo/
|
||||
RUN git checkout ${OPENROAD_APP_COMMIT}
|
||||
RUN git submodule update --init --recursive
|
||||
|
||||
@@ -127,13 +127,6 @@ RUN cd build && cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/install .. && make -j$(nproc
|
||||
RUN cd build && make install
|
||||
RUN cp -r build/install/bin /build/
|
||||
|
||||
# OpenDB Python interface
|
||||
WORKDIR src/OpenDB
|
||||
RUN mkdir build && mkdir -p /build/version && mkdir install
|
||||
RUN cd build && cmake -DCMAKE_CXX_STANDARD=17 -DCMAKE_INSTALL_PREFIX=$(pwd)/install .. && make -j$(nproc) opendbpy
|
||||
RUN cp -r build/src/swig/python /build/OpenDB_python
|
||||
WORKDIR /OpenROAD_10012020/
|
||||
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/openroad.version
|
||||
RUN git rev-parse HEAD >> /build/version/openroad.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
# Copyright 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# syntax = docker/dockerfile:1.0-experimental
|
||||
FROM centos:centos7 as build
|
||||
|
||||
|
||||
# Install Development Environment
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum install -y wget git
|
||||
RUN yum -y install centos-release-scl && \
|
||||
yum -y install devtoolset-8 devtoolset-8-libatomic-devel
|
||||
RUN wget https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh && \
|
||||
chmod +x cmake-3.14.0-Linux-x86_64.sh && \
|
||||
./cmake-3.14.0-Linux-x86_64.sh --skip-license --prefix=/usr/local
|
||||
|
||||
ENV CC=/opt/rh/devtoolset-8/root/usr/bin/gcc \
|
||||
CPP=/opt/rh/devtoolset-8/root/usr/bin/cpp \
|
||||
CXX=/opt/rh/devtoolset-8/root/usr/bin/g++ \
|
||||
PATH=/opt/rh/devtoolset-8/root/usr/bin:$PATH \
|
||||
LD_LIBRARY_PATH=/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
# update bison
|
||||
RUN yum -y remove bison
|
||||
RUN wget https://ftp.gnu.org/gnu/bison/bison-3.0.5.tar.gz && \
|
||||
tar -xvzf bison-3.0.5.tar.gz
|
||||
RUN cd bison-3.0.5 && \
|
||||
./configure --prefix=/usr && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
|
||||
RUN yum remove -y swig \
|
||||
&& yum install -y pcre-devel \
|
||||
&& wget https://github.com/swig/swig/archive/rel-3.0.12.tar.gz \
|
||||
&& tar xfz rel-3.0.12.tar.gz \
|
||||
&& rm -rf rel-3.0.12.tar.gz \
|
||||
&& cd swig-rel-3.0.12 \
|
||||
&& ./autogen.sh && ./configure --prefix=/usr && make -j $(nproc) && make install
|
||||
|
||||
RUN yum -y install zlib-devel flex
|
||||
|
||||
# download CUDD
|
||||
RUN wget https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz && \
|
||||
tar -xvf cudd-3.0.0.tar.gz && \
|
||||
cd cudd-3.0.0 && \
|
||||
./configure && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
RUN yum install -d6 -y tcl-devel tcl
|
||||
|
||||
ARG OPENSTA_REPO=https://github.com/The-OpenROAD-Project/OpenSTA
|
||||
ARG OPENSTA_COMMIT=6deaf6d8fcabc884063941c3046eb8bdb80061b5
|
||||
|
||||
RUN git clone ${OPENSTA_REPO}
|
||||
|
||||
WORKDIR OpenSTA
|
||||
|
||||
RUN git checkout ${OPENSTA_COMMIT}
|
||||
|
||||
RUN mkdir /build
|
||||
RUN mkdir build
|
||||
WORKDIR build
|
||||
RUN cmake -DCMAKE_INSTALL_PREFIX=/build -DCUDD=/usr/local ..
|
||||
|
||||
RUN make -j$(nproc)
|
||||
|
||||
RUN mkdir -p /build/bin/ && \
|
||||
cp ../app/sta /build/bin
|
||||
|
||||
RUN mkdir -p /build/version
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/opensta.version
|
||||
RUN git rev-parse HEAD >> /build/version/opensta.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
@@ -1,80 +0,0 @@
|
||||
# Copyright 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# syntax = docker/dockerfile:1.0-experimental
|
||||
FROM centos:centos7 as build
|
||||
|
||||
# # install gcc 8
|
||||
RUN yum -y install centos-release-scl && \
|
||||
yum -y install devtoolset-8 devtoolset-8-libatomic-devel
|
||||
ENV CC=/opt/rh/devtoolset-8/root/usr/bin/gcc \
|
||||
CPP=/opt/rh/devtoolset-8/root/usr/bin/cpp \
|
||||
CXX=/opt/rh/devtoolset-8/root/usr/bin/g++ \
|
||||
PATH=/opt/rh/devtoolset-8/root/usr/bin:$PATH \
|
||||
LD_LIBRARY_PATH=/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:/opt/rh/devtoolset-8/root/usr/lib64/dyninst:/opt/rh/devtoolset-8/root/usr/lib/dyninst:/opt/rh/devtoolset-8/root/usr/lib64:/opt/rh/devtoolset-8/root/usr/lib:$LD_LIBRARY_PATH
|
||||
|
||||
RUN yum install -y wget git pcre-devel tcl-devel tk-devel bison flex \
|
||||
python-devel libxml2-devel libxslt-devel zlib-static glibc-static
|
||||
|
||||
RUN wget http://prdownloads.sourceforge.net/swig/swig-4.0.0.tar.gz && \
|
||||
tar -xf swig-4.0.0.tar.gz && \
|
||||
cd swig-4.0.0 && \
|
||||
./configure && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
|
||||
|
||||
# Installing cmake for build dependency
|
||||
RUN wget https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh && \
|
||||
chmod +x cmake-3.14.0-Linux-x86_64.sh && \
|
||||
./cmake-3.14.0-Linux-x86_64.sh --skip-license --prefix=/usr/local
|
||||
|
||||
RUN yum -y remove bison
|
||||
RUN wget https://ftp.gnu.org/gnu/bison/bison-3.0.5.tar.gz && \
|
||||
tar -xvzf bison-3.0.5.tar.gz
|
||||
RUN cd bison-3.0.5 && \
|
||||
./configure --prefix=/usr && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
|
||||
RUN yum -y install bzip2
|
||||
# Installing boost for build dependency
|
||||
RUN wget https://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.bz2/download && \
|
||||
tar -xf download && \
|
||||
cd boost_1_72_0 && \
|
||||
./bootstrap.sh && \
|
||||
./b2 install --with-iostreams --with-test link=shared -j $(nproc)
|
||||
|
||||
# download public key for github.com
|
||||
#RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||
ARG TRITONROUTE_REPO=https://github.com/The-OpenROAD-Project/TritonRoute
|
||||
ARG TRITONROUTE_COMMIT=a639a8b8c99fb078057d8449aa57333952b06309
|
||||
RUN git clone ${TRITONROUTE_REPO} TritonRoute_26102020 \
|
||||
&& cd TritonRoute_26102020 \
|
||||
&& git checkout ${TRITONROUTE_COMMIT}
|
||||
|
||||
RUN mkdir TritonRoute_26102020/build
|
||||
|
||||
WORKDIR TritonRoute_26102020/build
|
||||
|
||||
RUN cmake ../
|
||||
RUN make -j$(nproc)
|
||||
|
||||
RUN mkdir -p /build/bin/ && \
|
||||
cp TritonRoute /build/bin/TritonRoute
|
||||
|
||||
RUN mkdir -p /build/version
|
||||
RUN date +"Build Timestamp: %Y-%m-%d_%H-%M-%S" > /build/version/route_14.version
|
||||
RUN git rev-parse HEAD >> /build/version/route_14.version
|
||||
RUN tar -czf /build.tar.gz /build
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -175,11 +175,11 @@ Most of the following commands' implementation exists in this [file][7]
|
||||
|
||||
| Command | Flags | Description |
|
||||
|---------------|------------------------|-----------------------------------------|
|
||||
| `global_placement_or` | | Runs global placement on the processed design using the openroad app. The resulting file is under `/<run_path>/tmp/placement/` . |
|
||||
| `global_placement` | | Runs global placement on the processed design using RePlace. The resulting file is under `/<run_path>/tmp/placement/` . |
|
||||
| `random_global_placement` | | Runs random global placement using a custom opendp based script. Useful in designs that contains a very few cells or macros only. The resulting file is under `/<run_path>/tmp/placement/`. |
|
||||
| `detailed_placement_or` | | Runs detailed placement on the processed design using the openroad app. The resulting file is under `/<run_path>/results/placement/` . |
|
||||
| `detailed_placement` | | Runs detailed placement on the processed design using OpenDP. The resulting file is under `/<run_path>/results/placement/` . |
|
||||
| `global_placement_or` | | Runs global placement on the processed design using OpenROAD. The resulting file is under `/<run_path>/tmp/placement/` . |
|
||||
| `global_placement` | Alias for `global_placement_or`. |
|
||||
| `random_global_placement` | | Runs random global placement using a custom OpenROAD-based script. Useful for tiny designs. The resulting file is under `/<run_path>/tmp/placement/`. |
|
||||
| `detailed_placement_or` | | Runs detailed placement on the processed design using OpenROAD. The resulting file is under `/<run_path>/results/placement/` . |
|
||||
| `detailed_placement` | | Alias for `detailed_placement_or`. |
|
||||
| `add_macro_placement <macro_name> <x_coordinate> <y_coordinate> [<orientation>]` | | Writes a configuration file to be processed by `manual_macro_placement` by setting the initial placement of the macro `<macro_name>` to location (`<x_coordinate>`,`<y_coordinate>`) on the chip with the option of specifying the `<orientation>` as well. The line written will be appened to this configuration file `/run_path/tmp/macro_placements.cfg`. |
|
||||
| `manual_macro_placement [f]` | | Uses the configuration file generated by `add_macro_placement` (`/run_path/tmp/macro_placements.cfg`) to manually initialize the placement of the macros to the locations determined in the file. It works on the currently processed design and it overwrites the `CURRENT_DEF`. if `f` is passed as the first argument, the placement will be fixed and final, and the placement tools will not be allowed to change it.|
|
||||
| `basic_macro_placement` | | Runs basic macro placement on the chip level using the openroad app, and it writes into `::env(CURRENT_DEF).macro_placement.def`. |
|
||||
@@ -243,8 +243,8 @@ Most of the following commands' implementation exists in this [file][8]
|
||||
| `global_routing` | | Runs global routing on the processed design using either the openroad app's fastroute or cugr based on the value of `GLOBAL_ROUTER`. The resulting file is under `/<run_path>/tmp/routing/` . |
|
||||
| `global_routing_fastroute` | | Runs global routing on the processed design using the openroad app's fastroute. The resulting file is under `/<run_path>/tmp/routing/` . |
|
||||
| `global_routing_cugr` | | Runs global routing on the processed design using cugr. The resulting file is under `/<run_path>/tmp/routing/` . |
|
||||
| `detailed_routing` | | Runs detailed routing on the processed design using TritonRoute (standalone), TritonRoute (OpenROAD), or DRCU based onthe value of `DETAILED_ROUTER`. The resulting file is under `/<run_path>/results/routing/` . |
|
||||
| `detailed_routing_tritonroute` | | Runs detailed routing on the processed design using TritonRoute: standalone or OpenROAD based on the value of `DETAILED_ROUTER`. The resulting file is under `/<run_path>/results/routing/` . |
|
||||
| `detailed_routing` | | Runs detailed routing on the processed design using OpenROAD TritonRoute, or DRCU based onthe value of `DETAILED_ROUTER`. The resulting file is under `/<run_path>/results/routing/` . |
|
||||
| `detailed_routing_tritonroute` | | Runs detailed routing on the processed design using OpenROAD TritonRoute based on the value of `DETAILED_ROUTER`. The resulting file is under `/<run_path>/results/routing/` . |
|
||||
| `detailed_routing_drcu` | | Runs detailed routing on the processed design using DRCU. The resulting file is under `/<run_path>/results/routing/` . |
|
||||
| `apply_route_obs`| | Uses `GLB_RT_OBS` to insert obstruction for each macro in order to prevent routing for each specified layer on each macro. Check `GLB_RT_OBS` in the configurations documentation for more details.|
|
||||
| `add_route_obs`| | Uses `GLB_RT_OBS` to call `apply_route_obs`, then calls `apply_route_obs` again to apply obstructions over the whole die area based on the value of `GLB_RT_MAXLAYER` up to the highest available metal layer.|
|
||||
|
||||
@@ -49,8 +49,6 @@ This section defines the neccessary variables for PDK configuration file
|
||||
| `NETGEN_SETUP_FILE` | Points to the setup file for netgen(lvs), that can exclude certain cells etc.. |
|
||||
| `FP_TAPCELL_DIST` | The distance between tapcell columns. Used in floorplanning in tapcell insertion. |
|
||||
| `GLB_RT_L1_ADJUSTMENT` | Reduction in the routing capacity of the edges between the cells in the global routing graph but specific to li1 layer in sky130A. Values range from 0 to 1 <br> (Default: `0`) |
|
||||
| `CTS_SQR_CAP` | Defines the capacitance per square micron, used in CTS. |
|
||||
| `CTS_SQR_RES` | Defines the resistance per square micron, used in CTS. |
|
||||
| `DEFAULT_MAX_TRAN` | Defines the default maximum transition value, used in CTS & synthesis. |
|
||||
| `FP_PDN_RAIL_OFFSET` | Defines the rail offset for met1 used in PDN. <br> Default: `0`. |
|
||||
| `FP_PDN_VWIDTH` | Defines the strap width for the vertical layer used in PDN. <br> Default: `1.6`. |
|
||||
|
||||
4
flow.tcl
4
flow.tcl
@@ -15,7 +15,9 @@
|
||||
|
||||
|
||||
set ::env(OPENLANE_ROOT) [file dirname [file normalize [info script]]]
|
||||
|
||||
if { ! [info exists ::env(OPENROAD_BIN) ] } {
|
||||
set ::env(OPENROAD_BIN) openroad
|
||||
}
|
||||
lappend ::auto_path "$::env(OPENLANE_ROOT)/scripts/"
|
||||
package require openlane; # provides the utils as well
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ def run_installer():
|
||||
if input_options("RISK_ACKNOWLEDGED", "I affirm that I have read LOCAL_INSTALL.md and agree to the outlined risks.", ["n", "y"]) != "y":
|
||||
return
|
||||
|
||||
print(f"""
|
||||
print(f"""\
|
||||
DO NOT USE THIS UTILITY BEFORE READING LOCAL_INSTALL.md.
|
||||
|
||||
OpenLane Local Installer ALPHA
|
||||
@@ -155,7 +155,6 @@ OpenLane Local Installer ALPHA
|
||||
|
||||
Note that this installer does *not* handle:
|
||||
- Installing OpenROAD to PATH
|
||||
- Installing opendbpy.py to PYTHONPATH
|
||||
|
||||
You'll have to do these on your own. We hope that you understand the implications of this.
|
||||
|
||||
@@ -315,7 +314,10 @@ OpenLane Local Installer ALPHA
|
||||
export NO_DIAMOND_SEARCH_HEIGHT=1
|
||||
export PATH=$OL_DIR/bin:$PATH
|
||||
|
||||
tclsh $OL_DIR/flow.tcl $@
|
||||
FLOW_TCL=${FLOW_TCL:-$OL_DIR/flow.tcl}
|
||||
FLOW_TCL=$(realpath $FLOW_TCL)
|
||||
|
||||
tclsh $FLOW_TCL $@
|
||||
""")
|
||||
sh("chmod", "+x", "./openlane")
|
||||
|
||||
|
||||
52
or_issue.py
52
or_issue.py
@@ -17,6 +17,7 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import glob
|
||||
import shutil
|
||||
import pathlib
|
||||
import argparse
|
||||
@@ -29,13 +30,15 @@ parser = argparse.ArgumentParser(description="""
|
||||
This script creates a reproducible, self-contained package of files to demonstrate
|
||||
OpenROAD behavior in a vaccum, suitable for filing issues.
|
||||
|
||||
Requires UNIX-like operating system. Final package printed to /dev/stdout. Don't forget to chomp/rstrip.
|
||||
Requires UNIX-like operating system. Final tarball's path is printed to stdout. Don't forget to chomp/strip.
|
||||
|
||||
Usage example: IMAGE_NAME=efabless/openlane:v0.15 python3 or_issue.py -s ./scripts/openroad/or_pdn.tcl ./designs/inverter/runs/openlane_test
|
||||
""")
|
||||
parser.add_argument('--or-script', '-s', required=True, help='Name of the OpenROAD script causing the failure: i.e. or_antenna_check.tcl, or_pdn.tcl, etc.')
|
||||
parser.add_argument('--pdk-root', required=(os.getenv("PDK_ROOT") is None), default=os.getenv("PDK_ROOT"), help='Path to the PDK root (Required if environment variable PDK_ROOT is not set.)')
|
||||
parser.add_argument('-c', '--compression', default="gzip", help='Comma,delimited list of compression techniques to use after tar. Use "None" to disable compression altogether. Default is "gzip", which will create a .tar.gzip file. Valid technologies: gzip/gz, xzip/xz, bzip2/bz2')
|
||||
parser.add_argument('--or-script', '-s', required=True, help='Path to the OpenROAD script causing the failure: i.e. or_antenna_check.tcl, or_pdn.tcl, etc. [required]')
|
||||
parser.add_argument('--pdk-root', required=(os.getenv("PDK_ROOT") is None), default=os.getenv("PDK_ROOT"), help='Path to the PDK root [required if environment variable PDK_ROOT is not set]')
|
||||
parser.add_argument('--input', '-i', required=True, help='Name of def file input into the OR script (usually denoted by environment variable CURRENT_DEF: get it from the logs) [required]')
|
||||
parser.add_argument('--output', '-o', default="./out.def", help='Name of def file to be generated [default: ./out.def]')
|
||||
parser.add_argument('-c', '--compression', default="gzip", help='Comma,delimited list of compression techniques to use after tar. Use "None" to disable compression altogether. Valid technologies: gzip/gz, xzip/xz, bzip2/bz2 [default: gzip]')
|
||||
parser.add_argument('run_path', help='Path to the run folder.')
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -44,6 +47,8 @@ run_path = abspath(args.run_path)
|
||||
pdk_root = abspath(args.pdk_root)
|
||||
compression = args.compression
|
||||
or_scripts_path = join(openlane_path, "scripts", "openroad")
|
||||
current_def = args.input
|
||||
save_def = args.output
|
||||
|
||||
if not script_path.startswith(or_scripts_path):
|
||||
print(f"⚠ The OpenROAD script {script_path} does not appear to be in {or_scripts_path}.", file=sys.stderr)
|
||||
@@ -100,6 +105,10 @@ def read_env(config_path: str, from_path: str, input_env={}) -> dict:
|
||||
return env
|
||||
|
||||
env = read_env(run_config, "Run Path") # , read_env(pdk_config, "PDK Root"))
|
||||
# Cannot be reliably read from config.tcl
|
||||
env["CURRENT_DEF"] = current_def
|
||||
env["SAVE_DEF"] = save_def
|
||||
|
||||
|
||||
# Phase 2: Set up destination folder
|
||||
destination_folder = abspath(join(".", "_build", f"{run_name}_{script_basename}_packaged"))
|
||||
@@ -123,7 +132,7 @@ def shift(deque):
|
||||
except:
|
||||
return None
|
||||
|
||||
envs_used = ["OR_SCRIPT"]
|
||||
env_keys_used = ["OR_SCRIPT"]
|
||||
env["OR_SCRIPT"] = script_path_containerized
|
||||
|
||||
current = shift(tcls_to_process)
|
||||
@@ -134,7 +143,7 @@ while current is not None:
|
||||
key_accessor = f"$::env({key})"
|
||||
if not key_accessor in script:
|
||||
continue
|
||||
envs_used.append(key)
|
||||
env_keys_used.append(key)
|
||||
if value.endswith(".tcl"):
|
||||
tcls_to_process.append(value)
|
||||
|
||||
@@ -149,15 +158,26 @@ openlane_misc_path = join(destination_folder, "openlane")
|
||||
def copy(frm, to):
|
||||
parents = dirname(to)
|
||||
mkdirp(parents)
|
||||
|
||||
try:
|
||||
if isdir(frm):
|
||||
shutil.copytree(frm, to)
|
||||
incomplete_matches = glob.glob(frm + "*")
|
||||
if len(incomplete_matches) == 0:
|
||||
raise Exception()
|
||||
elif len(incomplete_matches) != 1 or incomplete_matches[0] != frm:
|
||||
# Prefix File
|
||||
for match in incomplete_matches:
|
||||
new_frm = match
|
||||
new_to = to + new_frm[len(frm):]
|
||||
copy(new_frm, new_to)
|
||||
else:
|
||||
shutil.copyfile(frm, to)
|
||||
if isdir(frm):
|
||||
shutil.copytree(frm, to)
|
||||
else:
|
||||
shutil.copyfile(frm, to)
|
||||
except:
|
||||
print(f"ℹ Couldn't copy {frm}, skipping...", file=sys.stderr)
|
||||
|
||||
for key in envs_used:
|
||||
for key in env_keys_used:
|
||||
value = env[key]
|
||||
if value.startswith(run_path_containerized):
|
||||
relative = relpath(value, run_path_containerized)
|
||||
@@ -179,6 +199,11 @@ for key in envs_used:
|
||||
from_path = value.replace("/openLANE_flow", openlane_path)
|
||||
copy(from_path, final_path)
|
||||
final_env_pairs.append((key, final_value))
|
||||
elif value.startswith("/"):
|
||||
final_value = value[1:]
|
||||
final_path = join(destination_folder, final_value)
|
||||
copy(value, final_path)
|
||||
final_env_pairs.append((key, final_value))
|
||||
else:
|
||||
final_env_pairs.append((key, value))
|
||||
|
||||
@@ -186,7 +211,7 @@ for key in envs_used:
|
||||
run_ol = join(destination_folder, "run_ol")
|
||||
with open(run_ol, "w") as f:
|
||||
env_list = "\\\n ".join([f"-e {key}='{value}'" for key, value in final_env_pairs])
|
||||
f.write(f"""
|
||||
f.write(f"""\
|
||||
#!/bin/sh
|
||||
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
|
||||
cd $dir;
|
||||
@@ -200,12 +225,13 @@ os.chmod(run_ol, 0o755)
|
||||
run_raw = join(destination_folder, "run")
|
||||
with open(run_raw, "w") as f:
|
||||
env_list = "\n".join([f"export {key}='{value}';" for key, value in final_env_pairs])
|
||||
f.write(f"""
|
||||
f.write(f"""\
|
||||
#!/bin/sh
|
||||
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
|
||||
cd $dir;
|
||||
{env_list}
|
||||
openroad $OR_SCRIPT
|
||||
OPENROAD_BIN=${{OPENROAD_BIN:-openroad}}
|
||||
$OPENROAD_BIN -exit $OR_SCRIPT
|
||||
""")
|
||||
os.chmod(run_raw, 0o755)
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ python3 run_designs.py --designs spm xtea des aes256 --tag test --threads 3
|
||||
|
||||
You can view the results of the run against some designs (more [here](#usage)) against any of the 5 sky130 standard cell libraries through these sheets:
|
||||
|
||||
- [sky130_fd_sc_hd](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HD.html)
|
||||
- [sky130_fd_sc_hs](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HS.html)
|
||||
- [sky130_fd_sc_ms](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_MS.html)
|
||||
- [sky130_fd_sc_ls](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_LS.html)
|
||||
- [sky130_fd_sc_hdll](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HDLL.html)
|
||||
- [sky130_fd_sc_hd](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HD.csv)
|
||||
- [sky130_fd_sc_hs](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HS.csv)
|
||||
- [sky130_fd_sc_ms](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_MS.csv)
|
||||
- [sky130_fd_sc_ls](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_LS.csv)
|
||||
- [sky130_fd_sc_hdll](https://htmlpreview.github.io/?https://github.com/efabless/openlane/blob/master/regression_results/benchmark_results/SW_HDLL.csv)
|
||||
|
||||
**Note**: `flow_failed` under `flow_status` implies that the run had failed.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -198,13 +198,22 @@ def run_design(designs_queue):
|
||||
while not designs_queue.empty():
|
||||
design, config, tag,design_name= designs_queue.get(timeout=3) # 3s timeout
|
||||
run_path = utils.get_run_path(design=design, tag=tag)
|
||||
command = './flow.tcl -design {design} -tag {tag} -overwrite -disable_output -config_tag {config} -no_save'.format(design=design,tag=tag, config=config)
|
||||
log.info('{design} {tag} running'.format(design=design, tag=tag))
|
||||
command = ""
|
||||
if show_log_output:
|
||||
command = './flow.tcl -design {design} -tag {tag} -overwrite -config_tag {config} -no_save'.format(design=design,tag=tag, config=config)
|
||||
command = '{ol_entry} -design {design} -tag {tag} -overwrite -config_tag {config} -no_save'.format(
|
||||
ol_entry=os.getenv("OPENLANE_ENTRY") or "./flow.tcl",
|
||||
design=design,
|
||||
tag=tag,
|
||||
config=config
|
||||
)
|
||||
else:
|
||||
command = './flow.tcl -design {design} -tag {tag} -overwrite -disable_output -config_tag {config} -no_save'.format(design=design,tag=tag, config=config)
|
||||
command = '{ol_entry} -design {design} -tag {tag} -overwrite -disable_output -config_tag {config} -no_save'.format(
|
||||
ol_entry=os.getenv("OPENLANE_ENTRY") or "./flow.tcl",
|
||||
design=design,
|
||||
tag=tag,
|
||||
config=config
|
||||
)
|
||||
skip_rm_from_rems = False
|
||||
try:
|
||||
if show_log_output:
|
||||
@@ -382,7 +391,7 @@ for i in range(num_workers):
|
||||
workers[i].start()
|
||||
|
||||
for i in range(num_workers):
|
||||
while workers[i].isAlive() == True:
|
||||
while workers[i].is_alive() == True:
|
||||
workers[i].join(100)
|
||||
print("Exiting thread", i)
|
||||
|
||||
@@ -390,7 +399,7 @@ log.info("Getting top results..")
|
||||
best_result_cmd = "python3 ./scripts/report/get_best.py -i {input} -o {output}".format(
|
||||
input=report_handler.baseFilename,
|
||||
output=report_file_name + "_best.csv"
|
||||
)
|
||||
)
|
||||
subprocess.check_output(best_result_cmd.split())
|
||||
|
||||
if args.htmlExtract:
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
import argparse
|
||||
import re
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Creates obstructions in def files.')
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Produces a DEF file where a design is shown in the context of its instantiation in a top-level design')
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import argparse
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
# overkill
|
||||
parser = argparse.ArgumentParser(
|
||||
|
||||
@@ -30,7 +30,7 @@ import re
|
||||
import sys
|
||||
import argparse
|
||||
import random
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(description='''
|
||||
Places the IOs according to an input file. Supports regexes.
|
||||
|
||||
@@ -20,7 +20,7 @@ to single macro pin given also as an input -> writes a PINS section with shapes
|
||||
generated over those macro pins, "labels".
|
||||
"""
|
||||
import argparse
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Labels pins of macros according to netlist')
|
||||
|
||||
@@ -22,7 +22,7 @@ import argparse
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
# import opendbpy as odb
|
||||
# import opendb as odb
|
||||
|
||||
TECH = ""
|
||||
PDK_ROOT = os.environ["PDK_ROOT"]
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
import re
|
||||
import os
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Places macros in positions and orientations specified by a config file')
|
||||
|
||||
73
scripts/new_tracks.py
Normal file
73
scripts/new_tracks.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2020 Efabless Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import re
|
||||
import argparse
|
||||
|
||||
EXAMPLE_INPUT = """
|
||||
li1 X 0.23 0.46
|
||||
li1 Y 0.17 0.34
|
||||
met1 X 0.17 0.34
|
||||
met1 Y 0.17 0.34
|
||||
met2 X 0.23 0.46
|
||||
met2 Y 0.23 0.46
|
||||
met3 X 0.34 0.68
|
||||
met3 Y 0.34 0.68
|
||||
met4 X 0.46 0.92
|
||||
met4 Y 0.46 0.92
|
||||
met5 X 1.70 3.40
|
||||
met5 Y 1.70 3.40
|
||||
"""
|
||||
|
||||
def old_to_new_tracks(old_tracks: str) -> str:
|
||||
"""
|
||||
>>> old_to_new_tracks(EXAMPLE_INPUT)
|
||||
'make_tracks li1 -x_offset 0.23 -x_pitch 0.46 -y_offset 0.17 -y_pitch 0.34\\nmake_tracks met1 -x_offset 0.17 -x_pitch 0.34 -y_offset 0.17 -y_pitch 0.34\\nmake_tracks met2 -x_offset 0.23 -x_pitch 0.46 -y_offset 0.23 -y_pitch 0.46\\nmake_tracks met3 -x_offset 0.34 -x_pitch 0.68 -y_offset 0.34 -y_pitch 0.68\\nmake_tracks met4 -x_offset 0.46 -x_pitch 0.92 -y_offset 0.46 -y_pitch 0.92\\nmake_tracks met5 -x_offset 1.70 -x_pitch 3.40 -y_offset 1.70 -y_pitch 3.40\\n'
|
||||
"""
|
||||
old_tracks_lines = old_tracks.split("\n")
|
||||
layers = {}
|
||||
|
||||
for line in old_tracks_lines:
|
||||
if re.match(r"^\s*$", line):
|
||||
continue
|
||||
layer, cardinal, offset, pitch = re.split(r"\s+", line)
|
||||
layers[layer] = layers.get(layer) or {}
|
||||
layers[layer][cardinal] = (offset, pitch)
|
||||
|
||||
final_str = ""
|
||||
for layer, data in layers.items():
|
||||
x_offset, x_pitch = data["X"]
|
||||
y_offset, y_pitch = data["Y"]
|
||||
final_str += f"make_tracks {layer} -x_offset {x_offset} -x_pitch {x_pitch} -y_offset {y_offset} -y_pitch {y_pitch}\n"
|
||||
|
||||
return final_str
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Converts an old tracks.info file to a new .tracks file as dictated by OpenROAD.')
|
||||
|
||||
parser.add_argument('--input_file', '-i', required=True,
|
||||
help='input tracks.info')
|
||||
|
||||
parser.add_argument('--output_file', '-o', required=True,
|
||||
help='output .tracks file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
tracks_info_str = open(args.input_file).read()
|
||||
|
||||
with open(args.output_file, 'w') as f:
|
||||
f.write(old_to_new_tracks(tracks_info_str))
|
||||
@@ -26,4 +26,4 @@ if {[catch {read_def -order_wires $::env(CURRENT_DEF)} errmsg]} {
|
||||
#load_antenna_rules
|
||||
|
||||
# start checking antennas and generate a detail report
|
||||
check_antennas -path $::env(REPORTS_DIR)/routing/
|
||||
check_antennas -report_file $::env(REPORTS_DIR)/routing/antenna.rpt
|
||||
|
||||
@@ -40,9 +40,10 @@ repair_clock_inverters
|
||||
puts "\[INFO\]: Configuring cts characterization..."
|
||||
configure_cts_characterization\
|
||||
-max_slew $max_slew\
|
||||
-max_cap $max_cap\
|
||||
-sqr_cap $::env(CTS_SQR_CAP)\
|
||||
-sqr_res $::env(CTS_SQR_RES)
|
||||
-max_cap $max_cap
|
||||
|
||||
cts::set_cap_per_sqr $::env(CTS_SQR_CAP)
|
||||
cts::set_res_per_sqr $::env(CTS_SQR_RES)
|
||||
|
||||
puts "\[INFO]: Performing clock tree synthesis..."
|
||||
puts "\[INFO]: Looking for the following net(s): $::env(CLOCK_NET)"
|
||||
@@ -65,11 +66,7 @@ write_def $::env(SAVE_DEF)
|
||||
set buffers "$::env(CTS_ROOT_BUFFER) $::env(CTS_CLK_BUFFER_LIST)"
|
||||
set_placement_padding -masters $buffers -left $::env(CELL_PAD)
|
||||
puts "\[INFO\]: Legalizing..."
|
||||
if { [info exists ::env(NO_DIAMOND_SEARCH_HEIGHT)] } {
|
||||
detailed_placement
|
||||
} else {
|
||||
detailed_placement -diamond_search_height $::env(PL_DIAMOND_SEARCH_HEIGHT)
|
||||
}
|
||||
detailed_placement
|
||||
if { [info exists ::env(PL_OPTIMIZE_MIRRORING)] && $::env(PL_OPTIMIZE_MIRRORING) } {
|
||||
optimize_mirroring
|
||||
}
|
||||
|
||||
@@ -88,11 +88,7 @@ foreach net $::nets {
|
||||
puts "\n\[INFO\]: $count of $::antenna_cell_name inserted!"
|
||||
set_placement_padding -masters $::env(DIODE_CELL) -left $::env(DIODE_PADDING)
|
||||
puts "\[INFO\]: Legalizing..."
|
||||
if { [info exists ::env(NO_DIAMOND_SEARCH_HEIGHT)] } {
|
||||
detailed_placement
|
||||
} else {
|
||||
detailed_placement -diamond_search_height $::env(PL_DIAMOND_SEARCH_HEIGHT)
|
||||
}
|
||||
detailed_placement
|
||||
if { [info exists ::env(PL_OPTIMIZE_MIRRORING)] && $::env(PL_OPTIMIZE_MIRRORING) } {
|
||||
optimize_mirroring
|
||||
}
|
||||
|
||||
@@ -22,4 +22,9 @@ if {[catch {read_def $::env(CURRENT_DEF)} errmsg]} {
|
||||
exit 1
|
||||
}
|
||||
|
||||
tr::detailed_route_cmd $::env(tritonRoute_tmp_file_tag).param
|
||||
set_thread_count $::env(ROUTING_CORES)
|
||||
|
||||
detailed_route -param $::env(tritonRoute_tmp_file_tag).param
|
||||
|
||||
puts stderr "Saving to $::env(SAVE_DEF)"
|
||||
write_def $::env(SAVE_DEF)
|
||||
@@ -28,7 +28,6 @@ set top_margin [expr $::env(PLACE_SITE_HEIGHT) * $::env(TOP_MARGIN_MULT)]
|
||||
set left_margin [expr $::env(PLACE_SITE_WIDTH) * $::env(LEFT_MARGIN_MULT)]
|
||||
set right_margin [expr $::env(PLACE_SITE_WIDTH) * $::env(RIGHT_MARGIN_MULT)]
|
||||
|
||||
|
||||
if {$::env(FP_SIZING) == "absolute"} {
|
||||
if { ! [info exists ::env(CORE_AREA)] } {
|
||||
set die_ll_x [lindex $::env(DIE_AREA) 0]
|
||||
@@ -49,18 +48,14 @@ if {$::env(FP_SIZING) == "absolute"} {
|
||||
initialize_floorplan \
|
||||
-die_area $::env(DIE_AREA) \
|
||||
-core_area $::env(CORE_AREA) \
|
||||
-tracks $::env(TRACKS_INFO_FILE) \
|
||||
-site $::env(PLACE_SITE)
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
initialize_floorplan \
|
||||
-utilization $::env(FP_CORE_UTIL) \
|
||||
-aspect_ratio $::env(FP_ASPECT_RATIO) \
|
||||
-core_space "$bottom_margin $top_margin $left_margin $right_margin" \
|
||||
-tracks $::env(TRACKS_INFO_FILE) \
|
||||
-site $::env(PLACE_SITE)
|
||||
|
||||
set ::chip [[::ord::get_db] getChip]
|
||||
@@ -88,6 +83,7 @@ if {$::env(FP_SIZING) == "absolute"} {
|
||||
puts "\[INFO] Floorplanned on a die area of $::env(DIE_AREA) (microns). Saving to $::env(verilog2def_report_file_tag).die_area.rpt."
|
||||
puts "\[INFO] Floorplanned on a core area of $::env(CORE_AREA) (microns). Saving to $::env(verilog2def_report_file_tag).core_area.rpt."
|
||||
}
|
||||
source $::env(TRACKS_INFO_FILE)
|
||||
|
||||
set die_area_file [open $::env(verilog2def_report_file_tag).die_area.rpt w]
|
||||
set core_area_file [open $::env(verilog2def_report_file_tag).core_area.rpt w]
|
||||
|
||||
@@ -53,19 +53,17 @@ if { $::env(GLB_RT_MAXLAYER) > 3 } {
|
||||
}
|
||||
}
|
||||
|
||||
grt::set_unidirectional_routing $::env(GLB_RT_UNIDIRECTIONAL)
|
||||
# grt::set_unidirectional_routing $::env(GLB_RT_UNIDIRECTIONAL)
|
||||
# grt::set_tile_size $::env(GLB_RT_TILES)
|
||||
|
||||
grt::set_overflow_iterations $::env(GLB_RT_OVERFLOW_ITERS)
|
||||
|
||||
grt::set_allow_overflow $::env(GLB_RT_ALLOW_CONGESTION)
|
||||
|
||||
|
||||
grt::set_tile_size $::env(GLB_RT_TILES)
|
||||
|
||||
grt::run_fastroute 0
|
||||
grt::run
|
||||
|
||||
if { $::env(DIODE_INSERTION_STRATEGY) == 3 } {
|
||||
repair_antennas "$::env(DIODE_CELL)/$::env(DIODE_CELL_PIN)"
|
||||
repair_antennas "$::env(DIODE_CELL)/$::env(DIODE_CELL_PIN)" -iterations $::env(GLB_RT_ANT_ITERS)
|
||||
check_placement
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,12 @@ if { $::env(FP_IO_MODE) == 1 } {
|
||||
set opts "-random"
|
||||
}
|
||||
|
||||
set tech [[ord::get_db] getTech]
|
||||
set HMETAL [[$tech findRoutingLayer $::env(FP_IO_HMETAL)] getName]
|
||||
set VMETAL [[$tech findRoutingLayer $::env(FP_IO_VMETAL)] getName]
|
||||
place_pins $opts\
|
||||
-random_seed 42 \
|
||||
-min_distance $::env(FP_IO_MIN_DISTANCE) \
|
||||
-hor_layers $::env(FP_IO_HMETAL)\
|
||||
-ver_layers $::env(FP_IO_VMETAL)
|
||||
-hor_layers $HMETAL \
|
||||
-ver_layers $VMETAL
|
||||
|
||||
write_def $::env(SAVE_DEF)
|
||||
|
||||
@@ -26,11 +26,7 @@ set_placement_padding -global -right $::env(CELL_PAD)
|
||||
|
||||
set_placement_padding -masters $::env(CELL_PAD_EXCLUDE) -right 0 -left 0
|
||||
|
||||
if { [info exists ::env(NO_DIAMOND_SEARCH_HEIGHT)] } {
|
||||
detailed_placement
|
||||
} else {
|
||||
detailed_placement -diamond_search_height $::env(PL_DIAMOND_SEARCH_HEIGHT)
|
||||
}
|
||||
detailed_placement
|
||||
if { [info exists ::env(PL_OPTIMIZE_MIRRORING)] && $::env(PL_OPTIMIZE_MIRRORING) } {
|
||||
optimize_mirroring
|
||||
}
|
||||
|
||||
@@ -44,29 +44,28 @@ if { ! $free_insts_flag } {
|
||||
exit 0
|
||||
}
|
||||
|
||||
set_replace_verbose_level_cmd 1
|
||||
gpl::set_verbose_level_cmd 1
|
||||
|
||||
set_replace_density_cmd $::env(PL_TARGET_DENSITY)
|
||||
gpl::set_density_cmd $::env(PL_TARGET_DENSITY)
|
||||
|
||||
read_lib $::env(LIB_SYNTH)
|
||||
|
||||
if { $::env(PL_BASIC_PLACEMENT) } {
|
||||
set_replace_overflow_cmd 0.9
|
||||
set_replace_init_density_penalty_factor_cmd 0.0001
|
||||
set_replace_initial_place_max_iter_cmd 20
|
||||
set_replace_bin_grid_cnt_x_cmd 64
|
||||
set_replace_bin_grid_cnt_y_cmd 64
|
||||
gpl::set_overflow_cmd 0.9
|
||||
gpl::set_init_density_penalty_factor_cmd 0.0001
|
||||
gpl::set_initial_place_max_iter_cmd 20
|
||||
gpl::set_bin_grid_cnt_x_cmd 64
|
||||
gpl::set_bin_grid_cnt_y_cmd 64
|
||||
}
|
||||
|
||||
if { $::env(PL_TIME_DRIVEN) } {
|
||||
read_lib $::env(LIB_SYNTH)
|
||||
read_sdc $::env(BASE_SDC_FILE)
|
||||
gpl::set_timing_driven_mode 1
|
||||
read_verilog $::env(yosys_result_file_tag).v
|
||||
} else {
|
||||
set_replace_disable_timing_driven_mode_cmd
|
||||
}
|
||||
|
||||
if { !$::env(PL_ROUTABILITY_DRIVEN) } {
|
||||
set_replace_disable_routability_driven_mode_cmd
|
||||
} else {
|
||||
if { $::env(PL_ROUTABILITY_DRIVEN) } {
|
||||
gpl::set_routability_driven_mode 1
|
||||
grt::set_capacity_adjustment $::env(GLB_RT_ADJUSTMENT)
|
||||
grt::set_max_layer $::env(GLB_RT_MAXLAYER)
|
||||
grt::add_layer_adjustment 1 $::env(GLB_RT_L1_ADJUSTMENT)
|
||||
@@ -81,19 +80,19 @@ if { !$::env(PL_ROUTABILITY_DRIVEN) } {
|
||||
}
|
||||
}
|
||||
}
|
||||
grt::set_unidirectional_routing $::env(GLB_RT_UNIDIRECTIONAL)
|
||||
# grt::set_unidirectional_routing $::env(GLB_RT_UNIDIRECTIONAL)
|
||||
grt::set_overflow_iterations 150
|
||||
set_replace_routability_max_density_cmd [expr $::env(PL_TARGET_DENSITY) + 0.1]
|
||||
set_replace_routability_max_inflation_iter_cmd 10
|
||||
gpl::set_routability_max_density_cmd [expr $::env(PL_TARGET_DENSITY) + 0.1]
|
||||
gpl::set_routability_max_inflation_iter_cmd 10
|
||||
}
|
||||
|
||||
if { !$::env(PL_SKIP_INITIAL_PLACEMENT) || $::env(PL_BASIC_PLACEMENT) } {
|
||||
replace_initial_place_cmd
|
||||
gpl::replace_initial_place_cmd
|
||||
}
|
||||
|
||||
replace_nesterov_place_cmd
|
||||
gpl::replace_nesterov_place_cmd
|
||||
|
||||
replace_reset_cmd
|
||||
gpl::replace_reset_cmd
|
||||
|
||||
write_def $::env(SAVE_DEF)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import random
|
||||
import argparse
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
# TECH = ""
|
||||
# PDK_ROOT = os.environ["PDK_ROOT"]
|
||||
|
||||
@@ -8,7 +8,7 @@ import argparse
|
||||
import random
|
||||
import sys
|
||||
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
|
||||
class DiodeInserter:
|
||||
|
||||
@@ -19,7 +19,7 @@ from the power/ground pads to the *core ring*
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
from pprint import pprint
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
import argparse
|
||||
import random
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Places instances in random locations in layout. Intended for cases,'
|
||||
|
||||
@@ -51,7 +51,7 @@ arc_antenna_report=$(python3 $3/get_file_name.py -p ${path}/reports/routing/ -o
|
||||
fr_log=${path}/logs/routing/fastroute.log
|
||||
cvc_log=$(python3 $3/get_file_name.py -p ${path}/logs/cvc/ -o cvc_screen.log 2>&1)
|
||||
tritonRoute_def="${path}/results/routing/${designName}.def"
|
||||
openDP_log=$(python3 $3/get_file_name.py -p ${path}/logs/placement/ -o opendp.log 2>&1)
|
||||
replace_log=$(python3 $3/get_file_name.py -p ${path}/logs/placement/ -o replace.log 2>&1)
|
||||
lvs_report=${path}/results/lvs/${designName}.lvs_parsed.*.log
|
||||
# Extracting info from Yosys
|
||||
cell_count=$(grep "cells" $yosys_rprt -s | tail -1 | sed -r 's/.*[^0-9]//')
|
||||
@@ -97,7 +97,7 @@ cellperum=-1
|
||||
#if ! [[ $cellperum ]]; then cellperum=-1;fi
|
||||
|
||||
#Extracting OpenDP Reported Utilization
|
||||
opendpUtil=$(grep "utilization" $openDP_log -s | head -1 | sed -E 's/.* (\S+).*%/\1/')
|
||||
opendpUtil=$(grep "Util(%):" $replace_log -s | head -1 | sed -E 's/.*Util\(%\): (\S+)/\1/')
|
||||
if ! [[ $opendpUtil ]]; then opendpUtil=-1; fi
|
||||
|
||||
#Extracting TritonRoute memory usage peak
|
||||
@@ -255,17 +255,19 @@ level=$(grep -e "ABC: netlist" $yosys_log -s | tail -1 | sed -r 's/.*lev.*[^0-9]
|
||||
if ! [[ $level ]]; then level=-1; fi
|
||||
|
||||
#Extracting layer usage percentage
|
||||
layer1=$(grep "Layer 1 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 1 use percentage: (\S+)%/\1/')
|
||||
usageLine=$(grep -n -E "Layer\s+Resource" $fr_log | tail -1 | sed -E 's/(\S+):.*/\1/')
|
||||
|
||||
layer1=$(sed -n "$(expr $usageLine + 2)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer1 ]]; then layer1=-1; fi
|
||||
layer2=$(grep "Layer 2 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 2 use percentage: (\S+)%/\1/')
|
||||
layer2=$(sed -n "$(expr $usageLine + 3)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer2 ]]; then layer2=-1; fi
|
||||
layer3=$(grep "Layer 3 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 3 use percentage: (\S+)%/\1/')
|
||||
layer3=$(sed -n "$(expr $usageLine + 4)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer3 ]]; then layer3=-1; fi
|
||||
layer4=$(grep "Layer 4 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 4 use percentage: (\S+)%/\1/')
|
||||
layer4=$(sed -n "$(expr $usageLine + 5)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer4 ]]; then layer4=-1; fi
|
||||
layer5=$(grep "Layer 5 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 5 use percentage: (\S+)%/\1/')
|
||||
layer5=$(sed -n "$(expr $usageLine + 6)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer5 ]]; then layer5=-1; fi
|
||||
layer6=$(grep "Layer 6 use percentage:" $fr_log -s | tail -1 | sed -E 's/Layer 6 use percentage: (\S+)%/\1/')
|
||||
layer6=$(sed -n "$(expr $usageLine + 7)p" $fr_log | sed -E 's/.*\s+(\S+)%.*/\1/')
|
||||
if ! [[ $layer6 ]]; then layer6=-1; fi
|
||||
|
||||
#Extracting Endcaps and TapCells
|
||||
@@ -279,7 +281,7 @@ if ! [[ $tapcells ]]; then tapcells=0; fi
|
||||
#Extracting Diodes
|
||||
diodes=$(grep "inserted!" $diodes_log -s | tail -1 | sed -E 's/.* (\S+) of .* inserted!/\1/')
|
||||
if ! [[ $diodes ]]; then
|
||||
diodes=$(grep "diodes inserted" $fr_log -s | tail -1 | sed -E 's/.* (\S+) diodes inserted/\1/')
|
||||
diodes=$(grep "diodes inserted" $fr_log -s | tail -1 | sed -E 's/.* (\S+) diodes inserted./\1/')
|
||||
if ! [[ $diodes ]]; then diodes=0; fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -49,22 +49,24 @@ class SpefExtractor:
|
||||
vias = {}
|
||||
for line in vias_data:
|
||||
words = line.strip().split()
|
||||
if words:
|
||||
if words[0] == '-':
|
||||
current_via_name = words[1]
|
||||
vias[current_via_name] = []
|
||||
elif words[0] != ';':
|
||||
vias[current_via_name].append(words)
|
||||
|
||||
current_via_name = words[1]
|
||||
specs = line.strip().split('+')
|
||||
for spec in specs:
|
||||
words = spec.strip(" ;").split()
|
||||
if words[0] == '-':
|
||||
current_via_name = words[1]
|
||||
vias[current_via_name] = []
|
||||
else:
|
||||
vias[current_via_name].append(words)
|
||||
for via, lines in vias.items():
|
||||
current_via = {}
|
||||
if lines[0][1].lower() == 'viarule':
|
||||
if lines[0][0].lower() == 'viarule':
|
||||
for line in lines:
|
||||
current_via[line[1]] = line[2:]
|
||||
current_via[line[0]] = line[1:]
|
||||
else:
|
||||
layers = []
|
||||
for line in lines:
|
||||
layers.append(line[2])
|
||||
layers.append(line[1])
|
||||
current_via['LAYERS'] = layers
|
||||
self.vias_dict_def[via] = current_via
|
||||
|
||||
@@ -559,4 +561,4 @@ if __name__ == "__main__":
|
||||
wireModel = args.wire_model
|
||||
edgeCapFactor = float(args.edge_cap_factor)
|
||||
|
||||
inst.extract(lef_file_name, def_file_name, wireModel, edgeCapFactor)
|
||||
inst.extract(lef_file_name, def_file_name, wireModel, edgeCapFactor)
|
||||
@@ -12,6 +12,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
if {[catch {read_lef $::env(MERGED_LEF_UNPADDED)} errmsg]} {
|
||||
puts stderr $errmsg
|
||||
exit 1
|
||||
}
|
||||
|
||||
set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
|
||||
|
||||
read_liberty -min $::env(LIB_FASTEST)
|
||||
|
||||
@@ -70,7 +70,7 @@ proc set_guide {guide} {
|
||||
proc prep_lefs {args} {
|
||||
puts_info "Preparing LEF Files"
|
||||
puts_info "Extracting the number of available metal layers from $::env(TECH_LEF)"
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/extract_metal_layers.py -t $::env(TECH_LEF) -o $::env(TMP_DIR)/met_layers_list.txt
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/extract_metal_layers.py -t $::env(TECH_LEF) -o $::env(TMP_DIR)/met_layers_list.txt
|
||||
set tech_metal_layers_string [exec cat $::env(TMP_DIR)/met_layers_list.txt]
|
||||
set tech_metal_layers_string_strip [join $tech_metal_layers_string " "]
|
||||
set ::env(TECH_METAL_LAYERS) [split $tech_metal_layers_string_strip]
|
||||
@@ -403,9 +403,9 @@ proc prep {args} {
|
||||
set ::env(LIB_SYNTH) $::env(TMP_DIR)/trimmed.lib
|
||||
trim_lib
|
||||
|
||||
set tracks_copy $::env(TMP_DIR)/tracks_copy.info
|
||||
file copy -force $::env(TRACKS_INFO_FILE) $tracks_copy
|
||||
set ::env(TRACKS_INFO_FILE) $tracks_copy
|
||||
set tracks_processed $::env(TMP_DIR)/config.tracks
|
||||
try_catch $::env(OPENROAD_BIN) -python scripts/new_tracks.py -i $::env(TRACKS_INFO_FILE) -o $tracks_processed
|
||||
set ::env(TRACKS_INFO_FILE) $tracks_processed
|
||||
|
||||
if { $::env(USE_GPIO_PADS) } {
|
||||
if { ! [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
|
||||
@@ -701,7 +701,7 @@ proc heal_antenna_violators {args} {
|
||||
puts_info "Healing Antenna Violators..."
|
||||
if { $::env(USE_ARC_ANTENNA_CHECK) == 1 } {
|
||||
#ARC specific
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/extract_antenna_violators.py -i [index_file $::env(REPORTS_DIR)/routing/antenna.rpt 0] -o [index_file $::env(TMP_DIR)/vios.txt 0]
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/extract_antenna_violators.py -i [index_file $::env(REPORTS_DIR)/routing/antenna.rpt 0] -o [index_file $::env(TMP_DIR)/vios.txt 0]
|
||||
} else {
|
||||
#Magic Specific
|
||||
set report_file [open [index_file $::env(magic_report_file_tag).antenna_violators.rpt 0] r]
|
||||
@@ -711,7 +711,7 @@ proc heal_antenna_violators {args} {
|
||||
exec echo $violators >> [index_file $::env(TMP_DIR)/vios.txt 0]
|
||||
}
|
||||
#replace violating cells with real diodes
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/fakeDiodeReplace.py -v [index_file $::env(TMP_DIR)/vios.txt 0] -d $::env(tritonRoute_result_file_tag).def -f $::env(FAKEDIODE_CELL) -t $::env(DIODE_CELL)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/fakeDiodeReplace.py -v [index_file $::env(TMP_DIR)/vios.txt 0] -d $::env(tritonRoute_result_file_tag).def -f $::env(FAKEDIODE_CELL) -t $::env(DIODE_CELL)
|
||||
puts_info "DONE HEALING ANTENNA VIOLATORS"
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(LOG_DIR)/antenna_heal_runtime.txt 0]
|
||||
@@ -722,12 +722,12 @@ proc heal_antenna_violators {args} {
|
||||
proc li1_hack_start {args} {
|
||||
puts_info "Starting the li1 Hack..."
|
||||
try_catch touch $::env(TMP_DIR)/li1HackTmpFile.txt
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/li1_hack_start.py -d $::env(CURRENT_DEF) -l $::env(MERGED_LEF_UNPADDED) -t $::env(TMP_DIR)/li1HackTmpFile.txt
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/li1_hack_start.py -d $::env(CURRENT_DEF) -l $::env(MERGED_LEF_UNPADDED) -t $::env(TMP_DIR)/li1HackTmpFile.txt
|
||||
}
|
||||
|
||||
proc li1_hack_end {args} {
|
||||
puts_info "Ending the li1 Hack..."
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/li1_hack_end.py -d $::env(CURRENT_DEF) -t $::env(TMP_DIR)/li1HackTmpFile.txt
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/li1_hack_end.py -d $::env(CURRENT_DEF) -t $::env(TMP_DIR)/li1HackTmpFile.txt
|
||||
}
|
||||
|
||||
proc widen_site_width {args} {
|
||||
@@ -743,12 +743,12 @@ proc widen_site_width {args} {
|
||||
set ::env(MERGED_LEF_UNPADDED_WIDENED) $::env(TMP_DIR)/merged_unpadded_wider.lef
|
||||
set ::env(MERGED_LEF_WIDENED) $::env(TMP_DIR)/merged_wider.lef
|
||||
if { $::env(WIDEN_SITE_IS_FACTOR) == 1 } {
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF_UNPADDED) -w $::env(WIDEN_SITE) -f -o $::env(MERGED_LEF_UNPADDED_WIDENED)
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF) -w $::env(WIDEN_SITE) -f -o $::env(MERGED_LEF_WIDENED)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF_UNPADDED) -w $::env(WIDEN_SITE) -f -o $::env(MERGED_LEF_UNPADDED_WIDENED)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF) -w $::env(WIDEN_SITE) -f -o $::env(MERGED_LEF_WIDENED)
|
||||
|
||||
} else {
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF_UNPADDED) -w $::env(WIDEN_SITE) -o $::env(MERGED_LEF_UNPADDED_WIDENED)
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF) -w $::env(WIDEN_SITE) -o $::env(MERGED_LEF_WIDENED)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF_UNPADDED) -w $::env(WIDEN_SITE) -o $::env(MERGED_LEF_UNPADDED_WIDENED)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/widenSiteLef.py -l $::env(MERGED_LEF) -w $::env(WIDEN_SITE) -o $::env(MERGED_LEF_WIDENED)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -794,7 +794,7 @@ proc label_macro_pins {args} {
|
||||
|
||||
set_if_unset arg_values(-pad_pin_name) ""
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/label_macro_pins.py\
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/label_macro_pins.py\
|
||||
--lef $arg_values(-lef)\
|
||||
--input-def $::env(CURRENT_DEF)\
|
||||
--netlist-def $arg_values(-netlist_def)\
|
||||
@@ -823,7 +823,7 @@ proc write_verilog {filename args} {
|
||||
|
||||
set ::env(INPUT_DEF) $arg_values(-def)
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_write_verilog.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/write_verilog.log]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_write_verilog.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/write_verilog.log]
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(LOG_DIR)/write_verilog_runtime.txt 0]
|
||||
if { [info exists flags_map(-canonical)] } {
|
||||
@@ -842,14 +842,14 @@ proc set_layer_tracks {args} {
|
||||
set flags {}
|
||||
parse_key_args "set_layer_tracks" args arg_values $options flags_map $flags
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/setLayerTracks.py -d $arg_values(-defFile) -l $arg_values(-layer) -v $arg_values(-valuesFile) -o $arg_values(-originalFile)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/setLayerTracks.py -d $arg_values(-defFile) -l $arg_values(-layer) -v $arg_values(-valuesFile) -o $arg_values(-originalFile)
|
||||
|
||||
}
|
||||
|
||||
proc run_or_antenna_check {args} {
|
||||
TIMER::timer_start
|
||||
puts_info "Running OpenROAD Antenna Rule Checker..."
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_antenna_check.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/routing/or_antenna.log]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_antenna_check.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/routing/or_antenna.log]
|
||||
try_catch mv -f $::env(REPORTS_DIR)/routing/antenna.rpt [index_file $::env(REPORTS_DIR)/routing/antenna.rpt]
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(LOG_DIR)/routing/or_antenna_runtime.txt 0]
|
||||
|
||||
@@ -90,7 +90,7 @@ proc run_cts {args} {
|
||||
set ::env(LIB_CTS) $::env(TMP_DIR)/cts.lib
|
||||
trim_lib -input $::env(LIB_SYNTH_COMPLETE) -output $::env(LIB_CTS) -drc_exclude_only
|
||||
}
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_cts.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(cts_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_cts.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(cts_log_file_tag).log 0]
|
||||
check_cts_clock_nets
|
||||
set ::env(cts_report_file_tag) $report_tag_holder
|
||||
TIMER::timer_stop
|
||||
|
||||
@@ -22,7 +22,7 @@ proc init_floorplan {args} {
|
||||
set ::env(SAVE_DEF) [index_file $::env(verilog2def_tmp_file_tag)_openroad.def]
|
||||
set report_tag_saver $::env(verilog2def_report_file_tag)
|
||||
set ::env(verilog2def_report_file_tag) [index_file $::env(verilog2def_report_file_tag) 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_floorplan.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(verilog2def_log_file_tag).openroad.log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_floorplan.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(verilog2def_log_file_tag).openroad.log 0]
|
||||
check_floorplan_missing_lef
|
||||
check_floorplan_missing_pins
|
||||
|
||||
@@ -100,7 +100,7 @@ proc place_io_ol {args} {
|
||||
|
||||
set_if_unset arg_values(-extra_args) ""
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/io_place.py\
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/io_place.py\
|
||||
--input-lef $arg_values(-lef)\
|
||||
--input-def $arg_values(-def)\
|
||||
--config $arg_values(-cfg)\
|
||||
@@ -121,7 +121,7 @@ proc place_io {args} {
|
||||
TIMER::timer_start
|
||||
set ::env(SAVE_DEF) [index_file $::env(ioPlacer_tmp_file_tag).def]
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_ioplacer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(ioPlacer_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_ioplacer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(ioPlacer_log_file_tag).log 0]
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(ioPlacer_log_file_tag)_runtime.txt 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
@@ -142,7 +142,7 @@ proc place_contextualized_io {args} {
|
||||
|
||||
set prev_def $::env(CURRENT_DEF)
|
||||
set ::env(SAVE_DEF) [index_file $::env(ioPlacer_tmp_file_tag).context.def]
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/contextualize.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/contextualize.py \
|
||||
-md $prev_def -ml $::env(MERGED_LEF_UNPADDED) \
|
||||
-td $::env(TMP_DIR)/top_level.def -tl $::env(TMP_DIR)/top_level.lef \
|
||||
-o $::env(SAVE_DEF) |& \
|
||||
@@ -156,7 +156,7 @@ proc place_contextualized_io {args} {
|
||||
set old_mode $::env(FP_IO_MODE)
|
||||
set ::env(FP_IO_MODE) 0; # set matching mode
|
||||
set ::env(CONTEXTUAL_IO_FLAG_) 1
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_ioplacer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(ioPlacer_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_ioplacer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(ioPlacer_log_file_tag).log 0]
|
||||
set ::env(FP_IO_MODE) $old_mode
|
||||
|
||||
move_pins -from $::env(SAVE_DEF) -to $prev_def
|
||||
@@ -179,7 +179,7 @@ proc tap_decap_or {args} {
|
||||
puts_info "Running Tap/Decap Insertion..."
|
||||
TIMER::timer_start
|
||||
set ::env(SAVE_DEF) $::env(tapcell_result_file_tag).def
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_tapcell.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(tapcell_log_file_tag).log]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_tapcell.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(tapcell_log_file_tag).log]
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(tapcell_log_file_tag)_runtime.txt 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
@@ -213,7 +213,7 @@ proc chip_floorplan {args} {
|
||||
proc apply_def_template {args} {
|
||||
if { [info exists ::env(FP_DEF_TEMPLATE)] } {
|
||||
puts_info "Applying DEF template..."
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/apply_def_template.py -t $::env(FP_DEF_TEMPLATE) -u $::env(CURRENT_DEF) -s $::env(SCRIPTS_DIR)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/apply_def_template.py -t $::env(FP_DEF_TEMPLATE) -u $::env(CURRENT_DEF) -s $::env(SCRIPTS_DIR)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ proc run_klayout_gds_xor {args} {
|
||||
$arg_values(-layout1) $arg_values(-layout2) $::env(DESIGN_NAME) \
|
||||
$arg_values(-output_gds) \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(klayout_log_file_tag).xor.log]
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
|
||||
-l [index_file $::env(klayout_log_file_tag).xor.log 0] \
|
||||
-o [index_file $::env(klayout_report_file_tag).xor.rpt 0]
|
||||
scrot_klayout -layout $arg_values(-output_gds)
|
||||
@@ -132,7 +132,7 @@ proc run_klayout_gds_xor {args} {
|
||||
$arg_values(-layout1) $arg_values(-layout2) $::env(DESIGN_NAME) \
|
||||
$arg_values(-output_xml) \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(klayout_log_file_tag).xor.log]
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/parse_klayout_xor_log.py \
|
||||
-l [index_file $::env(klayout_log_file_tag).xor.log 0] \
|
||||
-o [index_file $::env(klayout_report_file_tag).xor.rpt 0]
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ proc write_powered_verilog {args} {
|
||||
set_if_unset arg_values(-powered_netlist) ""
|
||||
}
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/write_powered_def.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/write_powered_def.py \
|
||||
-d $arg_values(-def) \
|
||||
-l $arg_values(-lef) \
|
||||
--power-port $arg_values(-power) \
|
||||
|
||||
@@ -103,23 +103,23 @@ proc run_magic_drc {args} {
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(magic_log_file_tag).drc.log 0]
|
||||
|
||||
puts_info "Converting Magic DRC Violations to Magic Readable Format..."
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/magic_drc_to_tcl.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tcl.py \
|
||||
-i $::env(magic_report_file_tag).drc \
|
||||
-o $::env(magic_report_file_tag).drc.tcl
|
||||
|
||||
puts_info "Converting Magic DRC Violations to Klayout XML Database..."
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/magic_drc_to_tr_drc.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_tr_drc.py \
|
||||
-i $::env(magic_report_file_tag).drc \
|
||||
-o $::env(magic_report_file_tag).tr.drc
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/tr2klayout.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/tr2klayout.py \
|
||||
-i $::env(magic_report_file_tag).tr.drc \
|
||||
-o $::env(magic_report_file_tag).drc.klayout.xml \
|
||||
--design-name $::env(DESIGN_NAME)
|
||||
|
||||
if { $::env(MAGIC_CONVERT_DRC_TO_RDB) == 1 } {
|
||||
puts_info "Converting DRC Violations to RDB Format..."
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/magic_drc_to_rdb.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/magic_drc_to_rdb.py \
|
||||
--magic_drc_in $::env(magic_report_file_tag).drc \
|
||||
--rdb_out $::env(magic_report_file_tag).drc.rdb
|
||||
puts_info "Converted DRC Violations to RDB Format"
|
||||
|
||||
@@ -12,16 +12,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
proc global_placement {args} {
|
||||
puts_info "Running Global Placement..."
|
||||
TIMER::timer_start
|
||||
try_catch replace < $::env(SCRIPTS_DIR)/replace_gp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(replaceio_log_file_tag).log]
|
||||
try_catch cp $::env(replaceio_tmp_file_tag)_place.def $::env(replaceio_tmp_file_tag).def
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(replaceio_log_file_tag)_runtime.txt 0]
|
||||
set_def $::env(replaceio_tmp_file_tag).def
|
||||
}
|
||||
|
||||
proc global_placement_or {args} {
|
||||
puts_info "Running Global Placement..."
|
||||
TIMER::timer_start
|
||||
@@ -35,7 +25,7 @@ proc global_placement_or {args} {
|
||||
|
||||
set report_tag_saver $::env(replaceio_report_file_tag)
|
||||
set ::env(replaceio_report_file_tag) [index_file $::env(replaceio_report_file_tag) 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_replace.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(replaceio_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_replace.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(replaceio_log_file_tag).log 0]
|
||||
set ::env(replaceio_report_file_tag) $report_tag_saver
|
||||
# sometimes replace fails with a ZERO exit code; the following is a workaround
|
||||
# until the cause is found and fixed
|
||||
@@ -51,12 +41,17 @@ proc global_placement_or {args} {
|
||||
set_def $::env(SAVE_DEF)
|
||||
}
|
||||
|
||||
proc global_placement {args} {
|
||||
global_placement_or args
|
||||
}
|
||||
|
||||
|
||||
proc random_global_placement {args} {
|
||||
puts_warn "Performing Random Global Placement..."
|
||||
TIMER::timer_start
|
||||
set ::env(SAVE_DEF) [index_file $::env(replaceio_tmp_file_tag).def]
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/random_place.py --lef $::env(MERGED_LEF_UNPADDED) \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/random_place.py --lef $::env(MERGED_LEF_UNPADDED) \
|
||||
--input-def $::env(CURRENT_DEF) --output-def $::env(SAVE_DEF) \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(replaceio_log_file_tag).log 0]
|
||||
|
||||
@@ -65,18 +60,35 @@ proc random_global_placement {args} {
|
||||
set_def $::env(SAVE_DEF)
|
||||
}
|
||||
|
||||
proc detailed_placement {args} {
|
||||
proc detailed_placement_or {args} {
|
||||
puts_info "Running Detailed Placement..."
|
||||
TIMER::timer_start
|
||||
try_catch opendp \
|
||||
-lef $::env(MERGED_LEF) \
|
||||
-def $::env(CURRENT_DEF) \
|
||||
-output_def $::env(opendp_result_file_tag).def \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opendp_log_file_tag).log]
|
||||
set ::env(SAVE_DEF) $::env(opendp_result_file_tag).def
|
||||
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_opendp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opendp_log_file_tag).log]
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
if {[catch {exec grep -q -i "fail" [index_file $::env(opendp_log_file_tag).log 0]}] == 0} {
|
||||
puts_info "Error in detailed placement"
|
||||
puts_info "Retrying detailed placement"
|
||||
set ::env(SAVE_DEF) $::env(opendp_result_file_tag).1.def
|
||||
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_opendp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opendp_log_file_tag).log]
|
||||
}
|
||||
|
||||
if {[catch {exec grep -q -i "fail" [index_file $::env(opendp_log_file_tag).log 0]}] == 0} {
|
||||
puts "Error: Check [index_file $::env(opendp_log_file_tag).log 0]"
|
||||
puts stderr "\[ERROR\]: Check [index_file $::env(opendp_log_file_tag).log 0]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(opendp_log_file_tag)_runtime.txt 0]
|
||||
set_def $::env(opendp_result_file_tag).def
|
||||
set_def $::env(SAVE_DEF)
|
||||
}
|
||||
|
||||
proc detailed_placement {args} {
|
||||
detailed_placement_or args
|
||||
}
|
||||
|
||||
proc add_macro_placement {args} {
|
||||
@@ -93,49 +105,20 @@ proc manual_macro_placement {args} {
|
||||
set var "f"
|
||||
set fbasename [file rootname $::env(CURRENT_DEF)]
|
||||
if { [string compare [lindex $args 0] $var] == 0 } {
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/manual_macro_place.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o ${fbasename}.macro_placement.def -c $::env(TMP_DIR)/macro_placement.cfg -f |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/macro_placement.log]
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/manual_macro_place.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o ${fbasename}.macro_placement.def -c $::env(TMP_DIR)/macro_placement.cfg -f |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/macro_placement.log]
|
||||
} else {
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/manual_macro_place.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o ${fbasename}.macro_placement.def -c $::env(TMP_DIR)/macro_placement.cfg |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/macro_placement.log]
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/manual_macro_place.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o ${fbasename}.macro_placement.def -c $::env(TMP_DIR)/macro_placement.cfg |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/macro_placement.log]
|
||||
}
|
||||
set_def ${fbasename}.macro_placement.def
|
||||
}
|
||||
|
||||
proc detailed_placement_or {args} {
|
||||
puts_info "Running Detailed Placement..."
|
||||
TIMER::timer_start
|
||||
set ::env(SAVE_DEF) $::env(opendp_result_file_tag).def
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_opendp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opendp_log_file_tag).log]
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
if {[catch {exec grep -q -i "fail" [index_file $::env(opendp_log_file_tag).log 0]}] == 0} {
|
||||
puts_info "Error in detailed placement"
|
||||
puts_info "Retrying detailed placement"
|
||||
set ::env(SAVE_DEF) $::env(opendp_result_file_tag).1.def
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_opendp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opendp_log_file_tag).log]
|
||||
}
|
||||
|
||||
if {[catch {exec grep -q -i "fail" [index_file $::env(opendp_log_file_tag).log 0]}] == 0} {
|
||||
puts "Error: Check [index_file $::env(opendp_log_file_tag).log 0]"
|
||||
puts stderr "\[ERROR\]: Check [index_file $::env(opendp_log_file_tag).log 0]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(opendp_log_file_tag)_runtime.txt 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
}
|
||||
|
||||
proc basic_macro_placement {args} {
|
||||
puts_info "Running Basic Macro Placement"
|
||||
TIMER::timer_start
|
||||
set fbasename [file rootname $::env(CURRENT_DEF)]
|
||||
set ::env(SAVE_DEF) ${fbasename}.macro_placement.def
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_basic_mp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/basic_mp.log]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_basic_mp.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/basic_mp.log]
|
||||
|
||||
check_macro_placer_num_solns
|
||||
|
||||
@@ -226,7 +209,7 @@ proc run_resizer_timing {args} {
|
||||
gen_exclude_list -lib $::env(LIB_RESIZER_OPT) -drc_exclude_only -create_dont_use_list
|
||||
}
|
||||
set ::env(SAVE_DEF) [index_file $::env(resizer_tmp_file_tag)_timing.def 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_resizer_timing.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(resizer_log_file_tag)_timing.log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_resizer_timing.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(resizer_log_file_tag)_timing.log 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
TIMER::timer_stop
|
||||
@@ -264,7 +247,7 @@ proc run_resizer_design {args} {
|
||||
gen_exclude_list -lib $::env(LIB_RESIZER_OPT) -drc_exclude_only -create_dont_use_list
|
||||
}
|
||||
set ::env(SAVE_DEF) [index_file $::env(resizer_tmp_file_tag).def 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_resizer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(resizer_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_resizer.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(resizer_log_file_tag).log 0]
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
TIMER::timer_stop
|
||||
|
||||
@@ -35,7 +35,7 @@ proc global_routing_fastroute {args} {
|
||||
set saveLOG [index_file $::env(fastroute_log_file_tag).log 0]
|
||||
set report_tag_saver $::env(fastroute_report_file_tag)
|
||||
set ::env(fastroute_report_file_tag) [index_file $::env(fastroute_report_file_tag) 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_groute.tcl |& tee $::env(TERMINAL_OUTPUT) $saveLOG
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_groute.tcl |& tee $::env(TERMINAL_OUTPUT) $saveLOG
|
||||
if { $::env(DIODE_INSERTION_STRATEGY) == 3 } {
|
||||
set_def $::env(SAVE_DEF)
|
||||
set_guide $::env(SAVE_GUIDE)
|
||||
@@ -46,17 +46,17 @@ proc global_routing_fastroute {args} {
|
||||
set prevGUIDE2 $::env(SAVE_GUIDE)
|
||||
set prevLOG1 $saveLOG
|
||||
set prevLOG2 $saveLOG
|
||||
set prevAntennaVal [exec grep "#Antenna violations:" [index_file $::env(fastroute_log_file_tag).log 0] -s | tail -1 | sed -r "s/.*\[^0-9\]//"]
|
||||
set prevAntennaVal [exec grep "INFO GRT-0012\] Antenna violations:" [index_file $::env(fastroute_log_file_tag).log 0] -s | tail -1 | sed -r "s/.*\[^0-9\]//"]
|
||||
while {$iter <= $::env(GLB_RT_MAX_DIODE_INS_ITERS) && $prevAntennaVal > 0} {
|
||||
set ::env(SAVE_DEF) [index_file $::env(fastroute_tmp_file_tag)_$iter.def]
|
||||
set ::env(SAVE_GUIDE) [index_file $::env(fastroute_tmp_file_tag)_$iter.guide 0]
|
||||
set saveLOG [index_file $::env(fastroute_log_file_tag)_$iter.log 0]
|
||||
set replaceWith "INSDIODE$iter"
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/replace_prefix_from_def_instances.py -op "ANTENNA" -np $replaceWith -d $::env(CURRENT_DEF)
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/replace_prefix_from_def_instances.py -op "ANTENNA" -np $replaceWith -d $::env(CURRENT_DEF)
|
||||
puts_info "FastRoute Iteration $iter"
|
||||
puts_info "Antenna Violations Previous: $prevAntennaVal"
|
||||
set ::env(fastroute_report_file_tag) [index_file $report_tag_saver 0]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_groute.tcl |& tee $::env(TERMINAL_OUTPUT) $saveLOG
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_groute.tcl |& tee $::env(TERMINAL_OUTPUT) $saveLOG
|
||||
set currAntennaVal [exec grep "#Antenna violations:" $saveLOG -s | tail -1 | sed -r "s/.*\[^0-9\]//"]
|
||||
puts_info "Antenna Violations Current: $currAntennaVal"
|
||||
if { $currAntennaVal >= $prevAntennaVal } {
|
||||
@@ -108,16 +108,9 @@ proc global_routing {args} {
|
||||
proc detailed_routing_tritonroute {args} {
|
||||
try_catch envsubst < $::env(SCRIPTS_DIR)/tritonRoute.param > $::env(tritonRoute_tmp_file_tag).param
|
||||
|
||||
if { $::env(DETAILED_ROUTER) == "tritonroute" } {
|
||||
try_catch TritonRoute \
|
||||
$::env(tritonRoute_tmp_file_tag).param \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(tritonRoute_log_file_tag).log 0]
|
||||
} else {
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_droute.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(tritonRoute_log_file_tag).log 0]
|
||||
}
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_droute.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(tritonRoute_log_file_tag).log 0]
|
||||
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/tr2klayout.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/tr2klayout.py \
|
||||
-i $::env(tritonRoute_report_file_tag).drc \
|
||||
-o $::env(tritonRoute_report_file_tag).klayout.xml \
|
||||
--design-name $::env(DESIGN_NAME)
|
||||
@@ -157,7 +150,7 @@ proc detailed_routing {args} {
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(tritonRoute_log_file_tag)_runtime.txt 0]
|
||||
|
||||
set_def $::env(tritonRoute_result_file_tag).def
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
|
||||
set ::env(tritonRoute_report_file_tag) $report_tag_saver
|
||||
@@ -175,7 +168,7 @@ proc ins_fill_cells {args} {
|
||||
if {$::env(FILL_INSERTION)} {
|
||||
set ::env(SAVE_DEF) [index_file $::env(addspacers_tmp_file_tag).def]
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_fill.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(addspacers_log_file_tag).log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_fill.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(addspacers_log_file_tag).log 0]
|
||||
|
||||
set_def $::env(SAVE_DEF)
|
||||
} else {
|
||||
@@ -212,7 +205,7 @@ proc power_routing {args} {
|
||||
set_if_unset arg_values(-extra_args) ""
|
||||
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/power_route.py\
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/power_route.py\
|
||||
--input-lef $arg_values(-lef)\
|
||||
--input-def $arg_values(-def)\
|
||||
--core-vdd-pin $arg_values(-power)\
|
||||
@@ -232,7 +225,7 @@ proc gen_pdn {args} {
|
||||
set ::env(PDN_CFG) $::env(PDK_ROOT)/$::env(PDK)/libs.tech/openlane/common_pdn.tcl
|
||||
}
|
||||
set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def]
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_pdn.tcl \
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_pdn.tcl \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0]
|
||||
|
||||
|
||||
@@ -250,7 +243,7 @@ proc ins_diode_cells_1 {args} {
|
||||
TIMER::timer_start
|
||||
set ::env(SAVE_DEF) [index_file $::env(TMP_DIR)/placement/diodes.def]
|
||||
|
||||
try_catch openroad -exit $::env(SCRIPTS_DIR)/openroad/or_diodes.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/diodes.log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/or_diodes.tcl |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/diodes.log 0]
|
||||
|
||||
set_def $::env(SAVE_DEF)
|
||||
write_verilog $::env(yosys_result_file_tag)_diodes.v
|
||||
@@ -280,7 +273,7 @@ proc ins_diode_cells_4 {args} {
|
||||
}
|
||||
|
||||
# Custom script
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/place_diodes.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o $::env(SAVE_DEF) --diode-cell $::env(DIODE_CELL) --diode-pin $::env(DIODE_CELL_PIN) --fake-diode-cell $::antenna_cell_name |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/diodes.log 0]
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/place_diodes.py -l $::env(MERGED_LEF) -id $::env(CURRENT_DEF) -o $::env(SAVE_DEF) --diode-cell $::env(DIODE_CELL) --diode-pin $::env(DIODE_CELL_PIN) --fake-diode-cell $::antenna_cell_name |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/placement/diodes.log 0]
|
||||
|
||||
set_def $::env(SAVE_DEF)
|
||||
|
||||
@@ -303,7 +296,7 @@ proc apply_route_obs {args} {
|
||||
puts_warn "Specifying a routing obstruction is now done using the coordinates"
|
||||
puts_warn "of its bounding box instead of the now deprecated (x, y, size_x, size_y)."
|
||||
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/add_def_obstructions.py \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/add_def_obstructions.py \
|
||||
--input-def $::env(CURRENT_DEF) \
|
||||
--lef $::env(MERGED_LEF) \
|
||||
--obstructions $::env(GLB_RT_OBS) \
|
||||
@@ -349,7 +342,7 @@ proc run_spef_extraction {args} {
|
||||
puts_info "Running SPEF Extraction..."
|
||||
TIMER::timer_start
|
||||
set ::env(MPLCONFIGDIR) /tmp
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/spef_extractor/main.py -l $::env(MERGED_LEF_UNPADDED) -d $::env(CURRENT_DEF) -mw $::env(SPEF_WIRE_MODEL) -ec $::env(SPEF_EDGE_CAP_FACTOR) |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/routing/spef_extraction.log]
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/spef_extractor/main.py -l $::env(MERGED_LEF_UNPADDED) -d $::env(CURRENT_DEF) -mw $::env(SPEF_WIRE_MODEL) -ec $::env(SPEF_EDGE_CAP_FACTOR) |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(LOG_DIR)/routing/spef_extraction.log]
|
||||
set ::env(CURRENT_SPEF) [file rootname $::env(CURRENT_DEF)].spef
|
||||
TIMER::timer_stop
|
||||
exec echo "[TIMER::get_runtime]" >> [index_file $::env(LOG_DIR)/routing/spef_extraction_runtime.txt 0]
|
||||
|
||||
@@ -90,7 +90,7 @@ proc run_sta {args} {
|
||||
set report_tag_saver $::env(opensta_report_file_tag)
|
||||
set ::env(opensta_report_file_tag) [index_file $::env(opensta_report_file_tag)]
|
||||
|
||||
try_catch sta $::env(SCRIPTS_DIR)/sta.tcl \
|
||||
try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/sta.tcl \
|
||||
|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(opensta_log_file_tag) 0]
|
||||
|
||||
set ::env(opensta_report_file_tag) $report_tag_saver
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
lef:${MERGED_LEF_UNPADDED}
|
||||
def:${CURRENT_DEF}
|
||||
guide:${CURRENT_GUIDE}
|
||||
output:${tritonRoute_result_file_tag}.def
|
||||
outputTA:${tritonRoute_tmp_file_tag}_TA.def
|
||||
outputguide:${tritonRoute_tmp_file_tag}.guide
|
||||
outputDRC:${tritonRoute_report_file_tag}.drc
|
||||
outputMaze:${tritonRoute_tmp_file_tag}_maze.log
|
||||
threads:${ROUTING_CORES}
|
||||
verbose:1
|
||||
drouteEndIterNum:${ROUTING_OPT_ITERS}
|
||||
OR_SEED:42
|
||||
@@ -129,7 +129,7 @@ proc zeroize_origin_lef {args} {
|
||||
set flags {}
|
||||
parse_key_args "zeroize_origin_lef" args arg_values $options flags_map $flags
|
||||
exec cp $arg_values(-file) $arg_values(-file).original
|
||||
try_catch python3 $::env(SCRIPTS_DIR)/zeroize_origin_lef.py < $arg_values(-file) > $arg_values(-file).zeroized
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(SCRIPTS_DIR)/zeroize_origin_lef.py < $arg_values(-file) > $arg_values(-file).zeroized
|
||||
exec mv $arg_values(-file).zeroized $arg_values(-file)
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ proc generate_final_summary_report {args} {
|
||||
set_if_unset arg_values(-man_report) $::env(REPORTS_DIR)/manufacturability_report.rpt
|
||||
set_if_unset arg_values(-runtime_summary) $::env(REPORTS_DIR)/runtime_summary_report.rpt
|
||||
|
||||
try_catch python3 $::env(OPENLANE_ROOT)/report_generation_wrapper.py -d $::env(DESIGN_DIR) \
|
||||
try_catch $::env(OPENROAD_BIN) -python $::env(OPENLANE_ROOT)/report_generation_wrapper.py -d $::env(DESIGN_DIR) \
|
||||
-dn $::env(DESIGN_NAME) \
|
||||
-t $::env(RUN_TAG) \
|
||||
-o $arg_values(-output) \
|
||||
|
||||
@@ -17,7 +17,7 @@ import os
|
||||
import sys
|
||||
import argparse
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
import opendbpy as odb
|
||||
import opendb as odb
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Add cell power connections in the netlist. Useful for LVS purposes.')
|
||||
|
||||
Reference in New Issue
Block a user